import {
  ChangeDetectionStrategy,
  Component,
  signal,
  computed,
  input,
  inject,
  output,
} from '@angular/core';
import { FormsModule } from '@angular/forms';
import { PositiveIntegerInputDirective } from '@isa/utils/positive-integer-input';
import { ButtonComponent } from '@isa/ui/buttons';
import {
  CustomerBookingReasonsResource,
  CustomerCardBookingFacade,
} from '@isa/crm/data-access';
import {
  injectFeedbackDialog,
  injectFeedbackErrorDialog,
} from '@isa/ui/dialog';
import { logger } from '@isa/core/logging';
import {
  DropdownButtonComponent,
  DropdownOptionComponent,
} from '@isa/ui/input-controls';
import { TooltipIconComponent } from '@isa/ui/tooltip';

@Component({
  selector: 'crm-customer-booking',
  imports: [
    FormsModule,
    PositiveIntegerInputDirective,
    ButtonComponent,
    DropdownButtonComponent,
    DropdownOptionComponent,
    TooltipIconComponent,
  ],
  templateUrl: './crm-feature-customer-booking.component.html',
  styleUrl: './crm-feature-customer-booking.component.css',
  changeDetection: ChangeDetectionStrategy.OnPush,
  providers: [CustomerBookingReasonsResource],
})
export class CrmFeatureCustomerBookingComponent {
  #logger = logger(() => ({
    component: 'CrmFeatureCustomerBookingComponent',
  }));
  #customerCardBookingFacade = inject(CustomerCardBookingFacade);
  #bookingReasonsResource = inject(CustomerBookingReasonsResource);
  #errorFeedbackDialog = injectFeedbackErrorDialog();
  #feedbackDialog = injectFeedbackDialog();
  readonly cardCode = input<string | undefined>(undefined);

  readonly booked = output<void>();

  readonly bookingReasons = this.#bookingReasonsResource.resource.value;
  readonly bookingReasonsLoading =
    this.#bookingReasonsResource.resource.isLoading;

  points = signal<number | undefined>(undefined);
  selectedReasonKey = signal<string | undefined>(undefined);
  isBooking = signal(false);

  selectedReason = computed(() => {
    const key = this.selectedReasonKey();
    const reasons = this.bookingReasons();
    return reasons?.find((r) => r.key === key);
  });

  calculatedPoints = computed(() => {
    const reason = this.selectedReason();
    const pointsValue = this.points();
    if (!reason || !pointsValue) return 0;
    return pointsValue * (reason.value ?? 1);
  });

  disableBooking = computed(() => {
    return (
      this.isBooking() ||
      this.bookingReasonsLoading() ||
      !this.selectedReasonKey() ||
      !this.points() ||
      this.points() === 0
    );
  });

  dropdownLabel = computed(() => {
    const reason = this.selectedReason()?.label;
    return reason ?? 'Buchungstyp';
  });

  async booking() {
    this.isBooking.set(true);
    try {
      const cardCode = this.cardCode();
      const reason = this.selectedReason();
      const calculatedPoints = this.calculatedPoints();

      if (!cardCode) {
        throw new Error('Kein Karten-Code vorhanden');
      }

      if (!reason) {
        throw new Error('Kein Buchungsgrund ausgewählt');
      }

      if (calculatedPoints === 0) {
        throw new Error('Punktezahl muss größer als 0 sein');
      }

      const currentBookingPartnerStore =
        await this.#customerCardBookingFacade.fetchCurrentBookingPartnerStore();
      const storeId = currentBookingPartnerStore?.key;

      await this.#customerCardBookingFacade.addBooking({
        cardCode,
        booking: {
          points: calculatedPoints,
          reason: reason.key,
          storeId: storeId,
        },
      });

      this.#feedbackDialog({
        data: {
          message: `${reason.label} erfolgreich durchgeführt`,
        },
      });
      this.booked.emit();
    } catch (error: unknown) {
      this.#logger.error('Booking Failed', () => ({ error }));
      this.#errorFeedbackDialog({
        data: {
          errorMessage:
            error instanceof Error
              ? error.message
              : 'Buchen/Stornieren fehlgeschlagen',
        },
      });
    } finally {
      this.isBooking.set(false);
      this.resetInputs();
    }
  }

  resetInputs() {
    this.points.set(undefined);
    this.selectedReasonKey.set(undefined);
  }
}
