/**
 * Support Domain - Salesforce Provider Raw Types
 *
 * Raw Salesforce API response types for Case sobject.
 * These types represent the exact structure returned by Salesforce SOQL queries.
 *
 * Available Case fields in this org (standard fields used):
 * - Id, CaseNumber, Subject, Status, Priority, Type, Description, Origin, Reason
 * - AccountId, ContactId, OwnerId, ParentId
 * - CreatedDate, ClosedDate (LastModifiedDate via LastModifiedById)
 * - IsEscalated, IsClosedOnCreate, IsStopped
 * - ContactEmail, ContactPhone, ContactMobile, ContactFax
 */

import { z } from "zod";

// ============================================================================
// Salesforce Case Record (Raw API Response)
// ============================================================================

/**
 * Raw Salesforce Case record schema
 *
 * Represents the structure returned by SOQL queries on the Case object.
 * All fields are optional/nullable to handle partial queries and Salesforce nulls.
 */
export const salesforceCaseRecordSchema = z.object({
  // ─────────────────────────────────────────────────────────────────────────
  // Standard Salesforce ID fields
  // ─────────────────────────────────────────────────────────────────────────
  Id: z.string(),
  CaseNumber: z.string(),

  // ─────────────────────────────────────────────────────────────────────────
  // Core case fields (Picklists & Text)
  // ─────────────────────────────────────────────────────────────────────────
  Subject: z.string().nullable().optional(), // Text(255)
  Status: z.string().nullable().optional(), // Picklist
  Priority: z.string().nullable().optional(), // Picklist
  Type: z.string().nullable().optional(), // Picklist - Maps to Category in portal
  Description: z.string().nullable().optional(), // Long Text Area(32000)
  Origin: z.string().nullable().optional(), // Picklist (Case Origin)
  Reason: z.string().nullable().optional(), // Picklist (Case Reason)

  // ─────────────────────────────────────────────────────────────────────────
  // Relationship IDs (Lookups)
  // ─────────────────────────────────────────────────────────────────────────
  AccountId: z.string().nullable().optional(), // Lookup(Account)
  ContactId: z.string().nullable().optional(), // Lookup(Contact)
  OwnerId: z.string().nullable().optional(), // Lookup(User,Group)
  ParentId: z.string().nullable().optional(), // Lookup(Case)
  AssetId: z.string().nullable().optional(), // Lookup(Asset)
  ProductId: z.string().nullable().optional(), // Lookup(Product)
  EntitlementId: z.string().nullable().optional(), // Lookup(Entitlement)
  ServiceContractId: z.string().nullable().optional(), // Lookup(Service Contract)
  SourceId: z.string().nullable().optional(), // Lookup(Chat Transcript,Email Message,etc)

  // ─────────────────────────────────────────────────────────────────────────
  // Nested objects (from relationship queries)
  // ─────────────────────────────────────────────────────────────────────────
  Account: z
    .object({
      Id: z.string().optional(),
      Name: z.string().nullable().optional(),
    })
    .nullable()
    .optional(),

  Contact: z
    .object({
      Id: z.string().optional(),
      Name: z.string().nullable().optional(),
      Email: z.string().nullable().optional(),
    })
    .nullable()
    .optional(),

  Owner: z
    .object({
      Id: z.string().optional(),
      Name: z.string().nullable().optional(),
    })
    .nullable()
    .optional(),

  // ─────────────────────────────────────────────────────────────────────────
  // Contact info fields (derived from Contact lookup)
  // ─────────────────────────────────────────────────────────────────────────
  ContactEmail: z.string().nullable().optional(), // Email
  ContactPhone: z.string().nullable().optional(), // Phone
  ContactMobile: z.string().nullable().optional(), // Phone
  ContactFax: z.string().nullable().optional(), // Phone

  // ─────────────────────────────────────────────────────────────────────────
  // Timestamps
  // ─────────────────────────────────────────────────────────────────────────
  CreatedDate: z.string().nullable().optional(), // Date/Time Opened
  LastModifiedDate: z.string().nullable().optional(), // Derived from LastModifiedById
  ClosedDate: z.string().nullable().optional(), // Date/Time Closed
  SlaStartDate: z.string().nullable().optional(), // SLA Policy Start Time
  SlaExitDate: z.string().nullable().optional(), // SLA Policy End Time

  // ─────────────────────────────────────────────────────────────────────────
  // Boolean flags
  // ─────────────────────────────────────────────────────────────────────────
  IsEscalated: z.boolean().nullable().optional(), // Escalated checkbox
  IsClosedOnCreate: z.boolean().nullable().optional(), // Closed When Created
  IsStopped: z.boolean().nullable().optional(), // Stopped checkbox

  // ─────────────────────────────────────────────────────────────────────────
  // Other standard fields
  // ─────────────────────────────────────────────────────────────────────────
  Comments: z.string().nullable().optional(), // Internal Comments - Text Area(4000)
  MilestoneStatus: z.string().nullable().optional(), // Text(30)
  Language: z.string().nullable().optional(), // Picklist

  // Web-to-Case fields
  SuppliedName: z.string().nullable().optional(), // Web Name - Text(80)
  SuppliedEmail: z.string().nullable().optional(), // Web Email - Email
  SuppliedPhone: z.string().nullable().optional(), // Web Phone - Text(40)
  SuppliedCompany: z.string().nullable().optional(), // Web Company - Text(80)

  // ─────────────────────────────────────────────────────────────────────────
  // Custom fields (org-specific)
  // ─────────────────────────────────────────────────────────────────────────
  // AI-related fields
  Case_Concern_AI__c: z.string().nullable().optional(), // Text Area(255)
  Case_Email_Summary__c: z.string().nullable().optional(), // Long Text Area(32768)
  Summary_AI__c: z.string().nullable().optional(), // Long Text Area(32768)
  Resolution_AI__c: z.string().nullable().optional(), // Long Text Area(32768)

  // Other custom fields (add as needed)
  Department__c: z.string().nullable().optional(), // Picklist
  Comment__c: z.string().nullable().optional(), // Long Text Area(32768)
  Notes__c: z.string().nullable().optional(), // Long Text Area(32768)
});

