import { greaterThanValidator } from '@/core/validators/greater.validator';
import { AbstractForm } from '@/shared/abstractClasses';
import { EnumSelectComponent } from '@/shared/apiEnum/select.component';
import { InputComponent } from '@/shared/components';
import { AmountPercentageInputComponent } from '@/shared/components/amountPercentageInput/amount-percentage-input.component';
import { TGoldKarat } from '@/shared/localEnum/constants/goldKarat';
import { formatWithCurrency } from '@/utils';
import { Component, computed, EventEmitter, Input, Output, signal } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { ButtonDirective } from 'primeng/button';
import { SelectButton, SelectButtonChangeEvent } from 'primeng/selectbutton';
import { debounceTime } from 'rxjs/operators';
import { IGoldPayload, IPosOrderItem } from '../../../models';
import { PosFormDialogAmountCardTemplateComponent } from '../form-dialog-amount-card-template.component';

@Component({
  selector: 'pos-gold-payload-form',
  templateUrl: './form.component.html',
  imports: [
    FormsModule,
    ReactiveFormsModule,
    InputComponent,
    EnumSelectComponent,
    PosFormDialogAmountCardTemplateComponent,
    SelectButton,
    AmountPercentageInputComponent,
    ButtonDirective,
  ],
})
export class PosGoldPayloadFormComponent extends AbstractForm<
  IPosOrderItem<IGoldPayload>,
  IPosOrderItem<IGoldPayload>
> {
  @Output() onSubmitForm = new EventEmitter<IGoldPayload>();
  @Output() onChangeTotalAmount = new EventEmitter<number>();

  readonly discountTypeItems = [
    {
      label: 'از سود',
      value: 1,
    },
    {
      label: 'از کل',
      value: 2,
    },
  ];

  discountType = signal<number>(1);
  unitWithQuantity = signal<number>(0);
  totalAmountBeforeProfit = signal<number>(0);
  baseTotalAmount = signal<number>(0);
  baseAmountForDiscountCalculation = signal<number>(0);
  taxAmount = signal<number>(0);
  totalAmount = signal<number>(0);
  formVisible = signal<boolean>(false);

  preparedCTAText = computed(() => (this.editMode ? 'اعمال ویرایش' : 'افزودن به لیست خرید'));

  private readonly initialForm = () => {
    const form = this.fb.group({
      unit_price: [this.initialValues?.unit_price || 0, [Validators.required]],
      quantity: [this.initialValues?.quantity || 0, [Validators.required, greaterThanValidator(0)]],
      discount_amount: [this.initialValues?.discount || 0],
      discount_percentage: [0, [Validators.max(100), Validators.min(0)]],
      payload: this.fb.group({
        commission_amount: [this.initialValues?.payload?.commission || 0, [Validators.required]],
        commission_percentage: [0, [Validators.required, Validators.max(100), Validators.min(0)]],
        wages_amount: [this.initialValues?.payload?.wages || 0, [Validators.required]],
        wages_percentage: [0, [Validators.required, Validators.max(100), Validators.min(0)]],
        profit_amount: [this.initialValues?.payload?.profit || 0, [Validators.required]],
        profit_percentage: [0, [Validators.required, Validators.max(100), Validators.min(0)]],
        karat: [this.initialValues?.payload?.karat || '', [Validators.required]],
      }),
    });

    form.valueChanges.pipe(debounceTime(100), takeUntilDestroyed()).subscribe((value) => {
      this.updateCalculateAmount(value as any);
    });

    form.controls.payload.controls.profit_amount.valueChanges
      .pipe(takeUntilDestroyed())
      .subscribe(() => {
        // if ((form.controls.discount_amount.value || 0) > (value || 0)) {
        form.controls.discount_amount.setValue(0, { emitEvent: false });
        // }
      });
    form.controls.payload.controls.profit_percentage.valueChanges
      .pipe(takeUntilDestroyed())
      .subscribe(() => {
        form.controls.discount_amount.setValue(0, { emitEvent: false });
      });

    return form;
  };

  form = this.initialForm();

  @Input() set visibleForm(v: boolean) {
    if (v) {
      if (this.editMode) {
        this.form.patchValue(this.initialValues || {}, { emitEvent: false });
        this.updateCalculateAmount(this.form.value as any);
      }
      this.formVisible.set(true);
    } else {
      this.formVisible.set(false);
    }
  }
  // form visibility and initial patching is controlled by the parent via `visibleForm` input

  override submitForm(payload: IPosOrderItem) {
    this.onSubmit.emit({
      ...payload,
      total_amount: this.totalAmount(),
      base_total_amount: this.baseTotalAmount(),
      tax_amount: this.taxAmount(),
      payload: {
        commission: this.form.controls.payload.controls.commission_amount.value || 0,
        karat: this.form.controls.payload.controls.karat.value as TGoldKarat,
        profit: this.form.controls.payload.controls.profit_amount.value || 0,
        wages: this.form.controls.payload.controls.wages_amount.value || 0,
      },
    });
  }

  updateCalculateAmount(payload: Partial<IPosOrderItem<any>>) {
    const commissionAmount = Number(payload.payload?.commission_amount ?? '0');
    const wageAmount = Number(payload.payload?.wages_amount ?? '0');
    const discountAmount = Number(payload.discount_amount ?? '0');
    const profitAmount = Number(payload.payload?.profit_amount ?? '0');
    const unitPrice = Number(payload.unit_price ?? '0');
    const quantity = Number(payload.quantity ?? '0');

    const unitWithQuantity = unitPrice * quantity;
    const totalAmountBeforeProfit = unitWithQuantity + wageAmount + commissionAmount;
    const baseTotalAmount = totalAmountBeforeProfit + profitAmount;
    const baseAmountForDiscountCalculation =
      this.discountType() === 1 ? profitAmount : unitWithQuantity;

    const taxAmount =
      (profitAmount +
        commissionAmount +
        wageAmount -
        (this.discountType() === 1 ? discountAmount : 0)) *
      0.1;
    const totalAmount = baseTotalAmount - discountAmount + taxAmount;

    this.unitWithQuantity.set(unitWithQuantity);
    this.totalAmountBeforeProfit.set(totalAmountBeforeProfit);
    this.baseTotalAmount.set(baseTotalAmount);
    this.taxAmount.set(taxAmount);
    this.totalAmount.set(totalAmount);
    this.baseAmountForDiscountCalculation.set(baseAmountForDiscountCalculation);

    this.onChangeTotalAmount.emit(totalAmount);
  }

  toAmountFormat(amount: number) {
    if (!amount) {
      return '';
    }
    return `(${formatWithCurrency(amount)})`;
  }

  changeDiscountCalculation($event: SelectButtonChangeEvent) {
    this.discountType.set($event.value);

    this.updateCalculateAmount(this.form.value as any);
  }
}
