/**
 * Правка ремонта в 1-часовом окне (У49).
 *
 * Минимальная версия: редактируются работы (имя из каталога + цена +
 * ручная правка + комментарий), запчасти, замена масла, пробег. Фото
 * НЕ редактируются — для смены фото нужно дождаться PR-9.
 */
import { useEffect, useMemo, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { ChevronLeft, Plus, Trash2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  getRepairDetail,
  patchRepair,
  type RepairDetailResponse,
} from "@/api/repairsFeed";
import { searchWorks, suggestParts, type MechWork } from "@/api/repairsCreate";
import WorksPickerModal from "@/components/repairs/WorksPickerModal";
import MechanicsField, { type SelectedMechanic } from "@/components/repairs/MechanicsField";

interface WorkRow {
  rowKey: string;
  work_catalog_id: number;
  name: string;
  price_catalog: number;
  price_applied: number;
  manual_override: boolean;
  override_comment: string | null;
}

interface PartRow {
  rowKey: string;
  name: string;
  qty: number;
}

interface OilState {
  enabled: boolean;
  next_in_km: number | null;
}

function uid(): string {
  return Math.random().toString(36).slice(2, 10);
}

function fmt(n: number): string {
  return new Intl.NumberFormat("ru-RU", { maximumFractionDigits: 0 }).format(Math.round(n));
}

export default function EditRepairPage() {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const [detail, setDetail] = useState<RepairDetailResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Form state.
  const [mileage, setMileage] = useState<number | null>(null);
  const [works, setWorks] = useState<WorkRow[]>([]);
  const [parts, setParts] = useState<PartRow[]>([]);
  const [oil, setOil] = useState<OilState>({ enabled: false, next_in_km: null });
  // Работавшие механики (делёж 1/N).
  const [mechanics, setMechanics] = useState<SelectedMechanic[]>([]);

  const [worksPicker, setWorksPicker] = useState<{ open: boolean; q: string; results: MechWork[] }>(
    { open: false, q: "", results: [] }
  );
  const [overrideModal, setOverrideModal] = useState<{ rowKey: string; comment: string } | null>(null);

  useEffect(() => {
    if (!id) return;
    setLoading(true);
    getRepairDetail(Number(id))
      .then((d) => {
        setDetail(d);
        setMileage(d.mileage);
        setWorks(d.works.map((w) => ({
          rowKey: uid(),
          work_catalog_id: w.work_catalog_id,
          name: w.name,
          price_catalog: w.price_applied,  // в payload мы не знаем catalog price отдельно — фронт хранит applied; PATCH перечитает из БД каталога
          price_applied: w.price_applied,
          manual_override: w.manual_override,
          override_comment: w.override_comment,
        })));
        setParts(d.parts.map((p) => ({
          rowKey: uid(), name: p.name, qty: p.qty,
        })));
        if (d.oil_change) {
          setOil({
            enabled: true,
            next_in_km: d.oil_change.next_in_km,
          });
        }
        // Механики: из списка работавших; fallback — создатель (старые ответы).
        if (d.mechanics && d.mechanics.length > 0) {
          setMechanics(d.mechanics.map((m) => ({ mechanic_id: m.mechanic_id, name: m.name })));
        } else if (d.mechanic_name) {
          // Нет id создателя в payload — оставляем имя без id-сопоставления;
          // если механик ничего не трогает, mechanic_ids не отправим.
          setMechanics([]);
        }
        if (!d.can_edit) {
          setError("Окно правки закрыто. Изменения отправить нельзя.");
        }
      })
      .catch((e: Error) => setError(e.message || "Не удалось загрузить ремонт"))
      .finally(() => setLoading(false));
  }, [id]);

  const totalSum = useMemo(() => works.reduce((s, w) => s + (w.price_applied || 0), 0), [works]);

  // Works picker — поиск по каталогу.
  const openWorksPicker = async () => {
    setWorksPicker({ open: true, q: "", results: [] });
    const list = await searchWorks("");
    setWorksPicker((s) => ({ ...s, results: list }));
  };
  const queryWorks = async (q: string) => {
    setWorksPicker((s) => ({ ...s, q }));
    const list = await searchWorks(q);
    setWorksPicker((s) => ({ ...s, results: list }));
  };
  const pickWork = (mw: MechWork) => {
    const p = Math.round(Number(mw.price));
    setWorks((arr) => [...arr, {
      rowKey: uid(),
      work_catalog_id: mw.id,
      name: mw.name,
      price_catalog: p,
      price_applied: p,
      manual_override: false,
      override_comment: null,
    }]);
    setWorksPicker({ open: false, q: "", results: [] });
  };

  // Override-цена: открываем модалку для комментария.
  const startOverride = (rowKey: string) => {
    const cur = works.find((w) => w.rowKey === rowKey);
    setOverrideModal({ rowKey, comment: cur?.override_comment ?? "" });
  };
  const confirmOverride = (newPrice: number) => {
    if (!overrideModal) return;
    setWorks((arr) => arr.map((w) =>
      w.rowKey === overrideModal.rowKey
        ? { ...w, price_applied: newPrice, manual_override: true, override_comment: overrideModal.comment }
        : w
    ));
    setOverrideModal(null);
  };

  const submit = async () => {
    if (!detail) return;
    setError(null);

    // Валидация: каждый manual_override → комментарий.
    for (const w of works) {
      if (w.manual_override && !(w.override_comment || "").trim()) {
        setError(`У работы «${w.name}» включена ручная правка цены, но не указан комментарий`);
        return;
      }
    }
    if (works.length === 0) {
      setError("Минимум одна работа в ремонте");
      return;
    }
    // Механики были загружены, но пользователь убрал всех — backend отклонит
    // пустой список, перехватываем заранее с понятным текстом.
    if ((detail.mechanics?.length ?? 0) > 0 && mechanics.length === 0) {
      setError("Минимум один механик в ремонте");
      return;
    }

    setSaving(true);
    try {
      await patchRepair(detail.id, {
        mileage,
        works: works.map((w) => ({
          work_catalog_id: w.work_catalog_id,
          price_applied: Math.round(w.price_applied),
          manual_override: w.manual_override,
          override_comment: w.manual_override ? (w.override_comment ?? "").trim() : null,
        })),
        parts: parts.filter((p) => p.name.trim().length > 0).map((p) => ({
          name: p.name.trim(),
          qty: p.qty,
        })),
        oil_change: oil.enabled
          // Один источник истины — главный пробег ремонта.
          ? { enabled: true, mileage_at_change: mileage, next_in_km: oil.next_in_km }
          : { enabled: false, mileage_at_change: null, next_in_km: null },
        // Список механиков отправляем, только если он непуст (иначе бэк
        // оставит набор как есть; пустой бы вызвал ValueError).
        ...(mechanics.length > 0
          ? { mechanic_ids: mechanics.map((m) => m.mechanic_id) }
          : {}),
      });
      navigate(`/repairs/${detail.id}`, { replace: true });
    } catch (e) {
      setError((e as Error).message || "Не удалось сохранить");
      setSaving(false);
    }
  };

  return (
    <div className="min-h-screen bg-background">
      <header className="sticky top-0 z-10 border-b bg-background/95 backdrop-blur">
        <div className="flex items-center gap-3 p-3">
          <button
            onClick={() => navigate(-1)}
            className="rounded-full p-2 hover:bg-accent"
            aria-label="Назад"
          >
            <ChevronLeft className="h-5 w-5" />
          </button>
          <h1 className="flex-1 text-base font-semibold truncate">
            Правка ремонта {detail ? `#${detail.id}` : ""}
          </h1>
        </div>
      </header>

      <main className="p-4 space-y-5 pb-32">
        {loading && (
          <div className="text-sm text-muted-foreground text-center py-12">
            Загрузка…
          </div>
        )}
        {error && (
          <div className="text-sm text-destructive bg-destructive/10 rounded-md p-3">
            {error}
          </div>
        )}
        {detail && (
          <>
            {/* Шапка машины — read-only */}
            <section className="rounded-lg border bg-muted/40 p-4">
              <div className="text-lg font-bold font-mono">{detail.car_plate ?? "—"}</div>
              {(detail.car_make || detail.car_model) && (
                <div className="text-sm text-muted-foreground">{detail.car_make} {detail.car_model}</div>
              )}
              {detail.driver_name && (
                <div className="text-sm mt-1">
                  <span className="text-muted-foreground">Водитель: </span>
                  {detail.driver_name}
                </div>
              )}
            </section>

            {/* Пробег */}
            <section>
              <Label className="text-sm">Пробег, км</Label>
              <Input
                type="number"
                inputMode="numeric"
                value={mileage ?? ""}
                onChange={(e) => setMileage(e.target.value === "" ? null : Number(e.target.value))}
                className="mt-1"
              />
            </section>

            {/* Работы */}
            <section>
              <div className="flex items-baseline justify-between">
                <Label className="text-sm">Работы</Label>
                <span className="text-xs text-muted-foreground">
                  {works.length} {works.length === 1 ? "шт" : "шт"}
                </span>
              </div>
              <div className="mt-2 space-y-2">
                {works.map((w) => (
                  <div key={w.rowKey} className="border rounded-md p-3 bg-card">
                    <div className="flex items-start gap-2">
                      <div className="flex-1 min-w-0">
                        <div className="text-sm font-medium">{w.name}</div>
                        <div className="flex items-baseline gap-2 mt-1">
                          <span className="text-sm font-mono">
                            {fmt(w.price_applied)} ₽
                          </span>
                          {w.manual_override && (
                            <span className="text-xs text-amber-700">
                              ✎ ручная правка
                            </span>
                          )}
                          {w.manual_override && w.price_applied !== w.price_catalog && (
                            <span className="text-xs text-muted-foreground line-through">
                              {fmt(w.price_catalog)}
                            </span>
                          )}
                        </div>
                        {w.manual_override && w.override_comment && (
                          <div className="text-xs text-muted-foreground mt-1">
                            {w.override_comment}
                          </div>
                        )}
                      </div>
                      <button
                        onClick={() => startOverride(w.rowKey)}
                        className="rounded-full p-2 hover:bg-accent text-amber-700"
                        title="Изменить цену"
                      >
                        ✎
                      </button>
                      <button
                        onClick={() => setWorks((arr) => arr.filter((x) => x.rowKey !== w.rowKey))}
                        className="rounded-full p-2 hover:bg-accent text-destructive"
                        title="Удалить"
                      >
                        <Trash2 className="h-4 w-4" />
                      </button>
                    </div>
                  </div>
                ))}
                <button
                  onClick={openWorksPicker}
                  className="w-full border-2 border-dashed rounded-md py-2.5 text-sm hover:bg-accent/40 flex items-center justify-center gap-1.5"
                >
                  <Plus className="h-4 w-4" /> Добавить работу
                </button>
                <div className="flex items-baseline justify-between pt-2 border-t mt-2">
                  <span className="text-sm font-semibold">Итого</span>
                  <span className="text-base font-mono font-bold">{fmt(totalSum)} ₽</span>
                </div>
              </div>
            </section>

            {/* Механики (делёж 1/N) */}
            <MechanicsField value={mechanics} onChange={setMechanics} totalSum={totalSum} />

            {/* Запчасти */}
            <section>
              <div className="flex items-baseline justify-between">
                <Label className="text-sm">Запчасти (опционально)</Label>
                <span className="text-xs text-muted-foreground">{parts.length} шт</span>
              </div>
              <div className="mt-2 space-y-2">
                {parts.map((p) => (
                  <PartEditRow
                    key={p.rowKey}
                    name={p.name}
                    qty={p.qty}
                    onChange={(name, qty) =>
                      setParts((arr) => arr.map((x) => x.rowKey === p.rowKey ? { ...x, name, qty } : x))
                    }
                    onRemove={() => setParts((arr) => arr.filter((x) => x.rowKey !== p.rowKey))}
                  />
                ))}
                <button
                  onClick={() => setParts((arr) => [...arr, { rowKey: uid(), name: "", qty: 1 }])}
                  className="w-full border-2 border-dashed rounded-md py-2.5 text-sm hover:bg-accent/40 flex items-center justify-center gap-1.5"
                >
                  <Plus className="h-4 w-4" /> Добавить запчасть
                </button>
              </div>
            </section>

            {/* Замена масла */}
            <section className="border rounded-md p-3">
              <label className="flex items-center gap-2 text-sm font-medium">
                <input
                  type="checkbox"
                  checked={oil.enabled}
                  onChange={(e) => setOil((o) => ({ ...o, enabled: e.target.checked }))}
                />
                Замена масла
              </label>
              {oil.enabled && (
                <div className="mt-3">
                  <Label className="text-xs">Через, км</Label>
                  <Input
                    type="number"
                    inputMode="numeric"
                    value={oil.next_in_km ?? 10000}
                    onChange={(e) => setOil((o) => ({
                      ...o, next_in_km: e.target.value === "" ? null : Number(e.target.value),
                    }))}
                  />
                </div>
              )}
            </section>

            <div className="text-xs text-muted-foreground">
              Фото и стикер замены масла редактировать пока нельзя — для смены
              нужно создать новый ремонт.
            </div>
          </>
        )}
      </main>

      {/* Sticky footer */}
      {detail && (
        <footer className="fixed bottom-0 left-0 right-0 border-t bg-background p-3 flex gap-2 z-10">
          <Button variant="outline" onClick={() => navigate(`/repairs/${detail.id}`)} disabled={saving} className="flex-1">
            Отмена
          </Button>
          <Button onClick={submit} disabled={saving || !detail.can_edit} className="flex-1">
            {saving ? "Сохранение…" : "Сохранить"}
          </Button>
        </footer>
      )}

      {/* Works picker modal — общий компонент (см. WorksPickerModal) */}
      {worksPicker.open && (
        <WorksPickerModal
          query={worksPicker.q}
          results={worksPicker.results}
          onQuery={queryWorks}
          onPick={pickWork}
          onClose={() => setWorksPicker({ open: false, q: "", results: [] })}
        />
      )}

      {/* Override modal */}
      {overrideModal && (() => {
        const cur = works.find((w) => w.rowKey === overrideModal.rowKey);
        if (!cur) return null;
        return (
          <OverridePriceModal
            workName={cur.name}
            catalogPrice={cur.price_catalog}
            appliedPrice={cur.price_applied}
            initialComment={overrideModal.comment}
            onCancel={() => setOverrideModal(null)}
            onSubmit={(newPrice, comment) => {
              setOverrideModal((m) => m ? { ...m, comment } : m);
              confirmOverride(newPrice);
            }}
          />
        );
      })()}
    </div>
  );
}


function PartEditRow({ name, qty, onChange, onRemove }: {
  name: string;
  qty: number;
  onChange: (name: string, qty: number) => void;
  onRemove: () => void;
}) {
  const [suggestions, setSuggestions] = useState<string[]>([]);
  const [showSugg, setShowSugg] = useState(false);

  const fetchSuggestions = async (q: string) => {
    if (!q.trim()) { setSuggestions([]); return; }
    try {
      const r = await suggestParts(q);
      setSuggestions(r.map((x) => x.name));
    } catch { /* noop */ }
  };

  return (
    <div className="flex gap-2 items-start">
      <div className="flex-1 relative">
        <Input
          placeholder="Название запчасти"
          value={name}
          onChange={(e) => { onChange(e.target.value, qty); fetchSuggestions(e.target.value); setShowSugg(true); }}
          onFocus={() => name && fetchSuggestions(name)}
          onBlur={() => setTimeout(() => setShowSugg(false), 150)}
        />
        {showSugg && suggestions.length > 0 && (
          <div className="absolute top-full left-0 right-0 z-10 mt-1 bg-popover border rounded-md shadow-md max-h-48 overflow-auto">
            {suggestions.map((s) => (
              <button
                key={s}
                onClick={() => { onChange(s, qty); setShowSugg(false); }}
                className="w-full text-left px-3 py-2 text-sm hover:bg-accent"
              >
                {s}
              </button>
            ))}
          </div>
        )}
      </div>
      <Input
        type="number"
        inputMode="numeric"
        min={1}
        value={qty}
        onChange={(e) => onChange(name, Math.max(1, Number(e.target.value) || 1))}
        className="w-20"
      />
      <button onClick={onRemove} className="rounded-full p-2 hover:bg-accent text-destructive">
        <Trash2 className="h-4 w-4" />
      </button>
    </div>
  );
}


function OverridePriceModal({ workName, catalogPrice, appliedPrice, initialComment, onCancel, onSubmit }: {
  workName: string;
  catalogPrice: number;
  appliedPrice: number;
  initialComment: string;
  onCancel: () => void;
  onSubmit: (newPrice: number, comment: string) => void;
}) {
  const [price, setPrice] = useState(String(Math.round(appliedPrice)));
  const [comment, setComment] = useState(initialComment);

  return (
    <div className="fixed inset-0 z-50 bg-black/50 flex items-end justify-center" onClick={onCancel}>
      <div className="bg-background w-full max-w-md rounded-t-xl p-4 space-y-3" onClick={(e) => e.stopPropagation()}>
        <h3 className="text-base font-semibold">Изменить цену</h3>
        <div className="text-sm">
          <div className="font-medium">{workName}</div>
          <div className="text-xs text-muted-foreground mt-0.5">
            По каталогу: <span className="font-mono">{fmt(catalogPrice)} ₽</span>
          </div>
        </div>
        <div>
          <Label className="text-xs">Применённая цена, ₽</Label>
          <Input
            type="number"
            inputMode="numeric"
            value={price}
            onChange={(e) => setPrice(e.target.value)}
            autoFocus
          />
        </div>
        <div>
          <Label className="text-xs">Причина (обязательно)</Label>
          <textarea
            className="w-full mt-1 border rounded-md px-3 py-2 text-sm"
            rows={2}
            value={comment}
            onChange={(e) => setComment(e.target.value)}
            placeholder="Например: договорились с клиентом"
          />
        </div>
        <div className="flex gap-2 pt-2">
          <Button variant="outline" onClick={onCancel} className="flex-1">Отмена</Button>
          <Button
            disabled={!comment.trim() || !price}
            onClick={() => onSubmit(Number(price), comment.trim())}
            className="flex-1"
          >
            Применить
          </Button>
        </div>
      </div>
    </div>
  );
}
