import type { ApprovedIconName } from '@/components/foundation/Icon';
import type { PreviewRow } from '@/components/marketing/ProductPreview';
import type { HomepageMessages, ShellMessages } from '@/lib/localization/messages';
import type { Locale } from '@/lib/localization/config';
import { accountCreateUrl } from '@/lib/account-urls';
import {
  fleetBandIds,
  pricingPlanIds,
  type FleetBandId,
  type PricingPlanId,
} from '@/content/pricing-config';
import { existsSync } from 'node:fs';
import { join } from 'node:path';

export interface HomepageAction {
  label: string;
  href?: string;
  disabledReason?: string;
}

export interface TitledDescription {
  id: string;
  title: string;
  description: string;
  icon?: ApprovedIconName;
}

export interface HomepageWorkflowStep extends TitledDescription {
  ordinal: string;
}

export interface HomepageFaqItem {
  id: string;
  title: string;
  body: string;
}

export interface HomepagePricingFleetBand {
  id: FleetBandId;
  label: string;
}

export interface HomepagePricingPlan {
  id: PricingPlanId;
  name: string;
  audience: string;
  features: string[];
  cta: string;
}

export interface HomepageImageAsset {
  src: string;
  alt: string;
  width: number;
  height: number;
}

export interface HomepageContent {
  hero: {
    eyebrow: string;
    title: string;
    body: string;
    primary: HomepageAction;
    secondary: HomepageAction;
    preview: {
      title: string;
      caption: string;
      illustrativeLabel: string;
      rows: PreviewRow[];
    };
    image: HomepageImageAsset;
  };
  trust: {
    eyebrow: string;
    title: string;
    body: string;
    items: TitledDescription[];
  };
  comparison: {
    eyebrow: string;
    title: string;
    body: string;
    beforeTitle: string;
    beforeItems: string[];
    afterTitle: string;
    afterItems: string[];
    image: HomepageImageAsset;
  };
  workflow: {
    eyebrow: string;
    title: string;
    body: string;
    steps: HomepageWorkflowStep[];
    image: HomepageImageAsset;
  };
  roles: {
    eyebrow: string;
    title: string;
    items: TitledDescription[];
  };
  modules: {
    eyebrow: string;
    title: string;
    body: string;
    items: TitledDescription[];
    image: HomepageImageAsset;
  };
  results: {
    eyebrow: string;
    title: string;
    body: string;
    metrics: TitledDescription[];
    methodTitle: string;
    method: string[];
    image: HomepageImageAsset;
  };
  integrations: {
    eyebrow: string;
    title: string;
    body: string;
    items: string[];
  };
  security: {
    eyebrow: string;
    title: string;
    body: string;
    checks: TitledDescription[];
  };
  pricing: {
    eyebrow: string;
    title: string;
    body: string;
    fleetSelectorLabel: string;
    fleetBands: HomepagePricingFleetBand[];
    billingLegend: string;
    billingMonthly: string;
    billingAnnual: string;
    billingSavings: string;
    recommended: string;
    startingAt: string;
    perMonth: string;
    annualEquivalent: string;
    pricePending: string;
    customPrice: string;
    plans: HomepagePricingPlan[];
    basisTitle: string;
    basis: string[];
    modulesTitle: string;
    modules: string[];
    assurances: string[];
    notSure: string;
    compare: string;
    note: string;
    actionDisabledReason: string;
  };
  faq: {
    eyebrow: string;
    title: string;
    items: HomepageFaqItem[];
  };
  final: {
    eyebrow: string;
    title: string;
    body: string;
    primary: HomepageAction;
    secondary: HomepageAction;
    image: HomepageImageAsset;
  };
}

const trustIcons: ApprovedIconName[] = ['calendar', 'car', 'check', 'settings'];
const roleIcons: ApprovedIconName[] = ['settings', 'calendar', 'car', 'check'];
const moduleIcons: ApprovedIconName[] = ['calendar', 'car', 'check', 'search', 'globe', 'settings'];
const resultIcons: ApprovedIconName[] = ['calendar', 'settings', 'car', 'warning'];
const securityIcons: ApprovedIconName[] = ['settings', 'search', 'globe', 'warning'];

const homepagePublicPath = join(process.cwd(), 'public');
const homepagePublicFallbackPath = join(process.cwd(), 'apps/homepage/public');
const localeAssetSuffix: Record<Locale, string> = {
  en: 'EN',
  fr: 'FR',
  ar: 'AR',
};

