import {
  article1ObjectiveFromClause,
  buildClausePack,
} from './contract-clause-packs';
import type {
  ContractDirection,
  ContractFreight,
  ContractServiceScope,
  ContractTemplateMeta,
} from './contract-template.types';

export type { ContractTemplateMeta } from './contract-template.types';

const DIRECTION_LABELS: Record<ContractDirection, string> = {
  IMP: 'Import',
  EXP: 'Export',
  DOM: 'Domestic',
};

const FREIGHT_LABELS: Record<ContractFreight, string> = {
  CON: 'Container',
  BULK: 'Bulk',
};

const DIRECTIONS: ContractDirection[] = ['IMP', 'EXP', 'DOM'];
const FREIGHTS: ContractFreight[] = ['CON', 'BULK'];
const CURRENCIES = ['ETB', 'USD'] as const;
const SERVICES: ContractServiceScope[] = ['TRANSPORT_ONLY', 'FORWARDING'];

const KEY_PATTERN =
  /^(IMP|EXP|DOM)_(CON|BULK)_(ETB|USD)_(TRANSPORT_ONLY|FORWARDING)$/;

function buildMeta(
  dir: ContractDirection,
  freight: ContractFreight,
  currency: string,
  service: ContractServiceScope,
): ContractTemplateMeta {
  const key = `${dir}_${freight}_${currency}_${service}`;
  const dirLabel = DIRECTION_LABELS[dir];
  const freightLabel = FREIGHT_LABELS[freight];
  const serviceLabel =
    service === 'FORWARDING' ? 'Rail and Forwarding' : 'Transport Only';

  const corridor =
    dir === 'IMP'
      ? 'from SGTD railway freight station at Djibouti to Ethiopian dry ports and return of empty containers as applicable'
      : dir === 'EXP'
        ? 'from Ethiopian dry ports to SGTD and related export corridors'
        : 'between designated Ethiopian rail terminals';

  const clauses = buildClausePack(dir, freight, service);

  return {
    key,
    direction: dir,
    freight,
    currency,
    serviceScope: service,
    title: `${dirLabel} ${freightLabel} Transport Service by Railway (${serviceLabel})`,
    directionLabel: dirLabel,
    freightLabel,
    whereas: `The Client has requested transportation of ${freightLabel.toLowerCase()} cargo ${corridor} using the Addis Ababa–Djibouti Railway line. The Service Provider has agreed to provide services per this contract.`,
    article1Objective: article1ObjectiveFromClause(clauses.article1),
    article1: clauses.article1,
    clientObligations: clauses.clientObligations,
    providerObligations: clauses.providerObligations,
    contractDocuments: clauses.contractDocuments,
  };
}

/** Full template matrix (24 keys). */
export const CONTRACT_TEMPLATE_REGISTRY: Record<string, ContractTemplateMeta> =
  {};

for (const dir of DIRECTIONS) {
  for (const freight of FREIGHTS) {
    for (const currency of CURRENCIES) {
      for (const service of SERVICES) {
        const meta = buildMeta(dir, freight, currency, service);
        CONTRACT_TEMPLATE_REGISTRY[meta.key] = meta;
      }
    }
  }
}

export const CONTRACT_TEMPLATE_KEYS = Object.keys(CONTRACT_TEMPLATE_REGISTRY);

export function listTemplateKeys(): string[] {
  return CONTRACT_TEMPLATE_KEYS;
}

export function getTemplateMeta(key: string): ContractTemplateMeta {
  const found = CONTRACT_TEMPLATE_REGISTRY[key];
  if (found) return found;

  const fallbackClauses = buildClausePack('IMP', 'CON', 'TRANSPORT_ONLY');
  return {
    key,
    direction: 'IMP',
    freight: 'CON',
    currency: 'USD',
    serviceScope: 'TRANSPORT_ONLY',
    title: 'Freight Contract Agreement',
    directionLabel: 'Freight',
    freightLabel: 'Cargo',
    whereas:
      'The parties agree to railway freight services as described in the schedule below.',
    article1Objective: article1ObjectiveFromClause(fallbackClauses.article1),
    article1: fallbackClauses.article1,
    clientObligations: fallbackClauses.clientObligations,
    providerObligations: fallbackClauses.providerObligations,
    contractDocuments: fallbackClauses.contractDocuments,
  };
}

export function isValidTemplateKey(key: string): boolean {
  return KEY_PATTERN.test(key);
}
