import { createContext, useContext } from 'react';
import { Briefcase, Heart, Moon, Sparkles, Sun, type LucideIcon } from 'lucide-react';
import type { ChakraType } from '@/lib/aura/types';
import type { PersonalBlueprintData } from '@/lib/blueprint/synthesizer';
import type { AuraCalculationResult } from '@/lib/aura/types';
import type { BaziCalculationResult } from '@/lib/bazi/types';
import type { NumerologyCalculationResult } from '@/lib/numerology/types';
import type { ReportScan } from '@/lib/reports/types';
import { useLocale, useMessages } from '@/i18n/client';
import { chakraMeta } from '@/lib/aura/chakraMeta';
import { DetailedPillars, ElementCycle } from '@/components/insights/BaziDetail';
import {
  DAY_MASTER_INFO,
  ELEMENT_INFO,
  ROLE_INFO,
  STRENGTH_INFO,
  elementLevel,
  elementRole,
} from '@/lib/bazi/guide';
import { CareerBaziSections, JodohSections } from './DestinyChapters';
import { CoreNumbers } from '@/components/insights/CoreNumbers';
import { numerologyTitle } from '@/lib/numerology/pythagorean';
import { ELEMENT_ORDER, ELEMENT_STYLE } from '@/components/insights/elements';
import { Button } from '@/components/ui/Button';
import { cn } from '@/lib/cn';
import { CHAPTERS, type ChapterId } from './chapters';
import type { Service } from '@/lib/reports/services';

export const CHAKRA_ORDER: ChakraType[] = [
  'crown',
  'third_eye',
  'throat',
  'heart',
  'solar_plexus',
  'sacral',
  'root',
];

/* ------------------------------------------------------------------ */
/* Building blocks                                                     */
/* ------------------------------------------------------------------ */

/** The chapters this report shows, in order — chapter numbers follow it. */
export const ChapterOrder = createContext<readonly ChapterId[]>(CHAPTERS);

export function Chapter({
  id,
  title,
  lead,
  onAsk,
  children,
}: {
  id: ChapterId;
  title: string;
  lead?: string;
  /** Omitted for viewers without Tanya AI access. */
  onAsk?: () => void;
  children: React.ReactNode;
}) {
  const t = useMessages().report.chapter;
  const number = useContext(ChapterOrder).indexOf(id) + 1;
  return (
    <section id={id} aria-labelledby={`${id}-title`} className="scroll-mt-36 lg:scroll-mt-24 print:break-before-page">
      <div className="flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between">
        <div>
          <p className="eyebrow text-subtle">{t.number(number)}</p>
          <h2 id={`${id}-title`} className="mt-3 text-[28px] leading-tight font-semibold tracking-[-0.02em] text-ink">
            {title}
          </h2>
          {lead && <p className="mt-2 max-w-xl text-[15px] leading-relaxed text-muted">{lead}</p>}
        </div>
        {onAsk && (
          <button
            type="button"
            onClick={onAsk}
            className="inline-flex shrink-0 items-center gap-1.5 self-start text-[13px] font-medium text-accent transition-colors hover:text-ink sm:self-auto print:hidden"
          >
            <Sparkles className="size-3.5" aria-hidden />
            {t.ask}
          </button>
        )}
      </div>
      <div className="mt-8 space-y-4">{children}</div>
    </section>
  );
}

export function Card({ className, children }: { className?: string; children: React.ReactNode }) {
  return (
    <div className={cn('rounded-card bg-surface p-6 shadow-card ring-1 ring-line/70', className)}>{children}</div>
  );
}

export function CardTitle({ icon: Icon, children }: { icon?: LucideIcon; children: React.ReactNode }) {
  return (
    <h3 className="flex items-center gap-2 text-[15px] font-semibold text-ink">
      {Icon && <Icon className="size-4 text-ink-soft" aria-hidden />}
      {children}
    </h3>
  );
}

export function Prose({ children }: { children: React.ReactNode }) {
  return <p className="mt-2 text-sm leading-relaxed text-ink-soft">{children}</p>;
}

export function BulletList({ items }: { items: string[] }) {
  return (
    <ul className="mt-3 space-y-2.5">
      {items.map((t) => (
        <li key={t} className="flex gap-3 text-sm leading-relaxed text-ink-soft">
          <span className="mt-[9px] size-1 shrink-0 rounded-full bg-ink-soft" aria-hidden />
          {t}
        </li>
      ))}
    </ul>
  );
}