function publicAssetExists(fileName: string): boolean {
  return existsSync(join(homepagePublicPath, fileName)) || existsSync(join(homepagePublicFallbackPath, fileName));
}

function localizedImage(
  subject: string,
  locale: Locale,
  extension: 'jpeg' | 'png',
  dimensions: Pick<HomepageImageAsset, 'width' | 'height'>,
  alt: string,
): HomepageImageAsset {
  const localizedFile = `${subject}_${localeAssetSuffix[locale]}.${extension}`;
  const hyphenLocalizedFile = `${subject}-${locale}.${extension}`;
  const defaultFile = `${subject}.${extension}`;
  const fileName = publicAssetExists(localizedFile)
    ? localizedFile
    : publicAssetExists(hyphenLocalizedFile)
      ? hyphenLocalizedFile
      : defaultFile;

  return {
    src: `/${fileName}`,
    alt,
    width: dimensions.width,
    height: dimensions.height,
  };
}

function pair(value: readonly string[], context: string): { title: string; description: string } {
  const title = value[0];
  const description = value[1];
  if (title === undefined || description === undefined) {
    throw new Error(`${context} must contain a title and description.`);
  }
  return { title, description };
}

function triple(
  value: readonly string[],
  context: string,
): { ordinal: string; title: string; description: string } {
  const ordinal = value[0];
  const title = value[1];
  const description = value[2];
  if (ordinal === undefined || title === undefined || description === undefined) {
    throw new Error(`${context} must contain an ordinal, title, and description.`);
  }
  return { ordinal, title, description };
}

function asFleetBandId(value: string, context: string): FleetBandId {
  if (!(fleetBandIds as readonly string[]).includes(value)) {
    throw new Error(`${context} contains an unknown fleet band ID: ${value}`);
  }
  return value as FleetBandId;
}

function asPricingPlanId(value: string, context: string): PricingPlanId {
  if (!(pricingPlanIds as readonly string[]).includes(value)) {
    throw new Error(`${context} contains an unknown pricing plan ID: ${value}`);
  }
  return value as PricingPlanId;
}

function mapPairs(
  values: readonly (readonly string[])[],
  prefix: string,
  icons: readonly ApprovedIconName[] = [],
): TitledDescription[] {
  return values.map((value, index) => {
    const item = pair(value, `${prefix}[${index}]`);
    const icon = icons[index];
    return {
      id: `${prefix}-${index + 1}`,
      ...item,
      ...(icon ? { icon } : {}),
    };
  });
}

