import { Booking } from './entities/booking.entity';

/**
 * Resolves which seeded clearance FileUploadSetting applies to a booking, from
 * its trade direction, freight type and whether its service includes customs.
 * Mirrors the codes seeded in file-upload-settings.seeder.ts.
 */

type Op = 'import' | 'export';
type Freight = 'container' | 'bulk';

/**
 * The single (admin-configured) document set intercity shipments upload.
 * DOMESTIC has no customs, so one shared set serves contracts and bookings:
 * ONE_TIME collects it at contract level, GENERAL per booking — Operations
 * reviews either way.
 */
export const INTERCITY_DOCUMENTS_SETTING_CODE = 'intercity_documents';

/** Trade direction → clearance operation. DOMESTIC has no customs clearance. */
function operationFor(tradeDirection: string): Op | null {
  if (tradeDirection === 'IMPORT') return 'import';
  if (tradeDirection === 'EXPORT') return 'export';
  return null; // DOMESTIC / intercity — no customs operation
}

function freightFor(freightType: string): Freight {
  return freightType === 'BULK' ? 'bulk' : 'container';
}

/** The customer-input clearance setting code, or null when no gate applies. */
export function clearanceSettingCode(
  tradeDirection: string,
  freightType: string,
  includesCustoms: boolean,
): string | null {
  // Intercity: no customs, but the admin-configured intercity document set is
  // still collected and ops-reviewed before the shipment may board a train.
  if (tradeDirection === 'DOMESTIC') return INTERCITY_DOCUMENTS_SETTING_CODE;
  const op = operationFor(tradeDirection);
  if (!op) return null;
  const freight = freightFor(freightType);
  // Non-customs (Path A) bookings self-clear: the customer proves his own
  // clearance with the SAME smaller document set a ONE_TIME self-clear
  // contract uses (customs declaration, release permit, …) — not the
  // GL-oriented booking sets.
  if (!includesCustoms) {
    return `contract_clearance_selfclear_${op}_${freight}`;
  }
  return `clearance_${op}_${freight}_with_customs`;
}

/** The GL-output (customs output) setting code, keyed on op + freight. */
export function clearanceOutputSettingCode(
  tradeDirection: string,
  freightType: string,
  includesCustoms: boolean,
): string | null {
  if (!includesCustoms) return null;
  const op = operationFor(tradeDirection);
  if (!op) return null;
  const freight = freightFor(freightType);
  return `clearance_output_${op}_${freight}`;
}

/** Convenience: resolve both codes for a loaded booking (with its serviceType). */
export function clearanceCodesForBooking(booking: Booking): {
  inputCode: string | null;
  outputCode: string | null;
  includesCustoms: boolean;
} {
  // Customs applies when EITHER the service type bundles it OR the booking was
  // created with customsClearingEnabled (copied from the contract). Contract
  // bookings carry customsClearingEnabled even when the serviceType relation
  // isn't loaded / has includesCustoms=false — without this the per-booking
  // clearance grid would resolve empty.
  const includesCustoms =
    Boolean(booking.serviceType?.includesCustoms) ||
    Boolean(booking.customsClearingEnabled);
  // Intercity drawdowns under a ONE_TIME contract already cleared the intercity
  // document set on the CONTRACT (post-signature); only GENERAL drawdowns and
  // direct (contract-less) bookings carry the per-booking set.
  if (
    booking.tradeDirection === 'DOMESTIC' &&
    booking.contractId &&
    booking.contractKind === 'ONE_TIME'
  ) {
    return { inputCode: null, outputCode: null, includesCustoms: false };
  }
  return {
    inputCode: clearanceSettingCode(
      booking.tradeDirection,
      booking.freightType,
      includesCustoms,
    ),
    outputCode: clearanceOutputSettingCode(
      booking.tradeDirection,
      booking.freightType,
      includesCustoms,
    ),
    includesCustoms,
  };
}
