/**
 * Salesforce Opportunity Integration Service (Facade)
 *
 * Manages Opportunity records for service lifecycle tracking.
 * Delegates to focused sub-services for different operations.
 *
 * Key responsibilities:
 * - Create Opportunities at interest triggers (eligibility request, registration)
 * - Update Opportunity stages as orders progress
 * - Link WHMCS services to Opportunities for cancellation workflows
 * - Store cancellation form data on Opportunities
 *
 * Uses existing Salesforce stage values:
 * - Introduction → Ready → Post Processing → Active → △Cancelling → 〇Cancelled
 *
 * @see docs/salesforce/OPPORTUNITY-LIFECYCLE-GUIDE.md for complete documentation
 */

import { Injectable } from "@nestjs/common";
import {
  type OpportunityStageValue,
  type OpportunityProductTypeValue,
  type CreateOpportunityRequest,
  type OpportunityRecord,
} from "@customer-portal/domain/opportunity";
import {
  OpportunityQueryService,
  type InternetCancellationStatusResult,
  type SimCancellationStatusResult,
} from "./opportunity/opportunity-query.service.js";
import { OpportunityCancellationService } from "./opportunity/opportunity-cancellation.service.js";
import { OpportunityMutationService } from "./opportunity/opportunity-mutation.service.js";
import type {
  InternetCancellationOpportunityDataInput,
  SimCancellationOpportunityDataInput,
} from "./opportunity/opportunity.types.js";

/**
 * Facade service that provides a unified API for Opportunity operations.
 * Delegates to specialized sub-services for focused responsibilities.
 */
@Injectable()
export class SalesforceOpportunityService {
  constructor(
    private readonly queryService: OpportunityQueryService,
    private readonly cancellationService: OpportunityCancellationService,
    private readonly mutationService: OpportunityMutationService
  ) {}

  // ==========================================================================
  // Core CRUD Operations (via MutationService)
  // ==========================================================================

  /**
   * Create a new Opportunity in Salesforce
   */
  async createOpportunity(request: CreateOpportunityRequest): Promise<string> {
    return this.mutationService.createOpportunity(request);
  }

  /**
   * Update Opportunity stage
   */
  async updateStage(
    opportunityId: string,
    stage: OpportunityStageValue,
    reason?: string
  ): Promise<void> {
    return this.mutationService.updateStage(opportunityId, stage, reason);
  }

  // ==========================================================================
  // Cancellation Operations (via CancellationService)
  // ==========================================================================

  /**
   * Update Opportunity with Internet cancellation data from form submission
   */
  async updateInternetCancellationData(
    opportunityId: string,
    data: InternetCancellationOpportunityDataInput
  ): Promise<void> {
    return this.cancellationService.updateInternetCancellationData(opportunityId, data);
  }

  /**
   * Update Opportunity with SIM cancellation data from form submission
   */
  async updateSimCancellationData(
    opportunityId: string,
    data: SimCancellationOpportunityDataInput
  ): Promise<void> {
    return this.cancellationService.updateSimCancellationData(opportunityId, data);
  }

  /**
   * Mark cancellation as complete
   */
  async markCancellationComplete(opportunityId: string): Promise<void> {
    return this.cancellationService.markCancellationComplete(opportunityId);
  }

  // ==========================================================================
  // Lookup Operations (via QueryService)
  // ==========================================================================

  /**
   * Find an open Opportunity for an account by product type
   */
  async findOpenOpportunityForAccount(
    accountId: string,
    productType: OpportunityProductTypeValue,
    options?: { stages?: OpportunityStageValue[] }
  ): Promise<string | null> {
    return this.queryService.findOpenOpportunityForAccount(accountId, productType, options);
  }

  /**
   * Find Opportunity linked to an Order
   */
  async findOpportunityByOrderId(orderId: string): Promise<string | null> {
    return this.queryService.findOpportunityByOrderId(orderId);
  }

  /**
   * Find Opportunity by WHMCS Service ID
   */
  async findOpportunityByWhmcsServiceId(whmcsServiceId: number): Promise<string | null> {
    return this.queryService.findOpportunityByWhmcsServiceId(whmcsServiceId);
  }

  /**
   * Get full Opportunity details by ID
   */
  async getOpportunityById(opportunityId: string): Promise<OpportunityRecord | null> {
    return this.queryService.getOpportunityById(opportunityId);
  }

  /**
   * Get Internet cancellation status by WHMCS Service ID
   */
  async getInternetCancellationStatus(
    whmcsServiceId: number
  ): Promise<InternetCancellationStatusResult | null> {
    return this.queryService.getInternetCancellationStatus(whmcsServiceId);
  }

  /**
   * Get Internet cancellation status by Opportunity ID
   */
  async getInternetCancellationStatusByOpportunityId(
    opportunityId: string
  ): Promise<InternetCancellationStatusResult | null> {
    return this.queryService.getInternetCancellationStatusByOpportunityId(opportunityId);
  }

  /**
   * Get SIM cancellation status by WHMCS Service ID
   */
  async getSimCancellationStatus(
    whmcsServiceId: number
  ): Promise<SimCancellationStatusResult | null> {
    return this.queryService.getSimCancellationStatus(whmcsServiceId);
  }

  /**
   * Get SIM cancellation status by Opportunity ID
   */
  async getSimCancellationStatusByOpportunityId(
    opportunityId: string
  ): Promise<SimCancellationStatusResult | null> {
    return this.queryService.getSimCancellationStatusByOpportunityId(opportunityId);
  }

  // ==========================================================================
  // Lifecycle Helpers (via MutationService)
  // ==========================================================================

  /**
   * Link a WHMCS Service ID to an Opportunity
   */
  async linkWhmcsServiceToOpportunity(
    opportunityId: string,
    whmcsServiceId: number
  ): Promise<void> {
    return this.mutationService.linkWhmcsServiceToOpportunity(opportunityId, whmcsServiceId);
  }

  /**
   * Link an Order to an Opportunity
   */
  async linkOrderToOpportunity(orderId: string, opportunityId: string): Promise<void> {
    return this.mutationService.linkOrderToOpportunity(orderId, opportunityId);
  }
}
