import { Component, Inject, OnInit, ViewChild } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { NotificationService } from '@shared/ui-api/notification.service';
import { IConfigurableOptionCreateOptionsModel } from '@fleio-api/billing/model/configurable-option-create-options.model';
import { IConfigurableOptionCycleModel } from '@fleio-api/billing/model/configurable-option-cycle.model';
import { ConfigurableOptionsCycleApiService } from '@fleio-api/billing/configurable-options/configurable-option-cycle-api.service';
import { IConfigOptionModel } from '@fleio-api/billing/model/config-option.model';
import { IConfigurableOptionChoiceModel } from '@fleio-api/billing/model/configurable-option-choice.model';
import { FormErrorsHelper } from '@shared/ui-api/helpers/form-errors-helper';
import { IBaseDialog } from '@shared/common-dialogs/base-dialog';
import { IAction } from '@objects-view/interfaces/actions/action';
import { DialogCallbackAction } from '@objects-view/actions/dialog-callback-action';
import { ValidatorsHelper } from '@shared/ui-api/helpers/validators-helper';

@Component({
  selector: 'app-edit-option-cycle-dialog',
  templateUrl: './edit-option-cycle-dialog.component.html',
  styleUrls: ['./edit-option-cycle-dialog.component.scss']
})
export class EditOptionCycleDialogComponent implements IBaseDialog, OnInit {
  @ViewChild('formErrors') formErrors;
  backendErrors: Record<string, unknown> = {};
  editCycleForm: UntypedFormGroup = this.formBuilder.group({
    cycle: ['month', Validators.required],
    cycle_multiplier: [1, ValidatorsHelper.requiredIntegerValidator],
    price: [0, ValidatorsHelper.requiredNumericValueValidator],
    is_relative_price: [true],
    setup_fee: [0, ValidatorsHelper.requiredNumericValueValidator],
    currency: ['', Validators.required],
    price_type: ['fixed'],
    percentage_relative_to_options: [false],
  });
  dialogTitle: string;
  dialogActions: Array<IAction> = [
    new DialogCallbackAction({
      name: $localize`Save cycle`,
      primary: true,
      callback: () => this.addCycle(),
    }),
  ];
  dialogForm = this.editCycleForm;
  loading = false;

  constructor(
    public dialogRef: MatDialogRef<EditOptionCycleDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: {
      createOptions: IConfigurableOptionCreateOptionsModel;
      cycle?: IConfigurableOptionCycleModel;
      option?: IConfigOptionModel;
      choice?: IConfigurableOptionChoiceModel;
    },
    private notificationService: NotificationService,
    private formBuilder: UntypedFormBuilder,
    private configurableOptionsCycleApiService: ConfigurableOptionsCycleApiService,
  ) {
  }

  ngOnInit() {
    if (this.data.cycle) {
      this.editCycleForm.patchValue(this.data.cycle);
    }

    if (this.data.option.billing_type === 'onetime') {
      this.dialogActions[0].name = $localize`Save price`;
      this.editCycleForm.controls.cycle.setValue('onetime');
      if (this.data?.cycle?.id) {
        this.dialogTitle = $localize`Edit price`;
      } else {
        this.dialogTitle = $localize`Add price`;
      }
    } else {
      if (this.data?.cycle?.id) {
        this.dialogTitle = $localize`Edit cycle`;
      } else {
        this.dialogTitle = $localize`Add cycle`;
      }
    }

    this.editCycleForm.controls.currency.valueChanges.subscribe(() => {
      this.updateControls();
    });

    this.editCycleForm.controls.is_relative_price.valueChanges.subscribe(() => {
      this.updateControls();
    });

    if (this.editCycleForm.controls.price_type.value === 'percentage') {
      this.editCycleForm.controls.price.setValidators([Validators.min(0), Validators.max(100)]);
    }
    this.editCycleForm.controls.price_type.valueChanges.subscribe((value) => {
      if (value === 'fixed') {
        this.editCycleForm.controls.price.clearValidators();
      } else {
        this.editCycleForm.controls.price.setValidators([Validators.min(0), Validators.max(100)]);
      }
    });

    this.editCycleForm.valueChanges.subscribe(() => {
      this.backendErrors = FormErrorsHelper.setValidationErrors(this.editCycleForm, '', this.backendErrors);
    });

    this.updateControls();
  }

  defaultCurrencySelected() {
    if (this.data.createOptions) {
      const selectedCurrency = this.data.createOptions.currencies.find(
        c => c.code === this.editCycleForm.controls.currency.value
      );

      return !!selectedCurrency && selectedCurrency.is_default;
    } else {
      return false;
    }
  }

  updateControls() {
    if (this.editCycleForm.controls.is_relative_price.value) {
      this.editCycleForm.controls.price.disable({emitEvent: false});
      this.editCycleForm.controls.setup_fee.disable({emitEvent: false});
    } else {
      this.editCycleForm.controls.price.enable({emitEvent: false});
      this.editCycleForm.controls.setup_fee.enable({emitEvent: false});
    }

    if (this.defaultCurrencySelected()) {
      this.editCycleForm.controls.is_relative_price.setValue(false, {emitEvent: false});
      this.editCycleForm.controls.is_relative_price.disable({emitEvent: false});
      this.editCycleForm.controls.price.enable({emitEvent: false});
      this.editCycleForm.controls.setup_fee.enable({emitEvent: false});
    } else {
      this.editCycleForm.controls.is_relative_price.enable({emitEvent: false});
    }
  }

  addCycle() {
    if (this.editCycleForm.invalid) {
      this.editCycleForm.markAllAsTouched();
      this.backendErrors = FormErrorsHelper.setValidationErrors(this.editCycleForm, '', this.backendErrors);
      return;
    }
    const value = this.editCycleForm.value as IConfigurableOptionCycleModel;

    if (this.data.option) {
      value.option = this.data.option.id;
    }

    if (this.data.choice && this.data.choice.id) {
      value.value = this.data.choice.id;
    }

    let request;

    if (this.data.cycle) {
      value.id = this.data.cycle.id;
      request = this.configurableOptionsCycleApiService.update(value.id, value);
    } else {
      request = this.configurableOptionsCycleApiService.create(value);
    }

    this.loading = true;
    request.subscribe(() => {
        this.dialogRef.close(true);
      },
      (error) => {
        if (error.error) {
          this.backendErrors = error.error;
          this.formErrors.setBackendErrors(error.error);
        }
      }
    ).add(() => {
      this.loading = false;
    });
  }
}