export type SalesforceCaseRecord = z.infer<typeof salesforceCaseRecordSchema>;

// ============================================================================
// Salesforce EmailMessage Record (for case email conversations)
// ============================================================================

/**
 * Raw Salesforce EmailMessage record schema
 *
 * Represents email messages attached to a Case.
 * Used for displaying email conversation history.
 */
export const salesforceEmailMessageSchema = z.object({
  Id: z.string(),
  ParentId: z.string(), // Case ID

  // Email content
  Subject: z.string().nullable().optional(),
  TextBody: z.string().nullable().optional(),
  HtmlBody: z.string().nullable().optional(),

  // Sender/recipient
  FromAddress: z.string().nullable().optional(),
  FromName: z.string().nullable().optional(),
  ToAddress: z.string().nullable().optional(),
  ToName: z.string().nullable().optional(),
  CcAddress: z.string().nullable().optional(),
  BccAddress: z.string().nullable().optional(),

  // Direction and status
  Incoming: z.boolean().nullable().optional(), // true = customer sent, false = agent sent
  Status: z.string().nullable().optional(), // 0=New, 1=Read, 2=Replied, 3=Sent, 4=Forwarded, 5=Draft

  // Threading
  ThreadIdentifier: z.string().nullable().optional(),
  MessageIdentifier: z.string().nullable().optional(),

  // Timestamps
  MessageDate: z.string().nullable().optional(),
  CreatedDate: z.string().nullable().optional(),

  // Flags
  HasAttachment: z.boolean().nullable().optional(),
  IsExternallyVisible: z.boolean().nullable().optional(),
});

export type SalesforceEmailMessage = z.infer<typeof salesforceEmailMessageSchema>;

// ============================================================================
// Salesforce CaseComment Record (for case comments)
// ============================================================================

/**
 * Raw Salesforce CaseComment record schema
 *
 * Represents comments added to a Case.
 * Used for displaying comment conversation history.
 */
