import { Store, Select } from '@ngxs/store';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { FormGroup, FormBuilder, Validators, AbstractControl } from '@angular/forms';
import { Router } from '@angular/router';
import { Subject, Observable } from 'rxjs';
import { SharedSelectors } from '../../../../core/store/selectors/shared.selectors';
import { EditCustomerData } from '../../../../core/models/edit-customer.model';
import { takeUntil, take, tap, filter } from 'rxjs/operators';
import { User, Address } from '../../../../core/models/user.model';
import { ChangeCurrentRoute } from 'apps/sales/src/app/core/store/actions/process.actions';
import { AddNewShippingAddress } from 'apps/sales/src/app/core/store/actions/customer.actions';
import { GENDERS, TIITLES } from '../../dropdown-values';
import { Country } from 'apps/sales/src/app/core/models/country.model';
import { CountrySelector } from 'apps/sales/src/app/core/store/selectors/countries.selector';
import { isNullOrUndefined } from 'util';

@Component({
  selector: 'app-add-delivery-address',
  templateUrl: 'customer-add-delivery-address.component.html',
  styleUrls: ['customer-add-delivery-address.component.scss'],
})
export class CustomerAddDeliveryAddressComponent implements OnInit, OnDestroy {
  @Select(SharedSelectors.getCustomerEditData) customerEditData$: Observable<EditCustomerData>;
  @Select(CountrySelector.getCountriesIterable) countries$: Observable<Country[]>;
  deliveryForm: FormGroup;
  submitted = false;
  destroy$ = new Subject();
  customer: User;

  genders = GENDERS;
  titels = TIITLES;
  countries: Country[];
  companyFieldsRequired = false;

  constructor(private fb: FormBuilder, private store: Store, private router: Router) {}

  ngOnInit(): void {
    this.deliveryForm = this.buildForm(this.fb);

    this.customerEditData$
      .pipe(
        filter((data) => !isNullOrUndefined(data)),
        take(1)
      )
      .subscribe((data: EditCustomerData) => {
        if (data && data.customer) {
          this.customer = data.customer;
        }
      });

    this.countries$
      .pipe(
        take(1),
        tap((t) => {
          this.countries = t;
        })
      )
      .subscribe();
  }

  createDeliveryAddress() {
    if (this.deliveryForm.valid) {
      const newDelivery = this.createAdrressData();
      this.store
        .dispatch(new AddNewShippingAddress(this.customer.id, newDelivery))
        .pipe(takeUntil(this.destroy$))
        .subscribe(() => {
          const currentRoute = `customer/edit/${this.customer.id}/billing`;
          this.store.dispatch(new ChangeCurrentRoute(currentRoute));
          this.router.navigate([currentRoute]);
        });
    } else {
      this.submitted = true;
    }
  }

  valueChanges(control: AbstractControl, value: string) {
    control.setValue(value);
  }

  genderSelect(gender: string) {
    this.updateDataForSelectedOption('gender', gender, 'Andrede');
  }

  titelSelect(title: string) {
    this.updateDataForSelectedOption('title', title, 'Titel');
  }

  countrySelect(country: string) {
    this.updateDataForSelectedOption('country', country, 'Land');
  }

  private createAdrressData(): Address {
    const data: Address = new Address(
      Date.now() + Math.random(),
      this.deliveryForm.get('firstName').value,
      this.deliveryForm.get('lastName').value,
      this.deliveryForm.get('address').value,
      this.deliveryForm.get('zipCode').value,
      this.deliveryForm.get('city').value,
      this.getCountryCode(this.deliveryForm.get('country').value),
      this.deliveryForm.get('company').value ? this.deliveryForm.get('company').value : null,
      this.deliveryForm.get('department').value ? this.deliveryForm.get('department').value : null,
      this.deliveryForm.get('note').value ? this.deliveryForm.get('note').value : null,
      this.deliveryForm.get('tax_number').value ? this.deliveryForm.get('tax_number').value : null,
      this.deliveryForm.get('title').value ? this.deliveryForm.get('title').value : null,
      this.deliveryForm.get('gender').value ? this.deliveryForm.get('gender').value : null
    );

    return data;
  }

  private updateDataForSelectedOption(field: string, value: string, defaultValue: string) {
    if (value !== defaultValue) {
      this.deliveryForm.get(field).patchValue(value);
    } else {
      this.deliveryForm.get(field).patchValue(null);
    }
  }

  get f() {
    return this.deliveryForm.controls;
  }

  private buildForm(fb: FormBuilder) {
    return fb.group({
      firstName: ['', Validators.required],
      lastName: ['', Validators.required],
      address: ['', Validators.required],
      zipCode: ['', Validators.required],
      city: ['', Validators.required],
      country: ['', Validators.required],
      gender: [''],
      company: [''],
      department: [''],
      tax_number: [''],
      title: [''],
      note: [''],
    });
  }

  getCountryCode(name: string) {
    return this.countries.find((t) => t.value === name).key;
  }

  ngOnDestroy() {
    this.destroy$.next();
  }
}
