// Shared TypeScript types used by api and whatsapp services

export type UserRole = 'admin' | 'user' | 'company_user';
export type ChannelStatus = 'connecting' | 'connected' | 'disconnected';
export type TicketStatus = 'open' | 'closed';
export type TicketPriority = 'low' | 'medium' | 'high';
export type MessageDirection = 'inbound' | 'outbound';
export type MessageSource = 'whatsapp' | 'portal' | 'email';
export type AuditActorType = 'user' | 'system';

export interface User {
  id: string;
  email: string;
  /** Optional human name (portal users); shown in tickets next to email */
  display_name: string | null;
  /** Optional phone (portal / signup); staff may omit */
  phone: string | null;
  role: UserRole;
  company_id: string | null;
  is_active: boolean;
  created_at: string;
  last_login_at: string | null;
}

export interface Company {
  id: string;
  name: string;
  normalized_name: string;
  /** Customer-facing code used when joining an existing company (e.g. C1A2B3C4D5) */
  account_code: string;
  created_at: string;
}

/** Resolved for Web Portal tickets (staff + portal views) */
export interface PortalParticipant {
  company_name: string;
  user_email: string;
  user_display_name: string | null;
}

export interface Contact {
  id: string;
  phone_number: string;
  display_name: string | null;
  company_id: string | null;
  created_at: string;
  /** Populated for `portal:*` rows on GET /contacts (list) */
  portal_company_name?: string | null;
  portal_user_email?: string | null;
  portal_user_display_name?: string | null;
}

/** Editable WhatsApp onboarding prompts per channel */
export interface ChannelOnboardingTemplates {
  whoAreYou: string;
  company: string;
  query: string;
  queryStatus: string;
}

/** Per-channel LLM config (API key lives in env, not stored here) */
export interface ChannelAiSettings {
  enabled: boolean;
  model: string;
  systemPrompt: string;
  knowledgeBaseText: string;
}

/** Optional WhatsApp text when an agent closes a ticket (to the contact on that ticket). */
export interface ChannelTicketClosingSettings {
  enabled: boolean;
  message: string;
}

/** Staff SMS alert (optional Twilio on API host). */
export interface ChannelSmsAlertSettings {
  enabled: boolean;
  /** E.164, e.g. +27821234567 */
  phone_e164: string;
}

/** Staff email alert when a new inbound message arrives on this channel. */
export interface ChannelStaffEmailAlertSettings {
  enabled: boolean;
  address: string;
}

/**
 * Escalation: optionally notify email first, then SMS; optionally flag the ticket for review.
 */
export interface ChannelEscalationAlertSettings {
  enabled: boolean;
  /** true = email alert first, then SMS; false = send enabled alerts in parallel */
  emailThenSms: boolean;
  /** Set ticket.needs_escalation when inbound is processed (team ticks off in UI) */
  flagTicketForEscalation: boolean;
}

export interface ChannelAlertsSettings {
  sms: ChannelSmsAlertSettings;
  email: ChannelStaffEmailAlertSettings;
  escalation: ChannelEscalationAlertSettings;
}

export interface ChannelSettings {
  onboarding: { enabled: boolean; templates: ChannelOnboardingTemplates };
  ai: ChannelAiSettings;
  ticketClosing: ChannelTicketClosingSettings;
  alerts: ChannelAlertsSettings;
}

export const defaultChannelSettings: ChannelSettings = {
  onboarding: {
    enabled: false,
    templates: {
      whoAreYou: 'Hi! We do not have your details yet. Who are you, and how can we help?',
      company: 'Thanks! Which company are you with?',
      query: 'Please describe your query or issue in a few words.',
      queryStatus: 'What is the current status of this query from your side (e.g. new, waiting on us, urgent)?',
    },
  },
  ai: {
    enabled: false,
    model: 'gpt-4o-mini',
    systemPrompt: 'You are a helpful support assistant for WhatsApp. Be concise and professional.',
    knowledgeBaseText: '',
  },
  ticketClosing: {
    enabled: false,
    message:
      'Your support ticket has been closed. Thank you for contacting us — reply anytime if you need further help.',
  },
  alerts: {
    sms: { enabled: false, phone_e164: '' },
    email: { enabled: false, address: '' },
    escalation: { enabled: false, emailThenSms: true, flagTicketForEscalation: false },
  },
};

