'use client';

import type { ReactNode } from 'react';
import { useTranslations } from 'next-intl';
import { Trash2 } from 'lucide-react';
import { Button } from '@/components/ui/shared/Button';
import {
  ResponsiveDialogOverlay,
  ResponsiveDialogPanel,
} from '@/components/ui/shared/ResponsiveDialog';
import type { ProsthesisCatalogEntry } from '@/types/treatment-catalog';
import { prosthesisTypeColorFromCatalog, prosthesisTypeFillAccent } from '@/components/treatment/prosthesisTypeDisplay';
import {
  addonLeaves,
  categoryCodesInCatalog,
  categoryTileColor,
  leavesFor,
  subcategoriesFor,
  type ArchTarget,
  type PickerScope,
} from '@/components/treatment/prosthesisTree';

const CHIP_INK = '#14253d';
const TILE_CLASS =
  'flex h-full min-h-0 w-[3.6rem] shrink-0 flex-row items-center justify-center gap-0.5 rounded-[var(--radius-md)] border px-0.5 py-2 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/40';
const TILE_TEXT_CLASS =
  'max-h-full overflow-hidden [writing-mode:vertical-rl] [text-orientation:mixed] whitespace-normal break-words text-center text-xs font-medium leading-tight sm:text-[13px]';
const HEADER_BTN_CLASS = 'h-auto min-h-8 px-2.5 py-1 text-xs leading-tight';

export type PickerStep =
  | { kind: 'category' }
  | { kind: 'subcategory'; category: string; arch?: ArchTarget }
  | { kind: 'leaves'; category: string; subcategory?: string; arch?: ArchTarget }
  | { kind: 'addon'; slot: 'implant' | 'post_core' };

interface ProsthesisJobPopoverProps {
  open: boolean;
  mobile: boolean;
  catalog: readonly ProsthesisCatalogEntry[];
  step: PickerStep;
  scope: PickerScope;
  lockedArch?: ArchTarget;
  jobCodes: string[];
  tooth: string | null;
  rangeLabel?: string | null;
  allowImplantAddon: boolean;
  allowPostCoreAddon: boolean;
  onStep: (step: PickerStep) => void;
  onLockedArchChange?: (arch: ArchTarget) => void;
  onPickLeaf: (code: string, arch?: ArchTarget) => void;
  onPickAddon: (code: string | null, kind: 'implant' | 'post_core') => void;
  onRemoveJob: (code: string) => void;
  onClear: () => void;
  onClose: () => void;
}

function Tile({
  label,
  caption,
  color,
  active,
  onClick,
}: {
  label: string;
  caption?: string;
  color?: string;
  active?: boolean;
  onClick: () => void;
}) {
  return (
    <button
      type="button"
      title={caption ? `${caption}: ${label}` : label}
      onClick={onClick}
      className={`${TILE_CLASS} ${
        active
          ? 'border-primary ring-1 ring-primary/30'
          : 'border-border/70 hover:border-border hover:bg-background-card/70'
      }`}
      style={color ? { backgroundColor: color, color: CHIP_INK } : undefined}
    >
      {caption ? (
        <span className="max-h-full max-w-[0.7rem] shrink-0 overflow-hidden [writing-mode:vertical-rl] [text-orientation:mixed] whitespace-normal break-words text-center text-[10px] font-medium leading-tight opacity-70">
          {caption}
        </span>
      ) : null}
      <span className={TILE_TEXT_CLASS}>{label}</span>
    </button>
  );
}

function VRule() {
  return <div className="w-px shrink-0 self-stretch bg-border-strong" aria-hidden />;
}

function parentStep(step: PickerStep): PickerStep | null {
  if (step.kind === 'category') return null;
  if (step.kind === 'addon') return { kind: 'category' };
  if (step.kind === 'leaves') {
    if (step.subcategory) {
      return { kind: 'subcategory', category: step.category, arch: step.arch };
    }
    return { kind: 'category' };
  }
  if (step.kind === 'subcategory') return { kind: 'category' };
  return { kind: 'category' };
}

