/**
 * Opportunity Domain - Contract
 *
 * Business types and constants for Salesforce Opportunity lifecycle management.
 * Used to track customer journeys from interest through service cancellation.
 *
 * IMPORTANT: Stage values match existing Salesforce picklist values.
 * See docs/salesforce/OPPORTUNITY-LIFECYCLE-GUIDE.md for complete documentation.
 */

// ============================================================================
// Opportunity Stage Constants (Existing Salesforce Values)
// ============================================================================

/**
 * Opportunity lifecycle stages - these match existing Salesforce picklist values
 *
 * Portal Flow: Introduction -> Ready -> Post Processing -> Active -> △Cancelling -> 〇Cancelled
 */
export const OPPORTUNITY_STAGE = {
  // Interest/Lead stages
  INTRODUCTION: "Introduction", // Initial interest / eligibility pending (30%)
  WIKI: "WIKI", // Low priority / informational (10%)

  // Ready to proceed
  READY: "Ready", // Eligible / ready to order (60%)

  // Order/Processing stages
  POST_PROCESSING: "Post Processing", // Order placed, processing (75%)

  // Active service
  ACTIVE: "Active", // Service active (90%)

  // Cancellation stages
  CANCELLING: "△Cancelling", // Cancellation pending (100%, Open)
  CANCELLED: "〇Cancelled", // Successfully cancelled (100%, Closed/Won)

  // Completed/Closed stages
  COMPLETED: "Completed", // Service completed normally (100%, Closed/Won)
  VOID: "Void", // Lost / not eligible (0%, Closed/Lost)
  PENDING: "Pending", // On hold / abandoned (0%, Closed/Lost)
} as const;

export type OpportunityStageValue = (typeof OPPORTUNITY_STAGE)[keyof typeof OPPORTUNITY_STAGE];

// ============================================================================
// Application Stage Constants (Existing Salesforce Values)
// ============================================================================

/**
 * Application stage picklist (Application_Stage__c)
 * Tracks application process step
 *
 * For portal, we use INTRO_1 (single-step intro, not multi-email legacy flow)
 */
export const APPLICATION_STAGE = {
  INTRO_1: "INTRO-1", // Portal default - simple introduction
  NA: "N/A", // Not applicable
} as const;

export type ApplicationStageValue = (typeof APPLICATION_STAGE)[keyof typeof APPLICATION_STAGE];

// ============================================================================
// Cancellation Notice Constants (Existing Salesforce Values)
// ============================================================================

/**
 * Cancellation notice status (CancellationNotice__c)
 * Tracks whether cancellation form has been received
 */
export const CANCELLATION_NOTICE = {
  RECEIVED: "有", // Form received
  NOT_YET: "未", // Not yet received (default)
  NOT_REQUIRED: "不要", // Not required
  TRANSFER: "移転", // Transferring (moving)
} as const;

export type CancellationNoticeValue =
  (typeof CANCELLATION_NOTICE)[keyof typeof CANCELLATION_NOTICE];

// ============================================================================
// Line Return Status Constants (Existing Salesforce Values)
// ============================================================================

/**
 * Rental equipment return status (LineReturn__c)
 * Tracks equipment return process after cancellation
 */
export const LINE_RETURN_STATUS = {
  NOT_YET: "NotYet", // Not yet initiated (default)
  SENT_KIT: "SentKit", // Return kit sent to customer
  PICKUP_SCHEDULED: "AS/Pickup予定", // Pickup scheduled
  RETURNED_1: "Returned1", // Returned (variant 1)
  RETURNED: "Returned2", // Returned
  NTT_DISPATCH: "NTT派遣", // NTT dispatch
  COMPENSATED: "Compensated", // Compensation fee charged
  NA: "N/A", // Not applicable (no equipment)
} as const;

export type LineReturnStatusValue = (typeof LINE_RETURN_STATUS)[keyof typeof LINE_RETURN_STATUS];

// ============================================================================
// Commodity Type Constants (Existing Salesforce Field: CommodityType)
// ============================================================================