/** Merge DB JSON with defaults for safe reads in API and UI */
export function mergeChannelSettings(raw: unknown): ChannelSettings {
  const d = defaultChannelSettings;
  if (!raw || typeof raw !== 'object') return structuredClone(d);
  const r = raw as Partial<ChannelSettings>;
  return {
    onboarding: {
      enabled: r.onboarding?.enabled ?? d.onboarding.enabled,
      templates: {
        whoAreYou: r.onboarding?.templates?.whoAreYou ?? d.onboarding.templates.whoAreYou,
        company: r.onboarding?.templates?.company ?? d.onboarding.templates.company,
        query: r.onboarding?.templates?.query ?? d.onboarding.templates.query,
        queryStatus: r.onboarding?.templates?.queryStatus ?? d.onboarding.templates.queryStatus,
      },
    },
    ai: {
      enabled: r.ai?.enabled ?? d.ai.enabled,
      model: r.ai?.model ?? d.ai.model,
      systemPrompt: r.ai?.systemPrompt ?? d.ai.systemPrompt,
      knowledgeBaseText: r.ai?.knowledgeBaseText ?? d.ai.knowledgeBaseText,
    },
    ticketClosing: {
      enabled: r.ticketClosing?.enabled ?? d.ticketClosing.enabled,
      message: r.ticketClosing?.message ?? d.ticketClosing.message,
    },
    alerts: {
      sms: {
        enabled: r.alerts?.sms?.enabled ?? d.alerts.sms.enabled,
        phone_e164: r.alerts?.sms?.phone_e164 ?? d.alerts.sms.phone_e164,
      },
      email: {
        enabled: r.alerts?.email?.enabled ?? d.alerts.email.enabled,
        address: r.alerts?.email?.address ?? d.alerts.email.address,
      },
      escalation: {
        enabled: r.alerts?.escalation?.enabled ?? d.alerts.escalation.enabled,
        emailThenSms: r.alerts?.escalation?.emailThenSms ?? d.alerts.escalation.emailThenSms,
        flagTicketForEscalation:
          r.alerts?.escalation?.flagTicketForEscalation ?? d.alerts.escalation.flagTicketForEscalation,
      },
    },
  };
}

export type ChannelKind = 'whatsapp' | 'portal' | 'email';

export interface Channel {
  id: string;
  name: string;
  phone_number: string;
  kind: ChannelKind;
  status: ChannelStatus;
  created_at: string;
  last_connected_at: string | null;
  /** Email channels only: secret for inbound webhook URL (omit in list API). */
  inbound_token?: string | null;
  /** Merged with defaults when read from API */
  settings?: ChannelSettings;
  /**
   * Web chat only (`portal:system`): onboarding / AI / closing shown in API are copied from this
   * WhatsApp channel (oldest by created_at). Null if no WhatsApp channel exists yet.
   */
  web_chat_settings_source?: { id: string; name: string } | null;
}

export type TicketIntakeStep = 'idle' | 'who' | 'company' | 'query' | 'status' | 'done';

export interface TicketIntakeAnswers {
  whoAreYou?: string;
  company?: string;
  query?: string;
  queryStatus?: string;
}

export interface TicketIntake {
  step: TicketIntakeStep;
  answers: TicketIntakeAnswers;
}

export const defaultTicketIntake: TicketIntake = { step: 'done', answers: {} };

export function mergeTicketIntake(raw: unknown): TicketIntake {
  if (!raw || typeof raw !== 'object') return { ...defaultTicketIntake };
  const r = raw as Partial<TicketIntake>;
  return {
    step: r.step ?? defaultTicketIntake.step,
    answers: { ...defaultTicketIntake.answers, ...r.answers },
  };
}

export interface Ticket {
  id: string;
  contact_id: string;
  channel_id: string;
  assigned_to: string | null;
  status: TicketStatus;
  priority: TicketPriority;
  due_date: string | null;
  created_at: string;
  updated_at: string;
  closed_at: string | null;
  /** Set by alert rules or manually — team marks when escalation is handled */
  needs_escalation: boolean;
  intake?: TicketIntake;
  // Joined fields (optional)
  contact?: Contact;
  channel?: Channel;
  assigned_user?: Pick<User, 'id' | 'email'>;
  portal_participant?: PortalParticipant;
}

export interface Message {
  id: string;
  ticket_id: string;
  direction: MessageDirection;
  content: string;
  wa_message_id: string | null;
  sequence: number;
  source: MessageSource;
  created_at: string;
}

export interface AuditLog {
  id: string;
  actor_id: string | null;
  actor_type: AuditActorType;
  action: string;
  entity_type: string;
  entity_id: string;
  metadata: Record<string, unknown> | null;
  created_at: string;
}

// WebSocket event payloads
export interface WsQrUpdate {
  channelId: string;
  qrDataUrl: string;
}

export interface WsChannelConnected {
  channelId: string;
}

export interface WsChannelDisconnected {
  channelId: string;
  reason: string;
}

export interface WsMessageNew {
  ticketId: string;
  message: Message;
}

export interface WsTicketCreated {
  ticket: Ticket;
}

export interface WsTicketUpdated {
  ticket: Ticket;
}

export interface WsMessageSent {
  messageId: string;
  status: 'ok' | 'error';
  error?: string;
}

/** DB seed / synthetic channel — never connected to Baileys */
export const PORTAL_CHANNEL_PHONE = 'portal:system';

export function isPortalChannelPhone(phone: string | undefined | null): boolean {
  return Boolean(phone?.startsWith('portal:'));
}

/** Company web chat channel (inherits settings from the primary WhatsApp channel). */
export function isWebChatSystemChannel(phone: string | undefined | null): boolean {
  return phone === PORTAL_CHANNEL_PHONE;
}

/** Contact key for email tickets: `email:` + lowercased address */
export function emailContactKey(address: string): string {
  return `email:${address.trim().toLowerCase()}`;
}

export function isEmailContactKey(phone: string | undefined | null): boolean {
  return Boolean(phone?.startsWith('email:') && phone.includes('@'));
}