export function SampleNotice({ text, action, onAction }: { text: string; action: string; onAction?: () => void }) {
  const t = useMessages().report.chapter;
  return (
    <div className="flex flex-col gap-4 rounded-card bg-accent-soft p-5 ring-1 ring-accent/15 sm:flex-row sm:items-center sm:justify-between print:hidden">
      <p className="text-sm leading-relaxed text-ink-soft">
        <span className="font-semibold text-ink">{t.samplePrefix}</span>
        {text}
      </p>
      {onAction && (
        <Button size="sm" variant="dark" withArrow onClick={onAction} className="self-start sm:self-auto">
          {action}
        </Button>
      )}
    </div>
  );
}

/* ------------------------------------------------------------------ */
/* Chapters                                                            */
/* ------------------------------------------------------------------ */

/** Report data with sample fallbacks already applied. */
export interface ReportModel {
  services: Service[];
  aura: AuraCalculationResult | null;
  bazi: BaziCalculationResult;
  numerology: NumerologyCalculationResult;
  scan: ReportScan | null;
  /** On-device capture, when the report came from a photo scan. */
  photo: string | null;
  isSample: { bazi: boolean; numerology: boolean };
  /** Whether the viewer can add BaZi / numerology. */
  canEdit: boolean;
}

/** A report known to include the aura service. */
export interface AuraModel extends ReportModel {
  aura: AuraCalculationResult;
  scan: ReportScan;
}

export interface ChapterProps {
  profile: ReportModel;
  /** Cross-system synthesis; only for reports with all three services. */
  blueprint: PersonalBlueprintData | null;
  onAsk?: (question: string) => void;
}

export interface AuraChapterProps {
  profile: AuraModel;
  onAsk?: (question: string) => void;
}

export function SummaryChapter({ profile, blueprint, onAsk }: ChapterProps & { blueprint: PersonalBlueprintData }) {
  const m = useMessages().report;
  const t = m.summary;
  const { crossSystemSynthesis: s } = blueprint;
  return (
    <Chapter
      id="ringkasan"
      title={m.view.chapters.ringkasan}
      lead={s.theme}
      onAsk={onAsk && (() => onAsk(t.ask))}
    >
      <Card>
        <p className="text-[15px] leading-relaxed text-ink">{s.narrative}</p>
      </Card>
      <div className="grid gap-4 md:grid-cols-2">
        <Card>
          <CardTitle>{t.synergies}</CardTitle>
          <BulletList items={s.synergies} />
        </Card>
        <Card>
          <CardTitle>{t.tensions}</CardTitle>
          <BulletList items={s.tensionsToBalance} />
        </Card>
      </div>
      {profile.scan && (
        <Card className="bg-canvas shadow-none">
          <CardTitle>{t.fromPhoto}</CardTitle>
          <Prose>{profile.scan.summary}</Prose>
        </Card>
      )}
    </Chapter>
  );
}