/**
 * Commodity types - uses existing Salesforce CommodityType picklist
 * Maps to WHMCS product categories
 */
export const COMMODITY_TYPE = {
  // Internet types
  PERSONAL_HOME_INTERNET: "Personal SonixNet Home Internet",
  CORPORATE_HOME_INTERNET: "Corporate SonixNet Home Internet",
  // SIM
  SIM: "SIM",
  // VPN
  VPN: "VPN",
  // Other (not used by portal)
  TECH_SUPPORT: "Onsite Support",
} as const;

export type CommodityTypeValue = (typeof COMMODITY_TYPE)[keyof typeof COMMODITY_TYPE];

/**
 * Simplified product types for portal logic
 * Maps multiple CommodityType values to simple categories
 */
export const OPPORTUNITY_PRODUCT_TYPE = {
  INTERNET: "Internet",
  SIM: "SIM",
  VPN: "VPN",
} as const;

export type OpportunityProductTypeValue =
  (typeof OPPORTUNITY_PRODUCT_TYPE)[keyof typeof OPPORTUNITY_PRODUCT_TYPE];

/**
 * Map CommodityType to simplified product type
 */
export function getCommodityTypeProductType(
  commodityType: CommodityTypeValue
): OpportunityProductTypeValue | null {
  switch (commodityType) {
    case COMMODITY_TYPE.PERSONAL_HOME_INTERNET:
    case COMMODITY_TYPE.CORPORATE_HOME_INTERNET:
      return OPPORTUNITY_PRODUCT_TYPE.INTERNET;
    case COMMODITY_TYPE.SIM:
      return OPPORTUNITY_PRODUCT_TYPE.SIM;
    case COMMODITY_TYPE.VPN:
      return OPPORTUNITY_PRODUCT_TYPE.VPN;
    default:
      return null;
  }
}

/**
 * Get default CommodityType for a product type
 * Used when creating new Opportunities
 *
 * NOTE: Currently only Personal SonixNet Home Internet is used for Internet.
 * Corporate can be added later when needed.
 */
export function getDefaultCommodityType(
  productType: OpportunityProductTypeValue
): CommodityTypeValue {
  switch (productType) {
    case OPPORTUNITY_PRODUCT_TYPE.INTERNET:
      // Always use Personal for now - Corporate support can be added later
      return COMMODITY_TYPE.PERSONAL_HOME_INTERNET;
    case OPPORTUNITY_PRODUCT_TYPE.SIM:
      return COMMODITY_TYPE.SIM;
    case OPPORTUNITY_PRODUCT_TYPE.VPN:
      return COMMODITY_TYPE.VPN;
  }
}

/**
 * Default commodity types used when creating opportunities from portal
 * These are the only values the portal will create - agents can use others
 */
export const PORTAL_DEFAULT_COMMODITY_TYPES = {
  INTERNET: COMMODITY_TYPE.PERSONAL_HOME_INTERNET,
  SIM: COMMODITY_TYPE.SIM,
  VPN: COMMODITY_TYPE.VPN,
} as const;

// ============================================================================
// Opportunity Source Constants
// ============================================================================

/**
 * Sources from which Opportunities are created (Opportunity_Source__c)
 */
export const OPPORTUNITY_SOURCE = {
  INTERNET_ELIGIBILITY: "Portal - Internet Eligibility Request",
  SIM_CHECKOUT_REGISTRATION: "Portal - SIM Checkout Registration",
  ORDER_PLACEMENT: "Portal - Order Placement",
  AGENT_CREATED: "Agent Created",
} as const;

export type OpportunitySourceValue = (typeof OPPORTUNITY_SOURCE)[keyof typeof OPPORTUNITY_SOURCE];

// ============================================================================
// Opportunity Matching / Stage Sets
// ============================================================================