export function buildHomepageContent(
  homepage: HomepageMessages,
  shell: ShellMessages,
  locale: Locale = 'en',
): HomepageContent {
  const pendingReason = shell.states.pendingBody;

  return {
    hero: {
      eyebrow: homepage.hero.eyebrow,
      title: homepage.hero.title,
      body: homepage.hero.body,
      primary: { label: homepage.hero.primary, href: accountCreateUrl(locale) },
      secondary: { label: homepage.hero.secondary, disabledReason: pendingReason },
      preview: {
        title: homepage.preview.title,
        caption: homepage.hero.caption,
        illustrativeLabel: `${homepage.preview.today} · ${homepage.preview.branch}`,
        rows: [
          {
            id: 'preview-reservation-1',
            primary: `${homepage.preview.r1} · ${homepage.preview.taskAssign}`,
            secondary: homepage.preview.plate1,
            status: homepage.preview.statusReady,
            statusTone: 'success',
          },
          {
            id: 'preview-reservation-2',
            primary: `${homepage.preview.r2} · ${homepage.preview.taskInspect}`,
            secondary: homepage.preview.plate2,
            status: homepage.preview.statusDue,
            statusTone: 'warning',
          },
        ],
      },
      image: localizedImage(
        'dashboard1',
        locale,
        'png',
        { width: 1672, height: 941 },
        homepage.preview.title,
      ),
    },
    trust: {
      eyebrow: homepage.trust.eyebrow,
      title: homepage.trust.title,
      body: homepage.trust.body,
      items: mapPairs(homepage.trust.items, 'lifecycle', trustIcons),
    },
    comparison: {
      eyebrow: homepage.comparison.eyebrow,
      title: homepage.comparison.title,
      body: homepage.comparison.body,
      beforeTitle: homepage.comparison.beforeTitle,
      beforeItems: homepage.comparison.beforeItems,
      afterTitle: homepage.comparison.afterTitle,
      afterItems: homepage.comparison.afterItems,
      image: localizedImage(
        'benefit1',
        locale,
        'png',
        { width: 1672, height: 941 },
        homepage.comparison.title,
      ),
    },
    workflow: {
      eyebrow: homepage.workflow.eyebrow,
      title: homepage.workflow.title,
      body: homepage.workflow.body,
      steps: homepage.workflow.steps.map((value, index) => ({
        id: `workflow-${index + 1}`,
        ...triple(value, `workflow.steps[${index}]`),
      })),
      image: localizedImage(
        'workflow1',
        locale,
        'png',
        { width: 1672, height: 941 },
        homepage.workflow.title,
      ),
    },
    roles: {
      eyebrow: homepage.roles.eyebrow,
      title: homepage.roles.title,
      items: mapPairs(homepage.roles.roles, 'role', roleIcons),
    },
    modules: {
      eyebrow: homepage.modules.eyebrow,
      title: homepage.modules.title,
      body: homepage.modules.body,
      items: mapPairs(homepage.modules.items, 'module', moduleIcons),
      image: localizedImage(
        'oilchange1',
        locale,
        'png',
        { width: 1254, height: 1254 },
        homepage.modules.title,
      ),
    },
    results: {
      eyebrow: homepage.results.eyebrow,
      title: homepage.results.title,
      body: homepage.results.body,
      metrics: mapPairs(homepage.results.metrics, 'measurement', resultIcons),
      methodTitle: homepage.results.methodTitle,
      method: homepage.results.method,
      image: localizedImage(
        'dashboard2',
        locale,
        'png',
        { width: 1672, height: 941 },
        homepage.results.title,
      ),
    },
    integrations: {
      eyebrow: homepage.integrations.eyebrow,
      title: homepage.integrations.title,
      body: homepage.integrations.body,
      items: homepage.integrations.items,
    },
    security: {
      eyebrow: homepage.security.eyebrow,
      title: homepage.security.title,
      body: homepage.security.body,
      checks: mapPairs(homepage.security.checks, 'security', securityIcons),
    },
    pricing: {
      eyebrow: homepage.pricing.eyebrow,
      title: homepage.pricing.title,
      body: homepage.pricing.body,
      fleetSelectorLabel: homepage.pricing.fleetSelectorLabel,
      fleetBands: homepage.pricing.fleetBands.map((item, index) => ({
        id: asFleetBandId(item.id, `pricing.fleetBands[${index}]`),
        label: item.label,
      })),
      billingLegend: homepage.pricing.billingLegend,
      billingMonthly: homepage.pricing.billingMonthly,
      billingAnnual: homepage.pricing.billingAnnual,
      billingSavings: homepage.pricing.billingSavings,
      recommended: homepage.pricing.recommended,
      startingAt: homepage.pricing.startingAt,
      perMonth: homepage.pricing.perMonth,
      annualEquivalent: homepage.pricing.annualEquivalent,
      pricePending: homepage.pricing.pricePending,
      customPrice: homepage.pricing.customPrice,
      plans: homepage.pricing.plans.map((plan, index) => ({
        id: asPricingPlanId(plan.id, `pricing.plans[${index}]`),
        name: plan.name,
        audience: plan.audience,
        features: plan.features,
        cta: plan.cta,
      })),
      basisTitle: homepage.pricing.basisTitle,
      basis: homepage.pricing.basis,
      modulesTitle: homepage.pricing.modulesTitle,
      modules: homepage.pricing.modules,
      assurances: homepage.pricing.assurances,
      notSure: homepage.pricing.notSure,
      compare: homepage.pricing.compare,
      note: homepage.pricing.note,
      actionDisabledReason: pendingReason,
    },
    faq: {
      eyebrow: homepage.faq.eyebrow,
      title: homepage.faq.title,
      items: homepage.faq.items.map((value, index) => {
        const item = pair(value, `faq.items[${index}]`);
        return { id: `faq-${index + 1}`, title: item.title, body: item.description };
      }),
    },
    final: {
      eyebrow: homepage.final.eyebrow,
      title: homepage.final.title,
      body: homepage.final.body,
      primary: { label: homepage.final.primary, href: accountCreateUrl(locale) },
      secondary: { label: homepage.final.secondary, disabledReason: pendingReason },
      image: localizedImage(
        'rentaldrivego',
        locale,
        'png',
        { width: 1220, height: 1167 },
        'RentalDriveGo',
      ),
    },
  };
}
