// Презентационные примитивы и редакторы полей формы.
(function () {
  const { useState } = React as any;
  const T = (window as any).AppTypes;

  const Badge = ({ tone = "slate", children, title }: any) => {
    const tones: Record<string, string> = {
      slate: "bg-black/5 text-ink-soft",
      blue: "bg-ink text-white",
      lime: "bg-lime text-ink",
      violet: "bg-violet-100 text-violet-800",
      amber: "bg-amber-100 text-amber-900",
      emerald: "bg-lime-soft text-[#4d7a00]",
      rose: "bg-rose-100 text-rose-800",
    };
    return (
      <span title={title}
        className={"inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-[11px] font-semibold " + (tones[tone] || tones.slate)}>
        {children}
      </span>
    );
  };

  const Button = ({ variant = "primary", className = "", children, ...rest }: any) => {
    const base = "inline-flex items-center justify-center gap-2 rounded-full text-sm font-semibold transition active:scale-[.98] disabled:opacity-35 disabled:cursor-not-allowed px-4 py-2.5";
    const variants: Record<string, string> = {
      primary: "bg-ink text-white hover:bg-black",
      accent: "bg-lime text-ink hover:bg-lime-deep",
      ghost: "bg-white text-ink ring-1 ring-black/10 hover:bg-black/[.03]",
      soft: "bg-black/5 text-ink hover:bg-black/10",
      link: "text-ink-soft underline underline-offset-2 hover:text-ink px-0 py-0 font-medium",
    };
    return <button className={base + " " + (variants[variant] || variants.primary) + " " + className} {...rest}>{children}</button>;
  };

  const Card = ({ accent = "", className = "", children }: any) => (
    <div className={"rounded-3xl bg-white shadow-card " + (accent ? "border-l-4 " + accent : "") + " " + className}>
      {children}
    </div>
  );

  const Label = ({ children, hint }: any) => (
    <div className="mb-2 flex items-baseline gap-2">
      <span className="text-[13px] font-bold text-ink">{children}</span>
      {hint ? <span className="text-xs font-medium text-ink-mute">{hint}</span> : null}
    </div>
  );

  const inputCls = "w-full rounded-2xl border-0 bg-black/[.04] px-3.5 py-2.5 text-sm font-medium text-ink placeholder:text-ink-mute placeholder:font-normal focus:bg-white focus:ring-2 focus:ring-ink outline-none transition";

  const Input = (props: any) => <input {...props} className={inputCls + " " + (props.className || "")} />;
  const Select = ({ children, ...rest }: any) => (
    <select {...rest} className={inputCls + " pr-8 " + (rest.className || "")}>{children}</select>
  );
  const Textarea = (props: any) => (
    <textarea {...props} className={inputCls + " leading-relaxed " + (props.className || "")} />
  );

  const ConfidenceBar = ({ value }: { value: number }) => {
    const tone = T.confidenceTone(value);
    return (
      <div className="flex items-center gap-2" title="Уверенность модели в том, что это реальное обязательство">
        <div className="h-1.5 w-12 overflow-hidden rounded-full bg-black/10">
          <div className={"h-full rounded-full " + tone.bar} style={{ width: Math.max(6, Math.round(value * 100)) + "%" }} />
        </div>
        <span className="text-[11px] font-bold tabular-nums text-ink-soft">{T.pct(value)}</span>
      </div>
    );
  };

  // Источник решения — главное для доверия: цитата всегда доступна в один клик.
  const Evidence = ({ quote, verified }: { quote: string; verified: boolean }) => {
    const [open, setOpen] = useState(false);
    if (!quote) return null;
    return (
      <div className="mt-3">
        <button onClick={() => setOpen(!open)}
          className="inline-flex items-center gap-1.5 text-xs font-medium text-ink-soft hover:text-ink">
          <span className="text-slate-400">{open ? "▾" : "▸"}</span>
          Источник в транскрипции
          {verified
            ? <span className="text-emerald-600" title="Цитата найдена в транскрипции">✓ сверено</span>
            : <span className="text-rose-600" title="Цитату не удалось найти в транскрипции">⚠ не найдено</span>}
        </button>
        {open ? (
          <blockquote className={"fade-in mt-2 border-l-2 pl-3 text-sm italic leading-relaxed "
            + (verified ? "border-slate-300 text-ink-soft" : "border-rose-300 text-rose-700")}>
            «{quote}»
          </blockquote>
        ) : null}
      </div>
    );
  };

  const Warnings = ({ items }: { items: string[] }) => {
    if (!items || !items.length) return null;
    return (
      <ul className="mt-3 space-y-1 rounded-lg bg-amber-50 px-3 py-2 text-xs text-amber-900 ring-1 ring-amber-200">
        {items.map((w, i) => <li key={i}>⚠ {w}</li>)}
      </ul>
    );
  };

  // ---- редакторы формы

  const TeamEditor = ({ people, onChange, accent, withLogin }: any) => (
    <div className="space-y-2">
      {people.map((p: any, i: number) => (
        <div key={i} className="flex items-center gap-2">
          <span className={"h-1.5 w-1.5 shrink-0 rounded-full " + accent} />
          <Input value={p.name} placeholder="Имя" className="flex-1"
            onChange={(e: any) => onChange(people.map((x: any, j: number) => j === i ? { ...x, name: e.target.value } : x))} />
          <Input value={p.role} placeholder="Роль" className="flex-1"
            onChange={(e: any) => onChange(people.map((x: any, j: number) => j === i ? { ...x, role: e.target.value } : x))} />
          {withLogin ? (
            <Input value={p.login || ""} placeholder="логин в трекере" list="tracker-users" className="flex-1"
              onChange={(e: any) => onChange(people.map((x: any, j: number) => j === i ? { ...x, login: e.target.value } : x))} />
          ) : null}
          <button title="Убрать" className="px-1.5 text-ink-mute hover:text-rose-600"
            onClick={() => onChange(people.filter((_: any, j: number) => j !== i))}>×</button>
        </div>
      ))}
      <Button variant="link" onClick={() => onChange([...people, { name: "", role: "" }])}>+ участник</Button>
    </div>
  );

  const ExistingTasksEditor = ({ tasks, onChange }: any) => {
    // задач из трекера бывают десятки — по умолчанию показываем сводку, а не простыню
    const [open, setOpen] = useState(false);
    const patch = (i: number, field: string, value: string) =>
      onChange(tasks.map((x: any, j: number) => j === i ? { ...x, [field]: value } : x));

    if (!open) {
      return (
        <div>
          {tasks.length ? (
            <div className="max-h-40 space-y-1 overflow-y-auto pr-1">
              {tasks.map((t: any, i: number) => (
                <div key={i} className="flex gap-2 text-xs leading-snug">
                  <span className="mono shrink-0 font-semibold text-ink-soft">{t.id}</span>
                  <span className="min-w-0 flex-1 truncate text-ink-mute" title={t.title}>{t.title}</span>
                </div>
              ))}
            </div>
          ) : <p className="text-sm text-ink-mute">Пока пусто — загрузите из трекера или добавьте вручную.</p>}
          <div className="mt-2 flex items-center gap-3">
            <Button variant="link" onClick={() => setOpen(true)}>
              {tasks.length ? "редактировать список (" + tasks.length + ")" : "добавить вручную"}
            </Button>
            {tasks.length ? <Button variant="link" onClick={() => onChange([])}>очистить</Button> : null}
          </div>
        </div>
      );
    }

    return (
      <div>
        <div className="max-h-72 space-y-2 overflow-y-auto pr-1">
          {tasks.map((t: any, i: number) => (
            <div key={i} className="rounded-lg bg-slate-50 p-2 ring-1 ring-slate-200">
              <div className="flex items-center gap-2">
                <Input value={t.id} placeholder="SMART-124" className="mono w-36"
                  onChange={(e: any) => patch(i, "id", e.target.value)} />
                <button title="Убрать" className="ml-auto px-1.5 text-ink-mute hover:text-rose-600"
                  onClick={() => onChange(tasks.filter((_: any, j: number) => j !== i))}>×</button>
              </div>
              <Input value={t.title} placeholder="Название существующей задачи" className="mt-1.5"
                onChange={(e: any) => patch(i, "title", e.target.value)} />
            </div>
          ))}
        </div>
        <div className="mt-2 flex items-center gap-3">
          <Button variant="link" onClick={() => onChange([...tasks, { id: "", title: "", description: "" }])}>+ задача</Button>
          <Button variant="link" onClick={() => setOpen(false)}>свернуть</Button>
        </div>
      </div>
    );
  };

  const Collapsible = ({ title, hint, defaultOpen = false, children }: any) => {
    const [open, setOpen] = useState(defaultOpen);
    return (
      <Card className="overflow-hidden">
        <button onClick={() => setOpen(!open)}
          className="flex w-full items-center justify-between px-5 py-4 text-left">
          <span>
            <span className="text-[15px] font-bold text-ink">{title}</span>
            {hint ? <span className="ml-2 text-[13px] font-medium text-ink-mute">{hint}</span> : null}
          </span>
          <span className={"text-ink-mute transition " + (open ? "rotate-90" : "")}>›</span>
        </button>
        {open ? <div className="fade-in border-t border-black/5 px-5 py-4">{children}</div> : null}
      </Card>
    );
  };

  const Row = ({ title, hint, right, onClick }: any) => (
    <button onClick={onClick}
      className="flex w-full items-center justify-between gap-3 rounded-2xl bg-black/[.04] px-4 py-3 text-left transition hover:bg-black/[.07]">
      <span className="min-w-0">
        <span className="block truncate text-[14px] font-semibold text-ink">{title}</span>
        {hint ? <span className="block truncate text-xs font-medium text-ink-mute">{hint}</span> : null}
      </span>
      <span className="shrink-0 text-xs font-semibold text-ink-mute">{right}</span>
    </button>
  );

  const GlossaryEditor = ({ terms, onChange }: any) => (
    <div className="space-y-2">
      {terms.map((t: any, i: number) => (
        <div key={i} className="flex items-center gap-2">
          <Input value={t.wrong || ""} placeholder="как слышится" className="flex-1"
            onChange={(e: any) => onChange(terms.map((x: any, j: number) => j === i ? { ...x, wrong: e.target.value } : x))} />
          <span className="shrink-0 text-ink-mute">→</span>
          <Input value={t.right || ""} placeholder="как правильно" className="flex-1"
            onChange={(e: any) => onChange(terms.map((x: any, j: number) => j === i ? { ...x, right: e.target.value } : x))} />
          <button title="Убрать" className="px-1.5 text-ink-mute hover:text-rose-600"
            onClick={() => onChange(terms.filter((_: any, j: number) => j !== i))}>×</button>
        </div>
      ))}
      <Button variant="link" onClick={() => onChange([...terms, { wrong: "", right: "" }])}>+ термин</Button>
    </div>
  );

  const QueuePicker = ({ tracker, queues, selected, onChange, onLoadIssues, loading, loadedCount,
                         hints, onHintChange, onHintsSave }: any) => {
    if (!tracker) return null;
    if (!tracker.configured) {
      return (
        <div className="text-sm text-ink-soft">
          <Badge tone="slate">Трекер не подключён</Badge>
          <p className="mt-2 text-xs leading-relaxed text-ink-mute">
            {tracker.error || "Задайте TRACKER_PROVIDER, токен и идентификатор организации в .env."}
          </p>
        </div>
      );
    }
    const toggle = (key: string) =>
      onChange(selected.indexOf(key) >= 0 ? selected.filter((k: string) => k !== key) : selected.concat([key]));
    return (
      <div>
        <div className="flex flex-wrap items-center gap-2">
          <Badge tone="emerald">Трекер: {tracker.provider}</Badge>
          {tracker.dry_run ? <Badge tone="amber" title="Задачи не создаются, показывается тело запроса">dry-run</Badge>
                           : <Badge tone="rose" title="Задачи создаются по-настоящему">боевой режим</Badge>}
          {tracker.user ? <span className="text-xs text-ink-mute">{tracker.user}</span> : null}
        </div>
        <div className="mt-3 max-h-56 space-y-1 overflow-y-auto pr-1">
          {queues.map((q: any) => (
            <label key={q.key} className="flex cursor-pointer items-start gap-2 rounded-lg px-2 py-1.5 hover:bg-slate-50">
              <input type="checkbox" checked={selected.indexOf(q.key) >= 0} onChange={() => toggle(q.key)}
                className="mt-0.5 h-[18px] w-[18px] shrink-0 cursor-pointer rounded-md border-black/20 accent-ink" />
              <span className="min-w-0 flex-1">
                <span className="mono text-xs font-semibold">{q.key}</span>
                <span className="text-sm text-ink"> {q.name}</span>
                <input
                  value={(hints && hints[q.key]) || ""}
                  placeholder="что кладём в эту очередь — подсказка для AI"
                  onClick={(e: any) => e.preventDefault()}
                  onChange={(e: any) => onHintChange(q.key, e.target.value)}
                  onBlur={onHintsSave}
                  className="mt-1 w-full rounded-md border-0 bg-slate-50 px-2 py-1 text-xs text-ink-soft ring-1 ring-slate-200 placeholder:text-ink-mute focus:bg-white focus:ring-2 focus:ring-blue-500 outline-none" />
              </span>
            </label>
          ))}
          {!queues.length ? <p className="text-sm text-ink-mute">Очереди не найдены.</p> : null}
        </div>
        <p className="mt-3 text-xs font-medium leading-relaxed text-ink-mute">
          Задачи из этих очередей подтягиваются автоматически — по ним ищутся совпадения,
          чтобы не заводить то, что уже заведено.
        </p>
      </div>
    );
  };

  (window as any).UI = {
    Badge, Button, Card, Label, Input, Select, Textarea,
    ConfidenceBar, Evidence, Warnings, TeamEditor, ExistingTasksEditor, QueuePicker,
    Collapsible, Row, GlossaryEditor, inputCls,
  };
})();