/**
 * Stages considered "open" (i.e. not closed) in our lifecycle.
 *
 * IMPORTANT:
 * - Do NOT use this list to match a *new* order or eligibility request to an existing Opportunity.
 *   For those flows we intentionally match a much smaller set of early-stage Opportunities.
 * - Use the `OPPORTUNITY_MATCH_STAGES_*` constants below instead.
 */
export const OPEN_OPPORTUNITY_STAGES: OpportunityStageValue[] = [
  OPPORTUNITY_STAGE.INTRODUCTION,
  OPPORTUNITY_STAGE.READY,
  OPPORTUNITY_STAGE.POST_PROCESSING,
  OPPORTUNITY_STAGE.ACTIVE,
];

/**
 * Stages eligible for matching during an Internet eligibility request.
 *
 * We only ever reuse the initial "Introduction" opportunity; later stages indicate the
 * customer journey has progressed beyond eligibility.
 */
export const OPPORTUNITY_MATCH_STAGES_INTERNET_ELIGIBILITY: OpportunityStageValue[] = [
  OPPORTUNITY_STAGE.INTRODUCTION,
];

/**
 * Stages eligible for matching during order placement.
 *
 * If a customer came from eligibility, the Opportunity will usually be in "Introduction" or "Ready".
 * We must never match an "Active" Opportunity for a new order (that would corrupt lifecycle tracking).
 */
export const OPPORTUNITY_MATCH_STAGES_ORDER_PLACEMENT: OpportunityStageValue[] = [
  OPPORTUNITY_STAGE.INTRODUCTION,
  OPPORTUNITY_STAGE.READY,
];

/**
 * Stages that indicate the Opportunity is closed
 */
export const CLOSED_OPPORTUNITY_STAGES: OpportunityStageValue[] = [
  OPPORTUNITY_STAGE.CANCELLED,
  OPPORTUNITY_STAGE.COMPLETED,
  OPPORTUNITY_STAGE.VOID,
  OPPORTUNITY_STAGE.PENDING,
];

// ============================================================================
// Cancellation Deadline Constants
// ============================================================================

/**
 * Day of month by which cancellation form must be received
 * If after this day, cancellation applies to next month
 */
export const CANCELLATION_DEADLINE_DAY = 25;

/**
 * Day of following month by which rental equipment must be returned
 */
export const RENTAL_RETURN_DEADLINE_DAY = 10;

// ============================================================================
// Cancellation Opportunity Data Types
// ============================================================================

/**
 * Cancellation data to populate on Opportunity for Internet services
 * Only core lifecycle fields - details go on Cancellation Case
 */
export interface InternetCancellationOpportunityData {
  /** End of cancellation month (YYYY-MM-DD format) */
  scheduledCancellationDate: string;

  /** Cancellation notice status (always 有 from portal) */
  cancellationNotice: CancellationNoticeValue;

  /** Initial line return status (always NotYet from portal) */
  lineReturnStatus: LineReturnStatusValue;
}

/**
 * SIM cancellation notice values (SIMCancellationNotice__c)
 * Tracks whether SIM cancellation form has been received
 */
export const SIM_CANCELLATION_NOTICE = {
  RECEIVED: "有", // Form received
  NOT_YET: "未", // Not yet received (default)
  NOT_REQUIRED: "不要", // Not required
} as const;

export type SimCancellationNoticeValue =
  (typeof SIM_CANCELLATION_NOTICE)[keyof typeof SIM_CANCELLATION_NOTICE];

/**
 * Cancellation data to populate on Opportunity for SIM services
 * NOTE: Customer comments go on the Cancellation Case, not Opportunity (same as Internet)
 */
export interface SimCancellationOpportunityData {
  /** End of cancellation month (YYYY-MM-DD format) */
  scheduledCancellationDate: string;

  /** SIM Cancellation notice status (always 有 from portal) */
  cancellationNotice: SimCancellationNoticeValue;
}

/**
 * Data to populate on Cancellation Case
 * This contains all customer-provided details
 */
export interface CancellationCaseData {
  /** Account ID */
  accountId: string;

  /** Linked Opportunity ID (if known) */
  opportunityId?: string;