export const salesforceCaseCommentSchema = z.object({
  Id: z.string(),
  ParentId: z.string(), // Case ID

  // Comment content
  CommentBody: z.string().nullable().optional(),

  // Visibility
  IsPublished: z.boolean().nullable().optional(), // true = visible to customer

  // Author
  CreatedById: z.string().nullable().optional(),
  CreatedBy: z
    .object({
      Id: z.string().optional(),
      Name: z.string().nullable().optional(),
      Email: z.string().nullable().optional(),
    })
    .nullable()
    .optional(),

  // Timestamps
  CreatedDate: z.string().nullable().optional(),
  LastModifiedDate: z.string().nullable().optional(),
});

export type SalesforceCaseComment = z.infer<typeof salesforceCaseCommentSchema>;

// ============================================================================
// Salesforce Case Create Payload
// ============================================================================

/**
 * Payload schema for creating a new Case in Salesforce
 *
 * Uses Salesforce API names (Japanese) for Status and Priority defaults.
 */
export const salesforceCaseCreatePayloadSchema = z.object({
  Subject: z.string(),
  Description: z.string(),
  Status: z.string().default("新規"), // Default: New (Japanese API name)
  Priority: z.string().default("中"), // Default: Medium (Japanese API name)
  Origin: z.string(),
  Type: z.string().optional(),
  AccountId: z.string(),
  ContactId: z.string().optional(),
});

export type SalesforceCaseCreatePayload = z.infer<typeof salesforceCaseCreatePayloadSchema>;

// ============================================================================
// Salesforce Case Field Constants (Org-Specific Picklist Values)
// ============================================================================

/**
 * Salesforce Case Origin picklist values
 * API Names from Salesforce Setup > Object Manager > Case > Fields > Case Origin
 */
export const SALESFORCE_CASE_ORIGIN = {
  // Customer-visible support cases created from the portal support UI
  PORTAL_SUPPORT: "Portal Support",

  // Internal portal workflow cases (eligibility, verification, cancellations)
  PORTAL_NOTIFICATION: "Portal Notification",

  // Phone/Email origins
  PHONE: "電話", // Japanese: Phone
  MAIL: "メール", // Japanese: Mail
  EMAIL: "Email",
  WEB: "Web",

  // ChatBot origins
  AS_CHATBOT: "AS ChatBot",
  GENKI_CHATBOT: "Genki ChatBot",

  // Messaging origins
  WHATSAPP_CHAT: "WhatsApp Chat",
  MESSENGER_CHAT: "Messenger Chat",

  // Mail-specific origins
  GENKI_MAIL: "Genki Mail",
  BILLING_MAIL: "Billing Mail",
  TECH_MAIL: "Tech Mail",
  HELPDESK_MAIL: "Helpdesk Mail",
  MESERATI_MAIL: "Meserati Mail",

  // Other
  WEB_URGENT_INQUIRY: "Web Urgent Inquiry",
} as const;

export type SalesforceCaseOrigin =
  (typeof SALESFORCE_CASE_ORIGIN)[keyof typeof SALESFORCE_CASE_ORIGIN];

/**
 * Salesforce Case Status picklist values
 * API Names from Salesforce Setup > Object Manager > Case > Fields > Status
 *
 * Closed statuses: VPN Pending, Pending, 完了済み (Replied)
 * Open statuses: 新規 (New), 対応中 (Reply in Progress), Awaiting Approval
 */
export const SALESFORCE_CASE_STATUS = {
  // Open statuses
  NEW: "新規", // Japanese: New Email (Default)
  IN_PROGRESS: "対応中", // Japanese: Reply in Progress
  AWAITING_APPROVAL: "Awaiting Approval",

  // Closed statuses
  VPN_PENDING: "VPN Pending", // Closed
  PENDING: "Pending", // Closed
  REPLIED: "完了済み", // Japanese: Replied/Completed (Closed)
  CLOSED: "Closed",
} as const;

export type SalesforceCaseStatus =
  (typeof SALESFORCE_CASE_STATUS)[keyof typeof SALESFORCE_CASE_STATUS];

/** Status values that indicate a case is closed */
export const SALESFORCE_CLOSED_STATUSES: SalesforceCaseStatus[] = [
  SALESFORCE_CASE_STATUS.VPN_PENDING,
  SALESFORCE_CASE_STATUS.PENDING,
  SALESFORCE_CASE_STATUS.REPLIED,
  SALESFORCE_CASE_STATUS.CLOSED,
];

