import {
  ChangeDetectionStrategy,
  Component,
  computed,
  inject,
  resource,
} from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { toSignal } from '@angular/core/rxjs-interop';
import { z } from 'zod';

import { NgIconComponent, provideIcons } from '@ng-icons/core';
import { isaActionChevronLeft } from '@isa/icons';
import { ButtonComponent } from '@isa/ui/buttons';
import { injectTabId } from '@isa/core/tabs';
import { Location } from '@angular/common';
import { ExpandableDirectives } from '@isa/ui/expandable';
import { ProgressBarComponent } from '@isa/ui/progress-bar';
import {
  ReturnDetailsService,
  ReturnProcessStore,
  ReturnDetailsStore,
} from '@isa/oms/data-access';
import { ReturnDetailsStaticComponent } from './return-details-static/return-details-static.component';
import { ReturnDetailsLazyComponent } from './return-details-lazy/return-details-lazy.component';
import { logger } from '@isa/core/logging';
import { groupBy } from 'lodash';

@Component({
  selector: 'oms-feature-return-details',
  templateUrl: './return-details.component.html',
  styleUrls: ['./return-details.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [
    ReturnDetailsStaticComponent,
    ReturnDetailsLazyComponent,
    NgIconComponent,
    ButtonComponent,
    ExpandableDirectives,
    ProgressBarComponent,
  ],
  providers: [provideIcons({ isaActionChevronLeft }), ReturnDetailsStore],
})
export class ReturnDetailsComponent {
  #logger = logger(() => ({
    component: 'ReturnDetailsComponent',
    itemId: this.receiptId(),
    processId: this.processId(),
    params: this.params(),
  }));
  #store = inject(ReturnDetailsStore);
  #returnDetailsService = inject(ReturnDetailsService);
  #returnProcessStore = inject(ReturnProcessStore);

  private processId = injectTabId();

  private _router = inject(Router);

  private _activatedRoute = inject(ActivatedRoute);

  location = inject(Location);

  params = toSignal(this._activatedRoute.params);

  receiptId = computed<number>(() => {
    const params = this.params();
    if (params) {
      return z.coerce.number().parse(params['receiptId']);
    }
    throw new Error('No receiptId found in route params');
  });

  receiptResource = this.#store.receiptResource(this.receiptId);

  customerReceiptsResource = resource({
    params: this.receiptResource.value,
    loader: async ({ params, abortSignal }) => {
      const email = params.buyer?.communicationDetails?.email;
      if (!email) {
        return [];
      }

      try {
        return await this.#returnDetailsService.fetchReceiptsByEmail(
          { email },
          abortSignal,
        );
      } catch (error) {
        this.#logger.error('Failed to fetch customer receipts', error);
        return [];
      }
    },
  });

  canStartProcess = computed(() => {
    return (
      this.#store.selectedItemIds().length > 0 && this.processId() !== undefined
    );
  });

  startProcess() {
    if (!this.canStartProcess()) {
      this.#logger.warn(
        'Cannot start process: No items selected or no process ID',
      );
      return;
    }

    const processId = this.processId();
    const selectedItems = this.#store.selectedItems();
    const selectedQuantites = this.#store.selectedQuantityMap();
    const selectedProductCategories = this.#store.itemCategoryMap();

    this.#logger.info('Starting return process', () => ({
      processId: processId,
      selectedItems: selectedItems.map((item) => item.id),
    }));

    if (!selectedItems.length || !processId) {
      return;
    }

    const itemsGrouptByReceiptId = groupBy(
      selectedItems,
      (item) => item.receipt?.id,
    );
    const receipts = this.#store.receiptsEntityMap();

    const returns = Object.entries(itemsGrouptByReceiptId).map(
      ([receiptId, items]) => ({
        receipt: receipts[Number(receiptId)],
        items: items.map((item) => {
          const receiptItem = item;
          return {
            receiptItem,
            quantity: selectedQuantites[receiptItem.id],
            category: selectedProductCategories[receiptItem.id],
          };
        }),
      }),
    );

    this.#logger.info('Starting return process with returns', () => ({
      processId,
      returns,
    }));

    this.#returnProcessStore.startProcess({
      processId,
      returns,
    });

    this._router.navigate(['../../', 'process'], {
      relativeTo: this._activatedRoute,
    });
  }
}