  /** WHMCS Service ID for reference */
  whmcsServiceId: number;

  /** Product type (Internet, SIM, VPN) */
  productType: OpportunityProductTypeValue;

  /** Selected cancellation month (YYYY-MM) */
  cancellationMonth: string;

  /** End of cancellation month (YYYY-MM-DD) */
  cancellationDate: string;

  /** Optional alternative contact email */
  alternativeEmail?: string;

  /** Optional customer comments */
  comments?: string;
}

// ============================================================================
// Customer-Facing Service Display Model
// ============================================================================

/**
 * Customer-facing service phase
 * Only shows what's relevant to customers (no internal sales stages)
 */
export type CustomerServicePhase =
  | "order" // Order placed, awaiting activation (has SF Order, no WHMCS)
  | "active" // Service is live (has WHMCS service)
  | "cancelling" // Cancellation pending
  | "cancelled"; // Service ended

/**
 * Whether the WHMCS service is linked to an Opportunity
 */
export type ServiceLinkStatus =
  | "linked" // Opportunity has WHMCS_Service_ID__c (full features)
  | "unlinked"; // Legacy - WHMCS exists but Opp not linked

/**
 * Order tracking info (shown after order placed, before WHMCS activates)
 * Source: Salesforce Order
 */
export interface OrderTrackingInfo {
  /** Salesforce Order ID */
  orderId: string;

  /** Order number for display */
  orderNumber: string;

  /** Product being ordered */
  productName: string;

  /** Order status */
  status: string;

  /** When order was placed */
  orderDate: string;

  /** Expected activation date (estimated) */
  expectedActivation?: string;

  /** Progress steps */
  steps: Array<{
    label: string;
    status: "completed" | "current" | "upcoming";
  }>;
}

/**
 * Service details from WHMCS (shown when service is active)
 * This is the primary data source for customer service page
 */
export interface WhmcsServiceDetails {
  /** WHMCS Service ID */
  whmcsServiceId: number;

  /** Product/plan name */
  productName: string;

  /** WHMCS status (Active, Suspended, etc.) */
  status: string;

  /** Service address (for Internet) */
  serviceAddress?: string;

  /** Monthly amount */
  monthlyAmount?: number;

  /** Currency code */
  currency?: string;

  /** Next billing date */
  nextDueDate?: string;

  /** Registration date */
  registrationDate?: string;

  /** Linked Opportunity ID (from WHMCS custom field) */
  opportunityId?: string;
}

/**
 * Cancellation info for display (shown when cancelling)
 */
export interface CancellationDisplayInfo {
  /** When the service will end (end of month) */
  serviceEndDate: string;

  /** Deadline for returning equipment */
  equipmentReturnDeadline: string;

  /** Current return kit status */
  returnKitStatus: LineReturnStatusValue;

  /** Human-readable return status */
  returnKitStatusLabel: string;

  /** Whether equipment needs to be returned */
  hasEquipmentToReturn: boolean;

  /** Days remaining until service ends */
  daysUntilServiceEnd: number;

  /** Days remaining until return deadline */
  daysUntilReturnDeadline: number;
}

/**
 * Customer-facing service view for the portal
 *
 * Combines data from WHMCS (primary) and Opportunity (lifecycle/cancellation)
 * Handles both linked and legacy (unlinked) services
 */
export interface CustomerServiceView {
  // ---- Identification ----

  /** Unique ID for this view (WHMCS Service ID as string) */
  id: string;

  /** WHMCS Service ID */
  whmcsServiceId: number;

  /** Linked Opportunity ID (null for legacy services) */
  opportunityId?: string;

  /** Product type (Internet, SIM, VPN) */
  productType: OpportunityProductTypeValue;

  // ---- Display State ----

  /**
   * Customer-facing phase
   * - order: Waiting for activation
   * - active: Service is live
   * - cancelling: Cancellation pending
   * - cancelled: Service ended
   */
  phase: CustomerServicePhase;