export function BaziChapter({ profile, onAsk, onComplete }: ChapterProps & { onComplete: () => void }) {
  const locale = useLocale();
  const all = useMessages();
  const m = all.report;
  const t = m.bazi;
  const info = ELEMENT_INFO[locale];
  const roles = ROLE_INFO[locale];
  const { bazi } = profile;
  const { year, month, day, hour } = bazi.fourPillars;
  const dm = bazi.dayMaster;
  const dmInfo = DAY_MASTER_INFO[locale][dm.stem.chinese];
  const strength = STRENGTH_INFO[locale][dm.strength];
  const polarity = all.insights.polarity[dm.polarity];
  const dmName = info[dm.element].name;

  return (
    <Chapter
      id="bazi"
      title={m.view.chapters.bazi}
      lead={t.lead(polarity, dmName, dm.stem.chinese, dm.stem.pinyin, strength.label)}
      onAsk={onAsk && (() => onAsk(t.ask(polarity, dmName)))}
    >
      {profile.isSample.bazi && (
        <SampleNotice text={t.sample} action={t.sampleAction} onAction={profile.canEdit ? onComplete : undefined} />
      )}
      <Card className="bg-canvas shadow-none">
        <CardTitle>{t.whatTitle}</CardTitle>
        <Prose>{t.whatText}</Prose>
      </Card>

      <Card>
        <CardTitle>{t.pillarsTitle}</CardTitle>
        <Prose>{t.pillarsText}</Prose>
        <div className="mt-5">
          <DetailedPillars pillars={{ year, month, day, hour }} />
        </div>
      </Card>

      <Card>
        <p className={cn('eyebrow', ELEMENT_STYLE[dm.element].text)}>{t.dmEyebrow}</p>
        <div className="mt-3 flex items-start gap-5">
          <span
            className={cn(
              'flex size-16 shrink-0 items-center justify-center rounded-2xl bg-canvas font-serif text-[40px] ring-1 ring-line',
              ELEMENT_STYLE[dm.element].text,
            )}
          >
            {dm.stem.chinese}
          </span>
          <div>
            <h3 className="text-xl font-semibold text-ink">
              {polarity} {dmName} <span className="font-normal text-subtle">· {dm.stem.pinyin}</span>
            </h3>
            {dmInfo && <p className="mt-1 text-sm text-muted">{t.symbol(dmInfo.image)}</p>}
          </div>
        </div>
        {dmInfo && (
          <>
            <Prose>{dmInfo.character}</Prose>
            <div className="mt-4 grid gap-4 sm:grid-cols-2">
              <div className="rounded-xl bg-wood/5 p-4 ring-1 ring-wood/15">
                <p className="text-xs font-semibold text-wood">{t.strengths}</p>
                <p className="mt-1 text-sm leading-relaxed text-ink-soft">{dmInfo.strengths}</p>
              </div>
              <div className="rounded-xl bg-earth/5 p-4 ring-1 ring-earth/20">
                <p className="text-xs font-semibold text-earth">{t.watch}</p>
                <p className="mt-1 text-sm leading-relaxed text-ink-soft">{dmInfo.watch}</p>
              </div>
            </div>
          </>
        )}
        <div className="mt-5 border-t border-line pt-4">
          <p className="text-sm font-semibold text-ink">
            {t.dmStrength} <span className={ELEMENT_STYLE[dm.element].text}>{strength.label}</span>
          </p>
          <Prose>{strength.text}</Prose>
        </div>
      </Card>

      <Card>
        <CardTitle>{t.elementsTitle}</CardTitle>
        <Prose>
          {t.elementsText[0]}
          <span className="font-medium text-ink">{t.elementsText[1]}</span>
          {t.elementsText[2]}
          <span className="font-medium text-fire">{t.elementsText[3]}</span>
          {t.elementsText[4]}
        </Prose>
        <div className="mt-4 grid items-center gap-6 md:grid-cols-[260px_minmax(0,1fr)]">
          <ElementCycle elements={bazi.elements} dayMaster={dm.element} className="mx-auto w-full max-w-[260px]" />
          <ul className="space-y-3">
            {ELEMENT_ORDER.map((el) => {
              const lv = elementLevel(bazi.elements[el], locale);
              return (
                <li key={el} className="flex items-center gap-3 text-[13px]">
                  <span className={cn('w-14 shrink-0 font-semibold', ELEMENT_STYLE[el].text)}>{info[el].name}</span>
                  <span className="h-[6px] flex-1 rounded-full bg-canvas">
                    <span
                      className={cn('block h-full rounded-full', ELEMENT_STYLE[el].bg)}
                      style={{ width: `${bazi.elements[el]}%` }}
                    />
                  </span>
                  <span className="w-8 shrink-0 text-right text-subtle tabular-nums">{bazi.elements[el]}</span>
                  <span
                    className={cn('w-14 shrink-0 rounded-full px-2 py-0.5 text-center text-[11px] font-medium', LEVEL_TONE[lv.tone])}
                  >
                    {lv.label}
                  </span>
                </li>
              );
            })}
          </ul>
        </div>
        <div className="mt-6 grid gap-4 sm:grid-cols-2">
          {[
            { el: bazi.dominantElement, title: t.strongest, extra: t.ifExcess(info[bazi.dominantElement].excess) },
            { el: bazi.growthElement, title: t.weakest, extra: t.ifLack(info[bazi.growthElement].lack) },
          ].map(({ el, title, extra }) => (
            <div key={title} className="rounded-2xl bg-canvas p-4">
              <p className="text-xs text-subtle">{title}</p>
              <p className={cn('mt-1 text-sm font-semibold', ELEMENT_STYLE[el].text)}>
                {info[el].symbol} {info[el].name} · {info[el].nature}
              </p>
              <p className="mt-1.5 text-[13px] leading-relaxed text-ink-soft">{info[el].traits}</p>
              <p className="mt-1.5 text-[13px] leading-relaxed text-muted">{extra}</p>
            </div>
          ))}
        </div>
      </Card>

      <Card>
        <CardTitle>{t.rolesTitle}</CardTitle>
        <Prose>{t.rolesText(dmName)}</Prose>
        <ul className="mt-5 grid gap-3 sm:grid-cols-2">
          {ELEMENT_ORDER.map((el) => {
            const role = roles[elementRole(dm.element, el)];
            const lv = elementLevel(bazi.elements[el], locale);
            return (
              <li key={el} className="rounded-2xl bg-canvas p-4">
                <p className="flex flex-wrap items-center gap-2 text-sm font-semibold text-ink">
                  <span className={cn('font-serif text-lg', ELEMENT_STYLE[el].text)}>{info[el].symbol}</span>
                  {info[el].name}: {role.label}
                  <span className={cn('rounded-full px-2 py-0.5 text-[11px] font-medium', LEVEL_TONE[lv.tone])}>{lv.label}</span>
                </p>
                <p className="mt-1.5 text-[13px] leading-relaxed text-ink-soft">{role.text}</p>
              </li>
            );
          })}
        </ul>
      </Card>

      <Card>
        <CardTitle>{t.supportTitle}</CardTitle>
        <Prose>{t.supportText}</Prose>
        <div className="mt-5 space-y-3">
          {[
            ...dm.supportingElements.map((el) => ({ el, kind: 'support' as const })),
            ...dm.weakeningElements.map((el) => ({ el, kind: 'weaken' as const })),
            ...(dm.supportingElements.includes(bazi.growthElement) || dm.weakeningElements.includes(bazi.growthElement)
              ? []
              : [{ el: bazi.growthElement, kind: 'grow' as const }]),
          ].map(({ el, kind }) => {
            const e = info[el];
            return (
              <div key={`${kind}-${el}`} className="rounded-2xl p-4 ring-1 ring-line sm:p-5">
                <p className="flex flex-wrap items-center gap-2 text-sm font-semibold text-ink">
                  <span className={cn('font-serif text-xl', ELEMENT_STYLE[el].text)}>{e.symbol}</span>
                  {e.name}
                  <span
                    className={cn(
                      'rounded-full px-2 py-0.5 text-[11px] font-medium',
                      kind === 'support' ? 'bg-wood/10 text-wood' : kind === 'weaken' ? 'bg-fire/10 text-fire' : 'bg-earth/10 text-earth',
                    )}
                  >
                    {kind === 'support' ? t.tagSupport : kind === 'weaken' ? t.tagWeaken : t.tagGrow}
                  </span>
                </p>
                <p className="mt-2 text-[13px] leading-relaxed text-ink-soft">
                  {kind === 'weaken'
                    ? t.weakenText(e.name, dmName)
                    : kind === 'grow'
                      ? t.growText(e.name)
                      : el === dm.element
                        ? t.sameText(e.name)
                        : t.sourceText(e.name, dmName)}
                </p>
                <dl className="mt-3 grid grid-cols-2 gap-x-4 gap-y-2 text-[12px] sm:grid-cols-4">
                  {[
                    [t.colors, e.colors],
                    [t.direction, e.direction],
                    [t.season, e.season],
                    [t.organ, e.organ],
                  ].map(([k, v]) => (
                    <div key={k}>
                      <dt className="text-subtle">{k}</dt>
                      <dd className="font-medium text-ink">{v}</dd>
                    </div>
                  ))}
                </dl>
                {kind !== 'weaken' && (
                  <div className="mt-3 grid gap-3 sm:grid-cols-2">
                    <div>
                      <p className="text-[12px] text-subtle">{t.howTo}</p>
                      <p className="text-[13px] leading-relaxed text-ink-soft">{e.boost}</p>
                    </div>
                    <div>
                      <p className="text-[12px] text-subtle">{t.fields}</p>
                      <p className="text-[13px] leading-relaxed text-ink-soft">{e.careers}</p>
                    </div>
                  </div>
                )}
              </div>
            );
          })}
        </div>
      </Card>
    </Chapter>
  );
}