/** Status values that indicate a case is open */
export const SALESFORCE_OPEN_STATUSES: SalesforceCaseStatus[] = [
  SALESFORCE_CASE_STATUS.NEW,
  SALESFORCE_CASE_STATUS.IN_PROGRESS,
  SALESFORCE_CASE_STATUS.AWAITING_APPROVAL,
];

/**
 * Salesforce Case Priority picklist values
 * API Names from Salesforce Setup > Object Manager > Case > Fields > Priority
 */
export const SALESFORCE_CASE_PRIORITY = {
  HIGH: "高", // Japanese: High
  MEDIUM: "中", // Japanese: Medium (Default)
  LOW: "低", // Japanese: Low
  MEDIUM_EN: "Medium", // English Medium (also exists)
} as const;

export type SalesforceCasePriority =
  (typeof SALESFORCE_CASE_PRIORITY)[keyof typeof SALESFORCE_CASE_PRIORITY];

// ============================================================================
// Portal Display Labels (for UI rendering)
// ============================================================================

const STATUS_LABEL_IN_PROGRESS = "In Progress";

/**
 * Map Salesforce status API names to customer-friendly portal display labels.
 *
 * Mapping logic:
 * - Internal workflow statuses (Awaiting Approval, VPN Pending, Pending) → "In Progress"
 * - 完了済み (Replied) → "Awaiting Customer" (support replied, waiting for customer)
 * - Closed → "Closed"
 */
export const STATUS_DISPLAY_LABELS: Record<string, string> = {
  [SALESFORCE_CASE_STATUS.NEW]: "New",
  [SALESFORCE_CASE_STATUS.IN_PROGRESS]: STATUS_LABEL_IN_PROGRESS,
  // Internal workflow statuses - show as "In Progress" to customer
  [SALESFORCE_CASE_STATUS.AWAITING_APPROVAL]: STATUS_LABEL_IN_PROGRESS,
  [SALESFORCE_CASE_STATUS.VPN_PENDING]: STATUS_LABEL_IN_PROGRESS,
  [SALESFORCE_CASE_STATUS.PENDING]: STATUS_LABEL_IN_PROGRESS,
  // Replied = support has responded, waiting for customer
  [SALESFORCE_CASE_STATUS.REPLIED]: "Awaiting Customer",
  [SALESFORCE_CASE_STATUS.CLOSED]: "Closed",
};

/**
 * Map Salesforce priority API names to portal display labels
 */
export const PRIORITY_DISPLAY_LABELS: Record<string, string> = {
  [SALESFORCE_CASE_PRIORITY.HIGH]: "High",
  [SALESFORCE_CASE_PRIORITY.MEDIUM]: "Medium",
  [SALESFORCE_CASE_PRIORITY.LOW]: "Low",
  [SALESFORCE_CASE_PRIORITY.MEDIUM_EN]: "Medium",
};

/**
 * Get display label for a status value
 */
export function getStatusDisplayLabel(status: string): string {
  return STATUS_DISPLAY_LABELS[status] ?? status;
}

/**
 * Get display label for a priority value
 */
export function getPriorityDisplayLabel(priority: string): string {
  return PRIORITY_DISPLAY_LABELS[priority] ?? priority;
}

/**
 * Check if a status indicates the case is closed
 */
export function isClosedStatus(status: string): boolean {
  return SALESFORCE_CLOSED_STATUSES.includes(status as SalesforceCaseStatus);
}

// ============================================================================
// Reverse Mapping (Portal Display → Salesforce API)
// ============================================================================

/**
 * Map portal display priority to Salesforce API priority value
 * Used when creating cases - converts "High" → "高", etc.
 */
const PRIORITY_TO_SALESFORCE: Record<string, string> = {
  High: SALESFORCE_CASE_PRIORITY.HIGH, // "高"
  Medium: SALESFORCE_CASE_PRIORITY.MEDIUM, // "中"
  Low: SALESFORCE_CASE_PRIORITY.LOW, // "低"
};

/**
 * Convert portal priority display value to Salesforce API value
 */
export function toSalesforcePriority(displayPriority: string): string {
  return PRIORITY_TO_SALESFORCE[displayPriority] ?? SALESFORCE_CASE_PRIORITY.MEDIUM;
}
