import { and, eq } from 'drizzle-orm';

import { db } from '@/lib/db';
import { systemSettings } from '@/lib/db/schema/system';
import type { EoiContext } from '@/lib/services/eoi-context';

export interface DocumensoTemplatePayload {
  title: string;
  externalId: string;
  meta: {
    message: string;
    subject: string;
    redirectUrl: string;
    distributionMethod: 'NONE' | 'EMAIL';
    /**
     * PARALLEL = all signers can sign in any order (default, current behaviour).
     * SEQUENTIAL = signers must complete in the order their `signingOrder`
     * number dictates (client → developer → approver for EOI). v2 enforces
     * this server-side; v1 ignores the key and behaves as PARALLEL regardless.
     */
    signingOrder?: 'PARALLEL' | 'SEQUENTIAL';
  };
  formValues: {
    Name: string;
    Email: string;
    Address: string;
    'Yacht Name': string;
    Length: string;
    Width: string;
    Draft: string;
    'Berth Number': string;
    /**
     * Compact range string of every berth in the interest's EOI bundle
     * (e.g. "A1-A3, B5"). Empty when the bundle is empty. Multi-berth
     * EOIs surface here; single-berth EOIs duplicate the primary mooring.
     */
    'Berth Range': string;
    Lease_10: boolean;
    Purchase: boolean;
  };
  recipients: Array<{
    id: number;
    name: string;
    email: string;
    role: 'SIGNER' | 'APPROVER';
    signingOrder: number;
  }>;
}

export interface DocumensoPayloadOptions {
  /** `interestId` used to build `externalId` and Documenso referencing. */
  interestId: string;
  /** Documenso recipient IDs - come from env vars. */
  clientRecipientId: number;
  developerRecipientId: number;
  approvalRecipientId: number;
  /** Hardcoded developer + approver names/emails (legacy). */
  developerName?: string;
  developerEmail?: string;
  approverName?: string;
  approverEmail?: string;
  /** Redirect URL after signing. Defaults to the app URL. */
  redirectUrl?: string;
  /**
   * PARALLEL (default) or SEQUENTIAL — v2-only enforcement (v1 ignores).
   * Set via per-port `documenso_signing_order` system_settings key.
   */
  signingOrder?: 'PARALLEL' | 'SEQUENTIAL';
}

const DEFAULT_DEVELOPER_NAME = 'David Mizrahi';
const DEFAULT_DEVELOPER_EMAIL = 'dm@portnimara.com';
const DEFAULT_APPROVER_NAME = 'Abbie May';
const DEFAULT_APPROVER_EMAIL = 'sales@portnimara.com';
const DEFAULT_REDIRECT_URL = 'https://portnimara.com';

export interface EoiSignerConfig {
  developer: { name: string; email: string };
  approver: { name: string; email: string };
}

const DEFAULT_EOI_SIGNERS: EoiSignerConfig = {
  developer: { name: DEFAULT_DEVELOPER_NAME, email: DEFAULT_DEVELOPER_EMAIL },
  approver: { name: DEFAULT_APPROVER_NAME, email: DEFAULT_APPROVER_EMAIL },
};

function isSignerEntry(v: unknown): v is { name: string; email: string } {
  return (
    !!v &&
    typeof v === 'object' &&
    typeof (v as Record<string, unknown>).name === 'string' &&
    typeof (v as Record<string, unknown>).email === 'string' &&
    !!(v as Record<string, string>).name &&
    !!(v as Record<string, string>).email
  );
}

/** Read the per-port `eoi_signers` setting, fall back to legacy hardcoded
 *  defaults if missing or malformed. The fallback exists to keep older
 *  ports working until an admin saves the setting; once saved, the DB row
 *  always wins. */
export async function getPortEoiSigners(portId: string): Promise<EoiSignerConfig> {
  const row = await db.query.systemSettings.findFirst({
    where: and(eq(systemSettings.key, 'eoi_signers'), eq(systemSettings.portId, portId)),
  });
  const value = row?.value as Record<string, unknown> | undefined;
  if (value && isSignerEntry(value.developer) && isSignerEntry(value.approver)) {
    return {
      developer: value.developer,
      approver: value.approver,
    };
  }
  return DEFAULT_EOI_SIGNERS;
}

function formatAddress(address: EoiContext['client']['address']): string {
  if (!address) return '';
  return [address.street, address.city, address.country].filter(Boolean).join(', ');
}

function buildMessage(context: EoiContext): string {
  const greeting = `Dear ${context.client.fullName},`;
  const body = `Thank you for your interest in a berth at ${context.port.name}. Please click the link above to sign your LOI.`;
  const onBehalf =
    context.owner.type === 'company' && context.company
      ? `\n\nOn behalf of ${context.company.legalName ?? context.company.name} (representing the yacht's owner).`
      : '';
  const footer = `\n\nBest Regards,\n${context.port.name} Team`;
  return `${greeting}\n\n${body}${onBehalf}${footer}`;
}

export function buildDocumensoPayload(
  context: EoiContext,
  options: DocumensoPayloadOptions,
): DocumensoTemplatePayload {
  return {
    title: `${context.client.fullName}-EOI-NDA`,
    externalId: `loi-${options.interestId}`,
    meta: {
      message: buildMessage(context),
      subject: 'Your LOI is ready to be signed',
      redirectUrl: options.redirectUrl ?? DEFAULT_REDIRECT_URL,
      distributionMethod: 'NONE',
      ...(options.signingOrder ? { signingOrder: options.signingOrder } : {}),
    },
    formValues: {
      Name: context.client.fullName,
      Email: context.client.primaryEmail ?? '',
      Address: formatAddress(context.client.address),
      // Yacht + berth are optional EOI fields; when not linked, render as
      // empty strings so the corresponding template inputs stay blank.
      'Yacht Name': context.yacht?.name ?? '',
      Length: context.yacht?.lengthFt ?? '',
      Width: context.yacht?.widthFt ?? '',
      Draft: context.yacht?.draftFt ?? '',
      'Berth Number': context.berth?.mooringNumber ?? '',
      'Berth Range': context.eoiBerthRange,
      Lease_10: false,
      Purchase: true,
    },
    recipients: [
      {
        id: options.clientRecipientId,
        name: context.client.fullName,
        email: context.client.primaryEmail ?? '',
        role: 'SIGNER',
        signingOrder: 1,
      },
      {
        id: options.developerRecipientId,
        name: options.developerName ?? DEFAULT_DEVELOPER_NAME,
        email: options.developerEmail ?? DEFAULT_DEVELOPER_EMAIL,
        role: 'SIGNER',
        signingOrder: 2,
      },
      {
        id: options.approvalRecipientId,
        name: options.approverName ?? DEFAULT_APPROVER_NAME,
        email: options.approverEmail ?? DEFAULT_APPROVER_EMAIL,
        role: 'APPROVER',
        signingOrder: 3,
      },
    ],
  };
}