const LEVEL_TONE = { high: 'bg-wood/10 text-wood', mid: 'bg-earth/10 text-earth', low: 'bg-fire/10 text-fire' } as const;

export function NumerologyChapter({ profile, onAsk, onComplete }: ChapterProps & { onComplete: () => void }) {
  const locale = useLocale();
  const m = useMessages().report;
  const t = m.numerology;
  const n = profile.numerology;
  const title = (num: number) => numerologyTitle(num, locale);
  const rows: [string, number, string][] = [
    ['Life Path', n.lifePath, title(n.lifePath)],
    ['Destiny', n.destiny, title(n.destiny)],
    ['Soul Urge', n.soulUrge, title(n.soulUrge)],
    ['Personality', n.personality, title(n.personality)],
    ['Maturity', n.maturity, title(n.maturity)],
    ['Birthday', n.birthday, t.birthdayTitle],
  ];

  return (
    <Chapter
      id="numerologi"
      title={t.title}
      lead={t.lead(n.lifePath, title(n.lifePath))}
      onAsk={onAsk && (() => onAsk(t.ask(n.lifePath)))}
    >
      {profile.isSample.numerology && (
        <SampleNotice text={t.sample} action={t.sampleAction} onAction={profile.canEdit ? onComplete : undefined} />
      )}
      <div className="grid gap-4 md:grid-cols-5">
        <Card className="md:col-span-2">
          <CoreNumbers
            lifePath={n.lifePath}
            lifePathTitle={title(n.lifePath)}
            numbers={[
              { label: 'Destiny', value: n.destiny, title: '', tone: 'blue' },
              { label: 'Soul Urge', value: n.soulUrge, title: '', tone: 'violet' },
              { label: 'Personality', value: n.personality, title: '', tone: 'amber' },
            ]}
          />
        </Card>
        <Card className="md:col-span-3">
          <ul className="divide-y divide-line">
            {rows.map(([label, value, title]) => (
              <li key={label} className="flex items-center gap-4 py-3 first:pt-0 last:pb-0">
                <span className="w-8 text-xl font-light text-ink tabular-nums">{value}</span>
                <span className="min-w-0">
                  <span className="block text-xs font-medium text-subtle">{label}</span>
                  <span className="block truncate text-sm text-ink-soft">{title}</span>
                </span>
              </li>
            ))}
          </ul>
        </Card>
      </div>
    </Chapter>
  );
}

