import { Component, OnInit, ViewChild } from '@angular/core';
import { DetailsFormBase } from '@objects-view/details-form-base';
import { IDomainContactModel } from '@fleio-api/plugins/domains/model/domain-contact.model';
import { UntypedFormBuilder, Validators } from '@angular/forms';
import { IDomainContactCreateOptionsModel } from '@fleio-api/plugins/domains/model/domain-contact-create-options.model';
import { ICountry } from '@fleio-api/misc/model/country';
import { Observable, of } from 'rxjs';
import { DomainContactsApiService } from '@fleio-api/plugins/domains/domain-contacts-api.service';
import { ActivatedRoute, Router } from '@angular/router';
import { ConfigService } from '@shared/config/config.service';
import { catchError, map } from 'rxjs/operators';
import { IActionResult } from '@objects-view/interfaces/actions/action-result';
import { IClientModel } from '@fleio-api/client-user/model/client.model';
import { ClientsApiService } from '@fleio-api/client-user/client/clients-api.service';
import { CustomFieldsComponent } from '@shared/fleio-data-controls/custom-fields/custom-fields.component';
import { CallbackAction } from '@objects-view/actions/callback-action';
import { ICustomFieldModel } from '@fleio-api/custom-fields/model/custom-field.model';
import { PhoneInputComponent } from '@shared/fleio-data-controls/phone-input/phone-input.component';

@Component({
  selector: 'app-contact-edit-form',
  templateUrl: './contact-edit-form.component.html',
  styleUrls: ['./contact-edit-form.component.scss']
})
export class ContactEditFormComponent extends DetailsFormBase<IDomainContactModel> implements OnInit {
  @ViewChild('customFields') customFields: CustomFieldsComponent;
  @ViewChild('phoneInput') phoneInput: PhoneInputComponent;
  contactForm = this.formBuilder.group({
    first_name: ['', Validators.required],
    last_name: ['', Validators.required],
    email: ['', Validators.required],
    country: ['', Validators.required],
    company: [''],
    vat_id: [''],
    tax_exempt: [''],
    address1: ['', Validators.required],
    address2: [''],
    state: ['', Validators.required],
    city: ['', Validators.required],
    zip_code: ['', Validators.required],
    phone: ['', Validators.required],
    client: ['', Validators.required]
  });

  country = this.contactForm.controls.country;

  public createOptions: IDomainContactCreateOptionsModel;
  public customFieldsDefinitions: { [name: string]: ICustomFieldModel } = {};


  constructor(
    private formBuilder: UntypedFormBuilder,
    private domainContactsApiService: DomainContactsApiService,
    private router: Router,
    private config: ConfigService,
    private activatedRoute: ActivatedRoute,
    private clientsApi: ClientsApiService,
  ) {
    super();
  }

  findCountry(code: string): ICountry {
    return this.createOptions.countries.filter(country => country.value === code)[0];
  }

  ngOnInit() {
    super.ngOnInit();

    if (this.objectController) {
      this.objectController.actionCallback = (action) => this.saveContact(action);
    }

    if (this.objectController) {
      this.createOptions = this.objectController.additionalObjects.createOptions;
      if (this.createOptions.custom_fields) {
        for (const [name, field] of Object.entries(this.createOptions.custom_fields)) {
          this.customFieldsDefinitions[name] = field;
        }
      }
    }

    if (this.authSvc && !this.authSvc.feature('ui.plugins.domains.contacts.show-client')) {
      this.contactForm.removeControl('client');
    }

    if (this.object) {
      this.contactForm.patchValue(this.object);
      if (this.object.client && this.contactForm.contains('client')) {
        this.clientsApi.get(this.object.client).subscribe(client => {
          this.contactForm.controls.client.setValue(client);
        });
      }
    }

    if (this.object && this.object.country) {
      this.country.setValue(this.findCountry(this.object.country));
    }

    this.contactForm.controls.country.valueChanges.subscribe((selectedCountry:ICountry) => {
      if (this.phoneInput) {
        this.phoneInput.setPhoneCountry(selectedCountry?.value);
      }
    })
  }

  processError(error) {
    const errors = error.error;
    this.customFields.setBackendErrors(errors);
    this.setErrors(errors);
  }

  saveContact(action: CallbackAction): Observable<IActionResult> {
    this.validate();
    if (this.contactForm.invalid) {
      const insideDialog: boolean = this.objectController && this.objectController.hasOwnProperty('dialogActionCallback');
      this.displayControlErrors(!insideDialog);
      return of({success: false, message: ''});
    }
    const value = this.contactForm.value as IDomainContactModel;

    const customFieldsValid = this.customFields.checkCustomFieldsForm();
    if (!customFieldsValid) {
      return of({success: false, message: $localize`Invalid custom fields`});
    }

    if (typeof value.country !== 'string') {
      value.country = (value.country as ICountry).value;
    }

    if (typeof (value.client) === 'object') {
      value.client = (value.client as IClientModel).id;
    }

    if (this.customFields.customFieldsToSubmit && this.customFields.customFieldsToSubmit.length) {
      value.custom_fields = this.customFields.customFieldsToSubmit;
    } else {
      value.custom_fields = [];
    }

    let request;

    if (this.object.id) {
      value.id = this.object.id;
      request = this.domainContactsApiService.update(value.id, value);
    } else {
      request = this.domainContactsApiService.create(value);
    }

    if (!action || action.needsResult) {
      return request.pipe(
        map(() => ({success: true, message: $localize`Contact saved successfully`})),
        catchError((error) => {
          this.processError(error);
          return of({success: false, message: $localize`Failed to save contact`});
        })
      );
    } else {
      this.objectController.loading = true;
      request.subscribe(() => {
        this.router.navigateByUrl(
          this.config.getPrevUrl('domains/contacts')
        ).catch(() => {
        });
      }, (error) => {
        this.objectController.loading = false;
        this.processError(error);
      });
      return of(null);
    }
  }

  getLiveFormVal() {
    const value = this.contactForm.value;
    if (typeof value.country !== 'string') {
      value.country = (value.country as ICountry).value;
    }
    return value;
  }
}
