import { Component, ChangeDetectionStrategy, inject } from '@angular/core';
import { CheckboxComponent } from '@shared/components/checkbox';
import { FormControl, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
import { SelectModule } from '@shared/components/select';
import { FormControlComponent } from '@shared/components/form-control';
import { CrmCustomerService } from '@domain/crm';
import { AddressDTO, Gender, PayerDTO } from '@generated/swagger/crm-api';
import { map } from 'rxjs/operators';
import { AsyncPipe } from '@angular/common';
import { AddressSelectionModalService } from '@modal/address-selection';
import { CustomerSearchStore } from '../store';
import { CustomerSearchNavigation } from '@shared/services/navigation';
import { IconComponent } from '@shared/components/icon';
import { combineLatest } from 'rxjs';
import { RouterLink } from '@angular/router';
import { zipCodeValidator } from '../../validators/zip-code-validator';
import { GenderSettingsService } from '@shared/services/gender';

@Component({
  selector: 'page-add-billing-address-main-view',
  templateUrl: 'add-billing-address-main-view.component.html',
  styleUrls: ['add-billing-address-main-view.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  host: { class: 'page-add-billing-address-main-view' },
  imports: [
    IconComponent,
    RouterLink,
    AsyncPipe,
    ReactiveFormsModule,
    SelectModule,
    FormControlComponent,
    CheckboxComponent
],
})
export class AddBillingAddressMainViewComponent {
  private _customerService = inject(CrmCustomerService);
  private _addressSelection = inject(AddressSelectionModalService);
  private _store = inject(CustomerSearchStore);
  private _navigation = inject(CustomerSearchNavigation);
  public genderSettings = inject(GenderSettingsService);

  formGroup = new FormGroup({
    gender: new FormControl<Gender>(undefined, [Validators.required]),
    title: new FormControl<string>(undefined),
    firstName: new FormControl<string>(undefined, [Validators.required]),
    lastName: new FormControl<string>(undefined, [Validators.required]),
    organisation: new FormControl<string>(undefined),
    street: new FormControl<string>(undefined, [Validators.required]),
    streetNumber: new FormControl<string>(undefined, [Validators.required]),
    zipCode: new FormControl<string>(undefined, [Validators.required, zipCodeValidator()]),
    city: new FormControl<string>(undefined, [Validators.required]),
    country: new FormControl<string>('DEU', [Validators.required]),
    info: new FormControl<string>(undefined),
    isDefault: new FormControl<boolean>(false),
  });

  countries$ = this._customerService.getCountries().pipe(map((res) => res.result));

  detailsRoute$ = combineLatest([this._store.processId$, this._store.customerId$]).pipe(
    map(([processId, customerId]) => this._navigation.detailsRoute({ processId, customerId })),
  );

  async save() {
    if (this.formGroup.invalid) {
      this.formGroup.markAllAsTouched();
      return;
    }

    try {
      this.formGroup.disable();

      const formData = this.formGroup.value;

      const address: AddressDTO = {
        street: formData.street,
        streetNumber: formData.streetNumber,
        zipCode: formData.zipCode,
        city: formData.city,
        country: formData.country,
        info: formData.info,
      };

      const addressValidationResult = await this._addressSelection.validateAddress(address);

      if (addressValidationResult === undefined) {
        this.formGroup.enable();
        return;
      }

      const payer: PayerDTO = {
        gender: formData.gender,
        title: formData.title,
        firstName: formData.firstName,
        lastName: formData.lastName,
        organisation: formData.organisation ? { name: formData.organisation } : undefined,
        address: addressValidationResult,
      };

      const result = await this._customerService.createPayer(this._store.customerId, payer, formData.isDefault);

      this._navigation.navigateToDetails({ processId: this._store.processId, customerId: this._store.customerId });
    } catch (error) {
      this.formGroup.enable();
    }
  }
}