export function ProsthesisJobPopover({
  open,
  mobile,
  catalog,
  step,
  scope,
  lockedArch,
  jobCodes,
  tooth,
  rangeLabel,
  allowImplantAddon,
  allowPostCoreAddon,
  onStep,
  onLockedArchChange,
  onPickLeaf,
  onPickAddon,
  onRemoveJob,
  onClear,
  onClose,
}: ProsthesisJobPopoverProps) {
  const t = useTranslations('prosthesis');
  if (!open) return null;

  const categories = categoryCodesInCatalog(catalog, scope);
  const implantAddons = addonLeaves(catalog, 'implant');
  const postCoreAddons = addonLeaves(catalog, 'post_core');
  const currentImplant =
    jobCodes.find((c) => catalog.find((e) => e.code === c)?.addonKind === 'implant') ?? '';
  const currentPost =
    jobCodes.find((c) => catalog.find((e) => e.code === c)?.addonKind === 'post_core') ?? '';
  const hasLeaf = jobCodes.length > 0;
  const byCode = new Map(catalog.map((e) => [e.code, e]));
  const archForLeaves =
    step.kind === 'leaves' || step.kind === 'subcategory' ? step.arch : lockedArch;

  function categoryLabel(code: string) {
    return t(`category_${code}` as never);
  }
  function subLabel(code: string) {
    return t(`sub_${code}` as never);
  }

  const back = parentStep(step);

  function openCategory(code: string) {
    const subs = subcategoriesFor(catalog, code, scope);
    const arch = scope === 'arch' ? lockedArch : undefined;
    if (subs.length > 0) {
      onStep({ kind: 'subcategory', category: code, arch });
      return;
    }
    onStep({ kind: 'leaves', category: code, arch });
  }

  function leafTile(leaf: ProsthesisCatalogEntry) {
    return (
      <Tile
        key={leaf.code}
        label={leaf.label}
        color={prosthesisTypeColorFromCatalog(leaf.code, catalog)}
        active={jobCodes.includes(leaf.code)}
        onClick={() => onPickLeaf(leaf.code, archForLeaves)}
      />
    );
  }

  const addonTiles: ReactNode[] = [];
  if (scope === 'tooth' && hasLeaf) {
    if (allowImplantAddon && implantAddons.length > 0) {
      addonTiles.push(
        <Tile
          key="slot-implant"
          caption={t('slotImplant')}
          label={
            currentImplant
              ? (byCode.get(currentImplant)?.label ?? currentImplant)
              : t('addonNone')
          }
          color={
            currentImplant
              ? prosthesisTypeColorFromCatalog(currentImplant, catalog)
              : undefined
          }
          active={step.kind === 'addon' && step.slot === 'implant'}
          onClick={() =>
            onStep(
              step.kind === 'addon' && step.slot === 'implant'
                ? { kind: 'category' }
                : { kind: 'addon', slot: 'implant' },
            )
          }
        />,
      );
    }
    if (allowPostCoreAddon && postCoreAddons.length > 0) {
      addonTiles.push(
        <Tile
          key="slot-post"
          caption={t('slotPostCore')}
          label={
            currentPost ? (byCode.get(currentPost)?.label ?? currentPost) : t('addonNone')
          }
          color={
            currentPost ? prosthesisTypeColorFromCatalog(currentPost, catalog) : undefined
          }
          active={step.kind === 'addon' && step.slot === 'post_core'}
          onClick={() =>
            onStep(
              step.kind === 'addon' && step.slot === 'post_core'
                ? { kind: 'category' }
                : { kind: 'addon', slot: 'post_core' },
            )
          }
        />,
      );
    }
  }

  let selectedNode: { label: string; color?: string } | null = null;
  let childTiles: ReactNode[] = [];
  let childrenKey = 'root';

  if (step.kind === 'category') {
    childTiles = categories.map((code) => (
      <Tile
        key={code}
        label={categoryLabel(code)}
        color={categoryTileColor(code)}
        onClick={() => openCategory(code)}
      />
    ));
  } else if (step.kind === 'addon') {
    selectedNode = {
      label: step.slot === 'implant' ? t('slotImplant') : t('slotPostCore'),
    };
    childrenKey = `addon-${step.slot}`;
    const options = step.slot === 'implant' ? implantAddons : postCoreAddons;
    const current = step.slot === 'implant' ? currentImplant : currentPost;
    childTiles = [
      <Tile
        key="none"
        label={t('addonNone')}
        active={!current}
        onClick={() => onPickAddon(null, step.slot)}
      />,
      ...options.map((opt) => (
        <Tile
          key={opt.code}
          label={opt.label}
          color={prosthesisTypeColorFromCatalog(opt.code, catalog)}
          active={current === opt.code}
          onClick={() => onPickAddon(opt.code, step.slot)}
        />
      )),
    ];
  } else if (step.kind === 'leaves' && step.subcategory) {
    selectedNode = { label: subLabel(step.subcategory) };
    childrenKey = `leaves-${step.category}-${step.subcategory}`;
    childTiles = leavesFor(catalog, step.category, step.subcategory, scope).map(leafTile);
  } else {
    selectedNode = {
      label: categoryLabel(step.category),
      color: categoryTileColor(step.category),
    };
    childrenKey = `${step.kind}-${step.category}`;
    const arch = step.arch;
    const subs =
      step.kind === 'subcategory'
        ? subcategoriesFor(catalog, step.category, scope).map((sub) => (
            <Tile
              key={sub}
              label={subLabel(sub)}
              onClick={() =>
                onStep({
                  kind: 'leaves',
                  category: step.category,
                  subcategory: sub,
                  arch,
                })
              }
            />
          ))
        : [];
    const leaves = leavesFor(
      catalog,
      step.category,
      step.kind === 'leaves' ? step.subcategory : undefined,
      scope,
    ).map(leafTile);
    childTiles = [...subs, ...leaves];
  }

  const tileRow = (
    <div className="flex h-full min-h-0 min-w-0 flex-1 flex-row items-stretch gap-2 overflow-x-auto overflow-y-hidden pe-1">
      {selectedNode ? (
        <div className="flex h-full min-h-0 shrink-0 flex-row items-stretch gap-4">
          <Tile
            label={selectedNode.label}
            color={selectedNode.color}
            active
            onClick={() => back && onStep(back)}
          />
          <VRule />
          <div
            key={childrenKey}
            className="picker-expand flex h-full min-h-0 shrink-0 flex-row items-stretch gap-2"
          >
            {childTiles}
          </div>
        </div>
      ) : (
        childTiles
      )}
    </div>
  );

  const title = rangeLabel
    ? t('pickerTeeth', { teeth: rangeLabel })
    : scope === 'arch'
      ? lockedArch === 'both'
        ? t('pickerArchBoth')
        : lockedArch === 'lower'
          ? t('pickerArchLower')
          : t('pickerArchUpper')
      : tooth
        ? t('pickerTooth', { tooth })
        : t('pickerTitle');

  const header = (
    <div className="space-y-1.5 shrink-0">
      <div className="flex items-start justify-between gap-2">
        <p className="min-w-0 text-xs font-semibold text-text-primary">{title}</p>
        <div className="flex shrink-0 items-center gap-1.5">
          <Button
            type="button"
            variant="outline"
            size="sm"
            className={HEADER_BTN_CLASS}
            disabled={!hasLeaf}
            onClick={onClear}
          >
            {scope === 'arch' ? t('clearArch') : t('clear')}
          </Button>
          <Button
            type="button"
            variant="primary"
            size="sm"
            className={HEADER_BTN_CLASS}
            onClick={onClose}
          >
            {t('done')}
          </Button>
        </div>
      </div>
      {scope === 'arch' && onLockedArchChange ? (
        <div className="flex gap-1">
          {(['upper', 'lower', 'both'] as const).map((arch) => (
            <button
              key={arch}
              type="button"
              onClick={() => onLockedArchChange(arch)}
              className={`flex-1 min-h-9 rounded-[var(--radius-sm)] border text-xs font-medium ${
                lockedArch === arch
                  ? 'border-primary bg-primary-soft text-text-primary'
                  : 'border-border/70 text-text-secondary hover:border-border'
              }`}
            >
              {t(`arch_${arch}`)}
            </button>
          ))}
        </div>
      ) : null}
      {jobCodes.length === 0 ? (
        <p className="text-xs text-text-muted">{t('noneYet')}</p>
      ) : (
        <div className="flex flex-wrap gap-1.5">
          {jobCodes.map((code) => {
            const entry = byCode.get(code);
            const color = prosthesisTypeColorFromCatalog(code, catalog);
            const trashColor = prosthesisTypeFillAccent(color);
            return (
              <span
                key={code}
                className="inline-flex items-stretch overflow-hidden rounded-[var(--radius-md)] border text-[11px] font-medium"
                style={{
                  backgroundColor: color,
                  color: CHIP_INK,
                  borderColor: 'rgba(0,0,0,0.16)',
                }}
              >
                <span className="inline-flex items-center gap-1 px-2 py-0.5">
                  <span className="opacity-70">
                    {entry?.category
                      ? t(`category_${entry.category}` as never)
                      : t('regionCrown')}
                  </span>
                  {entry?.label ?? code}
                </span>
                <button
                  type="button"
                  className="inline-flex items-center justify-center border-s px-1.5 transition-colors hover:brightness-90"
                  style={{
                    borderColor: trashColor,
                    color: trashColor,
                  }}
                  aria-label={t('removeJob')}
                  onClick={(e) => {
                    e.stopPropagation();
                    onRemoveJob(code);
                  }}
                >
                  <Trash2 className="lucide-inherit h-3.5 w-3.5" aria-hidden />
                </button>
              </span>
            );
          })}
        </div>
      )}
      <p className="text-[10px] text-text-muted">
        {scope === 'arch' ? t('clearHintArch') : t('clearHint')}
      </p>
    </div>
  );

  const addonRail =
    addonTiles.length > 0 ? (
      <div className="flex shrink-0 flex-row items-stretch gap-2 border-s border-border ps-3">
        {addonTiles}
      </div>
    ) : null;

  const body = (
    <div className="flex h-full min-h-0 flex-col gap-3">
      {header}
      <div className="flex min-h-0 flex-1 flex-row items-stretch gap-0">
        {tileRow}
        {addonRail}
      </div>
    </div>
  );

  if (mobile) {
    return (
      <ResponsiveDialogOverlay onBackdropClick={onClose}>
        <ResponsiveDialogPanel
          role="dialog"
          aria-modal="true"
          maxWidthClass="sm:max-w-lg"
          className="max-h-[90dvh] flex flex-col"
        >
          <h4 className="sr-only">{t('pickerTitle')}</h4>
          <div className="min-h-0 flex-1 overflow-hidden">{body}</div>
        </ResponsiveDialogPanel>
      </ResponsiveDialogOverlay>
    );
  }

  return (
    <div className="absolute inset-0 z-30 pointer-events-none">
      <button
        type="button"
        className="absolute inset-0 bg-background-primary/55 pointer-events-auto"
        aria-label={t('done')}
        onClick={onClose}
      />
      <div
        className="absolute inset-0 z-10 pointer-events-auto flex flex-col overflow-hidden rounded-[var(--radius-md)] border border-border bg-background-secondary p-3 shadow-lg"
        role="dialog"
        onClick={(e) => e.stopPropagation()}
        onPointerDown={(e) => e.stopPropagation()}
      >
        <h4 className="sr-only">{t('pickerTitle')}</h4>
        {body}
      </div>
    </div>
  );
}
