import { Injectable, BadRequestException, Inject } from "@nestjs/common";
import { Logger } from "nestjs-pino";
import { InternetEligibilityService } from "@bff/modules/services/application/internet-eligibility.service.js";
import { WhmcsConnectionFacade } from "@bff/integrations/whmcs/facades/whmcs.facade.js";
import { extractErrorMessage } from "@bff/core/utils/error.util.js";
import {
  ValidationErrorCode,
  createValidationError,
  validationFailure,
  validationSuccess,
  type ValidationResult,
} from "./base-validator.interface.js";
import type * as Providers from "@customer-portal/domain/subscriptions/providers";

type WhmcsProduct = Providers.WhmcsProductRaw;

/**
 * Internet Order Validator
 *
 * Validates Internet-specific order requirements:
 * - Eligibility status (must be approved)
 * - No duplicate active Internet service
 */
@Injectable()
export class InternetOrderValidator {
  constructor(
    @Inject(Logger) private readonly logger: Logger,
    private readonly internetEligibilityService: InternetEligibilityService,
    private readonly whmcs: WhmcsConnectionFacade
  ) {}

  /**
   * Validate Internet order eligibility requirements
   */
  async validateEligibility(userId: string): Promise<ValidationResult> {
    const eligibility = await this.internetEligibilityService.getEligibilityDetailsForUser(userId);

    if (eligibility.status === "not_requested") {
      return validationFailure([
        createValidationError(
          ValidationErrorCode.INTERNET_ELIGIBILITY_NOT_REQUESTED,
          "Internet eligibility review is required before ordering. Please request an eligibility review from the Internet services page and try again."
        ),
      ]);
    }

    if (eligibility.status === "pending") {
      return validationFailure([
        createValidationError(
          ValidationErrorCode.INTERNET_ELIGIBILITY_PENDING,
          "Internet eligibility review is still in progress. Please wait for review to complete and try again."
        ),
      ]);
    }

    if (eligibility.status === "ineligible") {
      return validationFailure([
        createValidationError(
          ValidationErrorCode.INTERNET_INELIGIBLE,
          "Internet service is not available for your address. Please contact support if you believe this is incorrect."
        ),
      ]);
    }

    return validationSuccess();
  }

  /**
   * Validate no duplicate active Internet service exists
   * In development mode, logs warning but allows order
   */
  async validateNoDuplication(userId: string, whmcsClientId: number): Promise<ValidationResult> {
    const isDevelopment = process.env["NODE_ENV"] === "development";

    try {
      const products = await this.whmcs.getClientsProducts({ clientid: whmcsClientId });
      const productContainer = products.products?.product;
      const existing = Array.isArray(productContainer)
        ? productContainer
        : productContainer
          ? [productContainer]
          : [];

      // Check for active Internet products
      const activeInternetProducts = existing.filter((product: WhmcsProduct) => {
        const groupName = (product.groupname || product.translated_groupname || "").toLowerCase();
        const status = (product.status || "").toLowerCase();
        return groupName.includes("internet") && status === "active";
      });

      if (activeInternetProducts.length > 0) {
        const message = "An active Internet service already exists for this account";

        if (isDevelopment) {
          this.logger.warn(
            {
              userId,
              whmcsClientId,
              activeInternetCount: activeInternetProducts.length,
              environment: "development",
            },
            `[DEV MODE] ${message} - allowing order to proceed in development`
          );
          // In dev, just log warning and allow order
          return validationSuccess();
        }

        // In production, block the order
        this.logger.error(
          {
            userId,
            whmcsClientId,
            activeInternetCount: activeInternetProducts.length,
          },
          message
        );
        return validationFailure([
          createValidationError(ValidationErrorCode.INTERNET_SERVICE_EXISTS, message),
        ]);
      }

      return validationSuccess();
    } catch (error) {
      const err = extractErrorMessage(error);
      this.logger.error({ err, userId, whmcsClientId }, "Internet duplicate check failed");

      if (isDevelopment) {
        this.logger.warn(
          { environment: "development" },
          "[DEV MODE] WHMCS check failed - allowing order to proceed in development"
        );
        return validationSuccess();
      }

      return validationFailure([
        createValidationError(
          ValidationErrorCode.INTERNET_CHECK_FAILED,
          "Unable to verify existing Internet services. Please try again."
        ),
      ]);
    }
  }

  /**
   * Validate all Internet order requirements
   */
  async validate(userId: string, whmcsClientId: number): Promise<ValidationResult> {
    // First check eligibility
    const eligibilityResult = await this.validateEligibility(userId);
    if (!eligibilityResult.success) {
      return eligibilityResult;
    }

    // Then check for duplicates
    return this.validateNoDuplication(userId, whmcsClientId);
  }

  /**
   * Validate and throw BadRequestException on failure
   */
  async validateOrThrow(userId: string, whmcsClientId: number): Promise<void> {
    const result = await this.validate(userId, whmcsClientId);

    if (!result.success) {
      const error = result.errors?.[0];
      throw new BadRequestException(error?.message ?? "Internet order validation failed");
    }
  }
}
