import {
  BERTH_ACCESS_OPTIONS,
  BERTH_BOLLARD_TYPES,
  BERTH_CLEAT_TYPES,
  BERTH_MOORING_TYPES,
  BERTH_SIDE_PONTOON_OPTIONS,
  DOCUMENT_TYPES,
  EXPENSE_CATEGORIES,
} from '@/lib/constants';

/**
 * Per-port vocabularies - pick lists that the rep team needs to be
 * able to tweak without a code change. Each vocabulary is a JSON
 * array of strings stored in `system_settings` keyed by
 * `(port_id, key)`. The defaults below are the values the CRM
 * shipped with; the admin Vocabularies page lets a port admin
 * override any of them.
 *
 * Consumers should call {@link getVocabulary} to fetch the
 * effective list (port override first, falling back to default).
 * Never hardcode a vocabulary in component code - always read
 * through this module so the admin page is the single source of
 * truth.
 */
export type VocabularyKey =
  | 'interest_temperature_levels'
  | 'berth_status_change_reasons'
  | 'berth_tenure_types'
  | 'expense_categories'
  | 'document_types'
  | 'interest_outcome_statuses'
  | 'berth_side_pontoon_options'
  | 'berth_mooring_types'
  | 'berth_cleat_types'
  | 'berth_bollard_types'
  | 'berth_access_options';

export interface VocabularyDef {
  key: VocabularyKey;
  label: string;
  description: string;
  /** Domain grouping for the admin page card layout. */
  domain: 'Interests' | 'Berths' | 'Expenses' | 'Documents';
  /** Default values shipped with the CRM. */
  defaults: readonly string[];
}

export const VOCABULARIES: VocabularyDef[] = [
  // ─── Interests ─────────────────────────────────────────────────────────────
  {
    key: 'interest_temperature_levels',
    label: 'Interest temperatures',
    description:
      'Heat-level pills shown on each interest card. The first entry is treated as the highest urgency in lists and reports.',
    domain: 'Interests',
    defaults: ['HOT', 'WARM', 'COLD'],
  },
  {
    key: 'interest_outcome_statuses',
    label: 'Interest outcomes',
    description:
      'Terminal outcome labels recorded when an interest is closed. Used in reports and the lost-deal heat scorer.',
    domain: 'Interests',
    defaults: ['won', 'lost_other_marina', 'lost_unqualified', 'lost_no_response', 'cancelled'],
  },

  // ─── Berths ────────────────────────────────────────────────────────────────
  {
    key: 'berth_status_change_reasons',
    label: 'Berth status-change reasons',
    description:
      'Quick-pick chips shown in the status-change dialog when a berth is moved to Sold / Under Offer.',
    domain: 'Berths',
    defaults: [
      'Sold to existing prospect',
      'Sold to walk-in',
      'Reserved pending deposit',
      'Returned to inventory',
      'Owner withdrew',
    ],
  },
  {
    key: 'berth_tenure_types',
    label: 'Berth tenure types',
    description: 'Ownership / lease structure displayed on berth detail.',
    domain: 'Berths',
    defaults: ['permanent', 'fixed_term'],
  },
  {
    key: 'berth_side_pontoon_options',
    label: 'Side-pontoon configurations',
    description: 'Options for the Side Pontoon dropdown on the berth form.',
    domain: 'Berths',
    defaults: [...BERTH_SIDE_PONTOON_OPTIONS],
  },
  {
    key: 'berth_mooring_types',
    label: 'Mooring types',
    description: 'Mooring-type options on the berth form.',
    domain: 'Berths',
    defaults: [...BERTH_MOORING_TYPES],
  },
  {
    key: 'berth_cleat_types',
    label: 'Cleat types',
    description: 'Hardware tiers used in the berth spec form.',
    domain: 'Berths',
    defaults: [...BERTH_CLEAT_TYPES],
  },
  {
    key: 'berth_bollard_types',
    label: 'Bollard types',
    description: 'Bollard hardware options on the berth spec form.',
    domain: 'Berths',
    defaults: [...BERTH_BOLLARD_TYPES],
  },
  {
    key: 'berth_access_options',
    label: 'Access modes',
    description: 'Vehicle access options shown on the berth spec form.',
    domain: 'Berths',
    defaults: [...BERTH_ACCESS_OPTIONS],
  },

  // ─── Expenses ──────────────────────────────────────────────────────────────
  {
    key: 'expense_categories',
    label: 'Expense categories',
    description: 'Category dropdown on the expense form. Drives the expense PDF group-by-category.',
    domain: 'Expenses',
    defaults: [...EXPENSE_CATEGORIES],
  },

  // ─── Documents ─────────────────────────────────────────────────────────────
  {
    key: 'document_types',
    label: 'Document types',
    description: 'Type tag applied to uploaded documents and template metadata.',
    domain: 'Documents',
    defaults: [...DOCUMENT_TYPES],
  },
];

const VOCAB_BY_KEY = new Map<VocabularyKey, VocabularyDef>(VOCABULARIES.map((v) => [v.key, v]));

export function getVocabularyDef(key: VocabularyKey): VocabularyDef {
  const def = VOCAB_BY_KEY.get(key);
  if (!def) throw new Error(`Unknown vocabulary key: ${key}`);
  return def;
}

/**
 * Resolve the effective vocabulary for a port - merges the port's
 * override (when present) with the shipped defaults. Falls back to
 * defaults when the system_settings value is missing or malformed.
 */
export function resolveVocabulary(key: VocabularyKey, override: unknown): readonly string[] {
  const def = getVocabularyDef(key);
  if (!Array.isArray(override)) return def.defaults;
  const cleaned = override.filter((v): v is string => typeof v === 'string' && v.trim().length > 0);
  return cleaned.length > 0 ? cleaned : def.defaults;
}
