import { Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';
import { AbstractControl, FormControl, FormGroup, Validators } from '@angular/forms';
import { Observable, of, Subscription, throwError } from 'rxjs';
import { catchError, map, switchMap, tap } from 'rxjs/operators';
import { CategoryCustomer } from 'src/app/models/category.customer.model';
import { Customer } from 'src/app/models/customer.model';
import { Place } from 'src/app/models/places.model';
import { SubCategoryCustomer } from 'src/app/models/sub-category-customer.model';
import { CustomerService } from 'src/app/services/customer.service';
import { LookupService } from 'src/app/services/lookup.service';
import { ConsultaCepService } from 'src/app/shared/services/consulta-cep.service';
import { AuthService } from 'src/app/auth/services/auth.service';
import { FormatSettings } from '@progress/kendo-angular-dateinputs';
import { IntlService, CldrIntlService } from '@progress/kendo-angular-intl';
import { DocumentValidator } from 'src/app/shared/validators/document-validator';
import { Ramo } from 'src/app/models/ramo.model';

export interface JsonModel {
  birthDate: string;
}

export interface CustomerBirthDate {
  birthDate: Date;
}

@Component({
  selector: 'app-create-customer-modal',
  providers: [
    {
      provide: IntlService,
      useClass: CldrIntlService,
    },
  ],
  templateUrl: './create-customer-modal.component.html',
  styleUrls: ['./create-customer-modal.component.scss',
    '../../../shared/styles/button-style.scss']
})
export class CreateCustomerModalComponent implements OnInit, OnDestroy {
  public phoneNumberValue = '';
  public phoneNumberMask = '(99) 00000-0000';
  public cpfMask = '000.000.000-00';
  public cnpjMask = '00.000.000/0000-00';
  public customer: Customer;
  public isloading = false;
  public inProcess = false;
  public errorObject: any;
  public result;
  loaderVisible = false;
  @Input() openedDialog = false;
  @ViewChild('formCustomer') formCustomer: ElementRef;
  @ViewChild('inputCpf') inputCpf: ElementRef;
  @Output() resultEvent = new EventEmitter<Customer>();
  public windowWidth = 600;
  public windowHeight = 680;
  category$: Observable<CategoryCustomer[]>;
  categories: CategoryCustomer[] = [];
  subCategory$: Observable<SubCategoryCustomer[]>;
  subCategories: SubCategoryCustomer[];
  subscriptionCategories: Subscription;
  subscriptionSubCategories: Subscription;
  subscriptionPlaces: Subscription;
  subscriptionRamos: Subscription;
  places$: Observable<Place[]>;
  places: Place[] = [];
  ramos$: Observable<Ramo[]>;
  ramos: Ramo[] = []
  selectedCategory: CategoryCustomer;
  selectedSubCategory: SubCategoryCustomer;
  selectedPlace: Place;

  confirmMap = false;

  public format: FormatSettings = {
    displayFormat: 'dd/MM/yyyy',
    inputFormat: 'dd/MM/yyyy',
  };

  public isShowConfirmation = false;
  titleMessage = 'Cadastro de cliente';
  messageConfirmation = 'Confirma dados para o cliente?';
  textButtonConfirmation = 'Confirmar';
  textButtonCancel = 'Cancelar';

  public form: FormGroup;

  public customerData: any = {
    company: false,
    cpfCnpj: '',
    gender: '',
    name: '',
    numberState: '',
    cellPhone: '',
    whatsapp: false,
    email: '',
    address: '',
    addressNumber: '',
    complement: '',
    neighborhood: '',
    city: '',
    state: '',
    zipCode: '',
    category: '',
    subCategory: '',
    notifications: true,
    place: '',
    ibgeCode: '',
    sellerId: '',
    communicate: '',
    latitude: 0,
    longitude: 0,
    addressType: '',
  };

  public listCommunicate: Array<string> = [
    "JA SOU CLIENTE",
    "TELEVISÃO",
    "REDES SOCIAIS",
    "GOOGLE",
    "AMIGOS/CONHECIDOS",
    "OUTDOOR",
    "BUSDOOR",
    "CARRO SOM",
    "RÁDIO",
    "RÁDIO DE POSTE",
    "EVENTOS",
    "OUTROS",
  ];

  //mostrar mapa
  showMap = false;
  latitude = -1.3819925;
  longitude = -48.4084447;
  zoom = 15;

  constructor(
    private readonly customerService: CustomerService,
    private readonly lookupService: LookupService,
    private cepService: ConsultaCepService,
    private readonly authService: AuthService,
    private intl: IntlService) {
    this.form = new FormGroup({
      company: new FormControl('false', [
        Validators.required,
      ]),
      cpfCnpj: new FormControl(this.customerData.cpfCnpj, [
        Validators.required, DocumentValidator.isValidCpf(), // DocumentValidator.isValidCNPJ(),
      ]),
      gender: new FormControl(this.customerData.gender, [
        Validators.required,
      ]),
      name: new FormControl(this.customerData.name, [
        Validators.required,
      ]),
      whatsapp: new FormControl(this.customerData.whatsapp, [
        Validators.required,
      ]),
      numberState: new FormControl(this.customerData.numberState, []),
      cellPhone: new FormControl(this.customerData.cellPhone, [
        Validators.required,
      ]),
      email: new FormControl(this.customerData.email, [Validators.required]),
      address: new FormControl(this.customerData.address, [Validators.required]),
      addressNumber: new FormControl(this.customerData.addressNumber, [Validators.required]),
      neighborhood: new FormControl(this.customerData.neighborhood),
      complement: new FormControl(this.customerData.complement),
      city: new FormControl(this.customerData.city),
      state: new FormControl(this.customerData.state),
      zipCode: new FormControl(this.customerData.zipCode),
      notifications: new FormControl(this.customerData.notifications),
      category: new FormControl(null),
      subCategory: new FormControl(null),
      comments: new FormControl(this.customerData.comments),
      place: new FormControl(null, [Validators.required]),
      ibgeCode: new FormControl(this.customerData.ibgeCode),
      sellerId: new FormControl(this.customerData.sellerId),
      birthdate: new FormControl(null),
      ramo: new FormControl(null, [Validators.required]),
      communicate: new FormControl(this.customerData.communicate, [Validators.required]),
      idUser: new FormControl(null),
      latitude: new FormControl(null),
      longitude: new FormControl(null),
      addressType: new FormControl(null),
    });
  }
  ngOnDestroy(): void {
    if (this.subscriptionCategories) {
      this.subscriptionCategories.unsubscribe();
    }
    if (this.subscriptionSubCategories) {
      this.subscriptionSubCategories.unsubscribe();
    }
    if (this.subscriptionPlaces) {
      this.subscriptionPlaces.unsubscribe();
    }
    if (this.subscriptionRamos) {
      this.subscriptionRamos.unsubscribe();
    }
  }

  public showConfirmationold(mensage: string) {
    console.log(this.form.value);
    /*result$.subscribe
      .pipe(
        take(1),
        switchMap(result => result ? this.customerService.createCustomer(this.form.value) : EMPTY)
      ).subscribe(
        successCreate => {
          return successCreate;
        }, err => err
      );*/
  }

  ngOnInit(): void {
    this.category$ = this.customerService.getCategory();
    this.subCategory$ = this.customerService.getSubCategory();
    this.places$ = this.lookupService.getPlaces();
    this.ramos$ = this.lookupService.getRamos();
    this.subscriptionCategories = this.category$.subscribe(data => this.categories = data);
    this.subscriptionSubCategories = this.subCategory$.subscribe(data => this.subCategories = data);
    this.subscriptionPlaces = this.places$.subscribe(data => this.places = data);
    this.subscriptionRamos = this.ramos$.subscribe(data => this.ramos = data);

    this.form.valueChanges.subscribe(data => this.confirmMap = false);
  }

  cpfCadastrado(data: Customer) {
    /* const result$ = this.dialogsService.confirmResult;
     result$.asObservable()
       .pipe(
         take(1),
         map(result => result ? this.populateCustomer(data) : this.setFocus('inputCpf')),
         // switchMap(result => result ? console.log(result) : EMPTY)
       ).subscribe(
         successCreate => {
           return successCreate;
         }, err => err
       );
     this.dialogsService.showConfirmation('Confirmação', 'Cliente já cadastrado, deseja alterar seu cadastro?');*/
  }

  populateCustomer(data: Customer) {
    console.log(data);
    if (data.categoryId > 0) {
      const category = this.categories.filter(c => c.id === data.categoryId);
      if (category.length > 0) {
        this.form.patchValue({ category: category[0] });
        this.filterSubCategoria(category[0]);
      }
    }
    if (data.subCategoryId > 0) {
      const subCategory = this.subCategories.filter(s => s.categoryId === data.categoryId && s.id === data.subCategoryId);
      if (subCategory.length > 0) {
        this.form.patchValue({ subCategory: subCategory[0] });
      }
    }
    if (data.placeId > 0) {
      const places = this.places.filter(p => p.id === data.placeId);
      if (places.length > 0) {
        this.form.patchValue({ place: places[0] });
      }
    }

    if (data.ramoId > 0) {
      const ramos = this.ramos.filter(p => p.id === data.ramoId);
      console.log("ramo atividade: " + JSON.stringify(ramos));
      if (ramos.length > 0) {
        this.form.patchValue({ ramo: ramos[0] });
      }
    }

    const birthDate = new Date(data.birthdate);
    const year = birthDate.getFullYear();
    const month = birthDate.getMonth();
    const date = birthDate.getDate();
    const dateBirthDate = new Date(year, month, date);

    this.form.patchValue({
      gender: data.gender,
      name: data.name,
      numberState: data.numberState,
      cellPhone: data.cellPhone,
      email: data.email,
      zipCode: data.zipCode,
      address: data.address,
      addressNumber: data.addressNumber,
      complement: data.complement,
      neighborhood: data.neighborhood,
      city: data.city,
      state: data.state,
      mensage: data.allowMessage,
      ibgeCode: data.ibgeCode,
      birthdate: data.birthdate != null ? dateBirthDate : null,
      communicate: data.communicate,
      latitude: data.latitude,
      longitude: data.longitude,
      addressType: data.addressType,
      // category: data.categoryId,
    });

  }

  // A simple method for the string-to-date conversion
  private parse(json) {
    Object.keys(json).map((key) => {
      const date = new Date(json[key]);
      if (!isNaN(date.getTime())) {
        json[key] = date;
      }
    });

    return json;
  }

  searchCustomerByDocument() {
    const fieldCpf = 'cpfCnpj';
    const cpf = this.form.value[fieldCpf];
    this.isloading = true;
    this.errorObject = null;
    this.customerService.getCustomerbyCpf(cpf).pipe(
      map(result => {
        if (result.data != null) {
          this.customer = result.data;
          console.log(JSON.stringify(result.data));
          this.populateCustomer(this.customer);
          // this.cpfCadastrado(result.data);
        }
      }),
      tap(() => {
        this.isloading = false;
      }),
      catchError(err => {
        this.isloading = false;
        this.errorObject = err;
        console.log(err);
        return throwError(err);
      })).subscribe();
  }

  setFocus(name) {
    this.inputCpf.nativeElement.setFocus();
  }

  public closeDialog(result = false) {
    this.openedDialog = false;
    this.resultEvent.emit(this.customer);
  }

  createCustomer() {
    console.log(this.form.value);
    /*const result$ = this.customerService.createCustomer(this.form.value);
    result$.pipe(
      map(c => {
        this.customer = c.data;
      }),
    ).subscribe();*/
  }

  consultaCep() {
    const cep = this.form.get('zipCode').value;
    if (cep !== null &&  cep !== '') {
      this.cepService.consultaCep(cep)
        .subscribe(
          dados => {
            console.log(dados);
            if (!dados.erro) {
              this.populateAddress(dados);
            }
          });
    }
  }

  populateAddress(dadosCep: any) {
    console.log(dadosCep);
    let city = dadosCep.cidade as string;
    if (city.length > 15) {
      city = city.substring(0, 15);
    }
    this.form.patchValue({
      address: dadosCep.logradouro.toUpperCase(),
      complement: dadosCep.complemento.toUpperCase(),
      neighborhood: dadosCep.bairro.toUpperCase(),
      city, // dadosCep.localidade.toUpperCase(),
      state: dadosCep.uf.toUpperCase(),
      ibgeCode: dadosCep.codigo_ibge,
      latitude: dadosCep.lat,
      longitude: dadosCep.lon,
    });
  }

  showConfirmation() {
    if (this.inProcess) {
      return;
    }
    this.inProcess = true;
    this.isShowConfirmation = true;
  }

  async returnConfirmationSalve(result: any) {
    console.log(this.form.value);
    this.customer = null;
    this.isShowConfirmation = false;
    this.form.patchValue({
      sellerId: this.authService.getSeller(),
    });
    if (result) {
      this.form.patchValue({
        idUser: this.authService.getUser(),
      });
      const result$ = this.customerService.createCustomer(this.form.value);
      result$.pipe(
        map(c => {
          this.customer = c.data;
          console.log(c);
          this.inProcess = false;
        }),
      ).subscribe(() => {
        this.inProcess = false;
        this.closeDialog(true);
      }
      );
    }
  }

  filterSubCategoria(categoria: CategoryCustomer) {
    this.form.patchValue({ subCategory: null });
    this.subscriptionCategories = this.subCategory$.subscribe(data => {
      this.subCategories = data.filter(d => d.categoryId === categoria.id);
    });
  }


  removeCharacters(field: string) {
    const text = this.form.get(field).value;
    console.log(text);
    const str = text.normalize('NFD').replace(/[^a-zA-Z\s0-9]/g, '').toUpperCase();
    switch (field) {
      case 'name':
        this.form.patchValue({
          name: str,
        });
        return;
        case 'address':
          this.form.patchValue({
            address: str,
          });
          return;
      case 'neighborhood':
        this.form.patchValue({
          neighborhood: str,
        });
        return;
      case 'complement':
        this.form.patchValue({
          complement: str,
        });
        return;
      case 'city':
        this.form.patchValue({
          city: str,
        });
        return;
      case 'state':
        this.form.patchValue({
          state: str,
        });
        return;
      case 'comments':
        this.form.patchValue({
          comments: str,
        });
        return;
      default:
        return;
    }
  }

  MapCep(show: boolean, latitude?: number, longitude?: number) {
    if (show) {
      this.confirmMap = true;
      const customer = JSON.parse(localStorage.getItem('customer')) as Customer;
      console.log(this.form);
      this.latitude = latitude; //Number.parseFloat((this.form.get('latitude').value as string).replace(',', '.'));
      this.longitude = longitude; //Number.parseFloat((this.form.get('longitude').value as string).replace(',', '.'));

      // if ( this.latitude == 0 && customer != null ) {
      //   this.latitude  = customer.latitude;
      //   this.longitude = customer.longitude;
      // }
    }

    this.showMap = show;
  }

  async googleGeocode() {
    const address = this.form.get('address').value;
    const addressNumber = this.form.get('addressNumber').value;
    const neighborhood = this.form.get('neighborhood').value;
    const city = this.form.get('city').value;
    const state = this.form.get('state').value;

    this.cepService.googleGeocode(address, addressNumber, neighborhood, city, state)
      .pipe(
        map(result => {
          console.log(result);
          this.MapCep(true, result[0].latitude, result[0].longitude);
        })
      )
      .subscribe();
  }

}
