import { inject, Injectable } from '@angular/core';
import {
  ShoppingCartFacade,
  CompleteCrmOrderParams,
  CheckoutMetadataService,
} from '@isa/checkout/data-access';
import { OrderCreationFacade, DisplayOrder } from '@isa/oms/data-access';
import { logger } from '@isa/core/logging';
import { HttpErrorResponse } from '@angular/common/http';
import { isResponseArgs } from '@isa/common/data-access';
import { DisplayOrderDTO } from '@generated/swagger/oms-api';
import { injectFeedbackErrorDialog } from '@isa/ui/dialog';

/**
 * Orchestrates checkout completion and order creation.
 *
 * @remarks
 * This service coordinates cross-domain operations between checkout and OMS.
 * It belongs in the feature layer to avoid data-access layer coupling.
 *
 * **Responsibilities:**
 * - Coordinate CRM data transformation via ShoppingCartFacade
 * - Orchestrate checkout completion
 * - Trigger order creation
 * - Provide unified error handling for the entire flow
 *
 * This orchestrator demonstrates proper architectural layering:
 * - Feature layer orchestrates cross-domain workflows
 * - Data-access facades remain focused on single-domain operations
 * - Services don't depend on other domain facades
 */
@Injectable()
export class CheckoutCompletionOrchestratorService {
  #logger = logger(() => ({
    service: 'CheckoutCompletionOrchestratorService',
  }));

  #shoppingCartFacade = inject(ShoppingCartFacade);
  #orderCreationFacade = inject(OrderCreationFacade);
  #checkoutMetadataService = inject(CheckoutMetadataService);
  #errorFeedbackDialog = injectFeedbackErrorDialog();

  /**
   * Complete checkout with CRM data and create orders.
   *
   * @param params - CRM-sourced checkout parameters
   * @param abortSignal - Optional cancellation signal
   * @returns Created orders
   * @throws CheckoutCompletionError - If validation or order creation fails
   *
   * @example
   * ```typescript
   * const orders = await orchestrator.completeCheckoutAndCreateOrders({
   *   shoppingCartId: 123,
   *   crmCustomer: customer,
   *   crmShippingAddress: address,
   *   crmPayer: payer,
   *   notificationChannels: 1,
   * });
   * ```
   */
  async completeCheckoutAndCreateOrders(
    params: CompleteCrmOrderParams,
    tabId?: number,
    abortSignal?: AbortSignal,
  ): Promise<DisplayOrderDTO[]> {
    this.#logger.info('Starting checkout completion and order creation');

    try {
      // Step 1: Complete checkout with CRM data transformation
      this.#logger.debug('Completing checkout with CRM data');
      const checkoutId = await this.#shoppingCartFacade.completeWithCrmData(
        params,
        abortSignal,
      );

      await this.#shoppingCartFacade.getShoppingCart(
        params.shoppingCartId,
        abortSignal,
      );

      let orders: DisplayOrderDTO[] = [];

      try {
        orders =
          await this.#orderCreationFacade.createOrdersFromCheckout(checkoutId);
      } catch (error) {
        /**
         * Fehlerbehandlung für partielle Bestellungserstellung
         *
         * Hintergrund:
         * Das Backend kann HTTP-Fehler zurückgeben (z.B. Validierungswarnungen),
         * obwohl die Bestellungen erfolgreich erstellt wurden. In solchen Fällen
         * enthält die Fehlerantwort die erstellten Bestellungen im 'result'-Feld.
         *
         * Verhalten:
         * - Wenn Bestellungen erstellt wurden (orders.length > 0):
         *   → Warnung loggen, aber mit den erstellten Bestellungen fortfahren
         * - Wenn keine Bestellungen erstellt wurden (orders.length === 0):
         *   → Fehler loggen und Exception werfen
         *
         * Dies verhindert Datenverlust bei partiellen Erfolgen und verbessert
         * die Benutzererfahrung, indem erfolgreiche Bestellungen nicht verworfen werden.
         *
         * TODO: Benutzer-Feedback implementieren
         * Aktuell wird nur geloggt, aber dem Benutzer wird kein visuelles Feedback
         * über potenzielle Probleme bei der Bestellungserstellung gegeben.
         * Mögliche Lösungen:
         * - Toast-Benachrichtigung mit Warnhinweis
         * - Banner auf der Bestätigungsseite mit Details zu Validierungswarnungen
         * - Dialog mit Zusammenfassung der Probleme
         */
        if (
          error instanceof HttpErrorResponse &&
          isResponseArgs<DisplayOrderDTO[]>(error.error)
        ) {
          const responseArgs = error.error;
          orders = responseArgs.result;
          this.#errorFeedbackDialog({
            data: {
              errorMessage: responseArgs.message,
            },
          });

          // Wenn Bestellungen erstellt wurden, loggen wir eine Warnung aber fahren fort
          if (orders.length > 0) {
            this.#logger.warn(
              'Order creation encountered issues but returned partial results',
              () => ({
                createdOrderCount: orders.length,
                errorMessage: responseArgs.message,
                invalidProperties: responseArgs.invalidProperties,
              }),
            );
          } else {
            this.#logger.error('Order creation failed with no orders created', {
              errorMessage: responseArgs.message,
              invalidProperties: responseArgs.invalidProperties,
            });
            throw error;
          }
        } else {
          this.#logger.error('Order creation failed', error);
          throw error;
        }
      }

      if (tabId) {
        // Step 2: Cleanup the reward shopping cart
        this.#checkoutMetadataService.setRewardShoppingCartId(tabId, undefined);
      }

      this.#logger.info(
        'Checkout completion and order creation successful',
        () => ({
          orderCount: orders.length,
        }),
      );

      return orders;
    } catch (error) {
      this.#logger.error(
        'Checkout completion and order creation failed',
        error,
      );
      throw error;
    }
  }
}