export function CareerChapter({ profile, blueprint, onAsk }: ChapterProps) {
  const m = useMessages().report;
  const t = m.career;
  return (
    <Chapter id="karier" title={m.view.chapters.karier} onAsk={onAsk && (() => onAsk(t.ask))}>
      {blueprint && (
        <Card>
          <CardTitle icon={Briefcase}>{t.ideal}</CardTitle>
          <Prose>{blueprint.careerInsights}</Prose>
        </Card>
      )}
      <Card>
        <CardTitle>{t.wealthTitle}</CardTitle>
        <Prose>{t.wealthText}</Prose>
      </Card>
      <CareerBaziSections profile={profile} />
    </Chapter>
  );
}

export function RelationshipChapter({
  profile,
  blueprint,
  onAsk,
  onComplete,
}: ChapterProps & { onComplete: () => void }) {
  const m = useMessages().report;
  const t = m.relationship;
  return (
    <Chapter id="relasi" title={m.view.chapters.relasi} onAsk={onAsk && (() => onAsk(t.ask))}>
      {blueprint && (
        <Card>
          <CardTitle icon={Heart}>{t.connect}</CardTitle>
          <Prose>{blueprint.relationshipInsights}</Prose>
        </Card>
      )}
      <Card className="bg-canvas shadow-none">
        <CardTitle>{t.conflict}</CardTitle>
        <Prose>{t.conflictText}</Prose>
      </Card>
      <p className="eyebrow pt-4 text-subtle">{t.baziEyebrow}</p>
      <JodohSections profile={profile} onAsk={onAsk} onComplete={onComplete} />
    </Chapter>
  );
}

export function RitualChapter({ profile, blueprint, onAsk }: AuraChapterProps & { blueprint: PersonalBlueprintData | null }) {
  const locale = useLocale();
  const m = useMessages().report;
  const t = m.ritual;
  const growth = chakraMeta(locale)[profile.aura.growthChakra];
  return (
    <Chapter
      id="ritual"
      title={m.view.chapters.ritual}
      lead={t.lead}
      onAsk={onAsk && (() => onAsk(t.ask))}
    >
      <div className="grid gap-4 md:grid-cols-2">
        <Card>
          <CardTitle icon={Sun}>{t.morning}</CardTitle>
          <Prose>{t.morningText(growth.name)}</Prose>
        </Card>
        <Card>
          <CardTitle icon={Moon}>{t.night}</CardTitle>
          <Prose>{t.nightText}</Prose>
        </Card>
      </div>
      {blueprint && (
        <>
          <Card>
            <CardTitle>{t.growth}</CardTitle>
            <BulletList items={blueprint.personalGrowthAdvice} />
          </Card>
          <Card className="bg-canvas shadow-none">
            <CardTitle>{t.reflect}</CardTitle>
            <BulletList items={blueprint.reflectiveQuestions} />
          </Card>
        </>
      )}
    </Chapter>
  );
}