  /**
   * Whether this service has full Opportunity linking
   * - linked: Full features (can show cancellation status, etc.)
   * - unlinked: Legacy service (limited features)
   */
  linkStatus: ServiceLinkStatus;

  // ---- Service Data (from WHMCS) ----

  /** Product/plan name */
  productName: string;

  /** WHMCS status */
  status: string;

  /** Monthly amount */
  monthlyAmount?: number;

  /** Currency */
  currency?: string;

  /** Next billing date */
  nextDueDate?: string;

  // ---- Cancellation Data (from Opportunity, if linked) ----

  /**
   * Cancellation info (only when phase = 'cancelling' and linked)
   */
  cancellation?: CancellationDisplayInfo;

  // ---- Actions ----

  /** Whether cancel button should be shown */
  canCancel: boolean;

  /** Whether user can view invoices */
  canViewInvoices: boolean;

  /** Message to show if features are limited (for legacy) */
  limitedFeaturesMessage?: string;
}

/**
 * Map Opportunity stage to customer-facing phase
 */
export function getCustomerPhaseFromStage(
  stage: OpportunityStageValue | undefined,
  whmcsStatus: string
): CustomerServicePhase {
  // If no Opportunity or WHMCS is active, derive from WHMCS status
  if (!stage) {
    if (whmcsStatus === "Active") return "active";
    if (whmcsStatus === "Cancelled" || whmcsStatus === "Terminated") return "cancelled";
    return "active"; // Default for legacy
  }

  switch (stage) {
    case OPPORTUNITY_STAGE.INTRODUCTION:
    case OPPORTUNITY_STAGE.READY:
    case OPPORTUNITY_STAGE.POST_PROCESSING:
      return "order"; // Customer sees "order in progress"

    case OPPORTUNITY_STAGE.ACTIVE:
      return "active";

    case OPPORTUNITY_STAGE.CANCELLING:
      return "cancelling";

    case OPPORTUNITY_STAGE.CANCELLED:
    case OPPORTUNITY_STAGE.COMPLETED:
    case OPPORTUNITY_STAGE.VOID:
    case OPPORTUNITY_STAGE.PENDING:
      return "cancelled";

    default:
      return "active";
  }
}

function getStepStatus(index: number, currentStep: number): "completed" | "current" | "upcoming" {
  if (index < currentStep) return "completed";
  if (index === currentStep) return "current";
  return "upcoming";
}

/**
 * Get order tracking progress steps
 * Used for customers who have placed an order but WHMCS is not yet active
 */
export function getOrderTrackingSteps(
  currentStage: OpportunityStageValue
): OrderTrackingInfo["steps"] {
  const stages = [
    { stage: OPPORTUNITY_STAGE.POST_PROCESSING, label: "Order Received" },
    { stage: OPPORTUNITY_STAGE.POST_PROCESSING, label: "Processing" },
    { stage: OPPORTUNITY_STAGE.ACTIVE, label: "Activating" },
    { stage: OPPORTUNITY_STAGE.ACTIVE, label: "Active" },
  ];

  // Simplify to 4 steps for customer clarity
  let currentStep = 0;
  if (currentStage === OPPORTUNITY_STAGE.POST_PROCESSING) {
    currentStep = 1; // Processing
  } else if (currentStage === OPPORTUNITY_STAGE.ACTIVE) {
    currentStep = 3; // Active
  }

  return stages.map((s, index) => ({
    label: s.label,
    status: getStepStatus(index, currentStep),
  }));
}

/**
 * Determine if a service can be cancelled
 */
export function canServiceBeCancelled(
  whmcsStatus: string,
  opportunityStage?: OpportunityStageValue
): boolean {
  // Can't cancel if WHMCS is not active
  if (whmcsStatus !== "Active") return false;

  // If linked to Opportunity, check stage
  if (opportunityStage) {
    // Can only cancel from Active stage
    return opportunityStage === OPPORTUNITY_STAGE.ACTIVE;
  }

  // Legacy service - allow cancellation (will create Case for agent)
  return true;
}
