import { useEffect, useState } from "react";
import { useParams, useNavigate } from "react-router-dom";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import {
  getInspection,
  deleteInspection,
  patchInspection,
  type MarkerSummary,
  type PhotoSummary,
} from "@/api/inspections";
import { getMe } from "@/api/me";
import { AuthImg } from "@/components/AuthImg";
import { ttImageUrl } from "@/api/vehicles";
import { VendorVehicleScheme } from "@/components/vehicle-scheme/VendorVehicleScheme";
import { Card } from "@/components/ui/card";
import { loadZoneLabels } from "@/data/zoneLabels";

const STATUS_LABELS: Record<string, string> = {
  in_progress: "В работе",
  completed: "Завершён",
  cancelled: "Отменён",
};

const SEVERITY_LABELS: Record<string, string> = {
  cosmetic: "косметика",
  minor: "лёгкое",
  moderate: "среднее",
  severe: "тяжёлое",
};

const DAMAGE_TYPE_LABELS: Record<string, string> = {
  damaged: "повреждено",
  scratch: "царапина",
  chip: "скол",
  dent: "вмятина",
  crack: "трещина",
  scuff: "затёртость",
  burn: "прожог",
  stain: "пятно",
  bent: "погнуто",
  torn: "порвано",
  cut: "порез",
  puncture: "прокол",
  bulge: "грыжа",
  missing: "отсутствует",
  removed: "снято",
  "not-working": "не работает",
};

function humanizeMarkerSide(
  side: string | null | undefined,
  zoneLabels?: Record<string, string> | null,
): string {
  if (!side) return "—";
  if (side === "tires") return "Резина";
  const zm = /^zone-(\d+)$/.exec(side);
  if (zm) {
    const label = zoneLabels?.[zm[1]];
    if (label) return label;
    return `Зона ${zm[1]}`;
  }
  const map: Record<string, string> = {
    top: "Сверху",
    front: "Перед",
    back: "Зад",
    left: "Левый",
    right: "Правый",
    "bumper-fl": "Бампер ПЛ",
    "bumper-fr": "Бампер ПП",
    "bumper-rl": "Бампер ЗЛ",
    "bumper-rr": "Бампер ЗП",
    // Legacy named zone-* support (data from earlier prod)
    "zone-front": "Передний бампер",
    "zone-rear": "Задний бампер",
    "zone-left": "Левый бок",
    "zone-right": "Правый бок",
    "zone-hood": "Капот",
    "zone-trunk": "Багажник",
    "zone-roof": "Крыша",
  };
  return map[side] ?? side;
}

export default function InspectionReview() {
  const { id } = useParams<{ id: string }>();
  const insId = Number(id);
  const navigate = useNavigate();

  const { data: ins, isLoading, isError } = useQuery({
    queryKey: ["inspection", insId],
    queryFn: () => getInspection(insId),
  });

  const { data: me } = useQuery({
    queryKey: ["me"],
    queryFn: getMe,
    staleTime: 5 * 60_000,
  });
  const isAdmin = me?.permissions?.includes("admin") ?? false;

  const queryClient = useQueryClient();
  const deleteMutation = useMutation({
    mutationFn: () => deleteInspection(insId),
    onSuccess: () => {
      toast.success("Осмотр удалён");
      queryClient.invalidateQueries({ queryKey: ["vehicle"] });
      navigate(-1);
    },
    onError: () => toast.error("Не удалось удалить осмотр"),
  });

  const { data: zoneLabels } = useQuery({
    queryKey: ["zone-labels"],
    queryFn: loadZoneLabels,
    staleTime: Infinity,
  });

  // Lightbox: либо ID нашего фото в MinIO (через AuthImg), либо vendor TT
  // image hash (через ttImageUrl).
  const [preview, setPreview] = useState<
    { kind: "photo"; id: number } | { kind: "tt"; ttId: string } | null
  >(null);

  // Локальный draft заметок — синхронизируется с ins.notes при загрузке/обновлении.
  // Кнопка «Сохранить» появляется только если draft отличается от сохранённого.
  const [notesDraft, setNotesDraft] = useState<string>("");
  useEffect(() => {
    if (ins?.notes !== undefined) setNotesDraft(ins.notes ?? "");
  }, [ins?.notes]);

  const notesMutation = useMutation({
    mutationFn: (next: string) => patchInspection(insId, { notes: next }),
    onSuccess: (updated) => {
      toast.success("Заметка сохранена");
      queryClient.setQueryData(["inspection", insId], updated);
    },
    onError: () => toast.error("Не удалось сохранить заметку"),
  });

  if (isLoading) return <div className="p-8 text-muted-foreground">Загружаю…</div>;
  if (isError || !ins)
    return <div className="p-8 text-destructive">Осмотр не найден.</div>;

  const notesDirty = (notesDraft ?? "") !== (ins.notes ?? "");

  // Lookup photo by id для определения annotated_key.
  const photosById = new Map<number, typeof ins.photos[0]>();
  for (const p of ins.photos) photosById.set(p.id, p);

  // Все уникальные фото осмотра: основные + photo_id из маркеров (наши локальные
  // фото повреждений) + tt_image_id из маркеров (carry-over из Element). Без
  // tt_image_id counter недоучитывал импортированные дефекты — видно на
  // осмотрах, где почти все маркеры пришли из вендора.
  const markerPhotoIds = ins.markers
    .map((m: MarkerSummary) => m.photo_id)
    .filter((id): id is number => id != null);
  const markerTtIds = ins.markers
    .map((m: MarkerSummary) => m.tt_image_id)
    .filter((id): id is string => !!id);
  const uniquePhotoIds = Array.from(
    new Set([...ins.photos.map((p: PhotoSummary) => p.id), ...markerPhotoIds])
  );
  const uniqueTtIds = Array.from(new Set(markerTtIds));
  const totalPhotoCount = uniquePhotoIds.length + uniqueTtIds.length;
  // Дополнительные фото-карточки в галерее: photo_id маркеров, которых нет в
  // основном списке (`ins.photos` — это side-photos осмотра).
  const extraMarkerPhotos = markerPhotoIds.filter((id) => !photosById.has(id));

  return (
    <div className="min-h-screen bg-background p-4 space-y-4">
      <button
        onClick={() => navigate(-1)}
        className="text-sm text-muted-foreground hover:text-foreground"
      >
        ← Назад
      </button>

      <h1 className="text-xl font-semibold">Осмотр #{ins.id}</h1>

      {ins.vehicle && (
        <Card
          className="p-4 text-sm space-y-1 cursor-pointer hover:bg-accent/40 transition-colors"
          onClick={() => navigate(`/vehicles/${ins.vehicle?.id}`)}
        >
          <div className="text-lg font-semibold tracking-wide">
            {ins.vehicle.license_plate}
          </div>
          <div className="text-muted-foreground">
            {[ins.vehicle.make, ins.vehicle.model, ins.vehicle.year]
              .filter(Boolean)
              .join(" · ") || "—"}
          </div>
          {ins.vehicle.vin && (
            <div className="text-xs text-muted-foreground">
              <span className="font-semibold">VIN: </span>
              {ins.vehicle.vin}
            </div>
          )}
        </Card>
      )}

      <Card className="p-4 text-sm space-y-1">
        <div>
          <span className="font-semibold">Тип: </span>
          {ins.type}
        </div>
        <div>
          <span className="font-semibold">Статус: </span>
          {STATUS_LABELS[ins.status] ?? ins.status}
        </div>
        {ins.inspector_name && (
          <div>
            <span className="font-semibold">Механик: </span>
            {ins.inspector_name}
          </div>
        )}
        <div>
          <span className="font-semibold">Начат: </span>
          {new Date(ins.started_at).toLocaleString("ru-RU")}
        </div>
        {ins.finished_at && (
          <div>
            <span className="font-semibold">Завершён: </span>
            {new Date(ins.finished_at).toLocaleString("ru-RU")}
          </div>
        )}
        {ins.mileage != null && (
          <div>
            <span className="font-semibold">Пробег: </span>
            {ins.mileage.toLocaleString("ru-RU")} км
          </div>
        )}
      </Card>

      <Card className="p-4 space-y-2">
        <h2 className="text-sm font-semibold text-muted-foreground">
          Заметки механика
        </h2>
        <textarea
          value={notesDraft}
          onChange={(e) => setNotesDraft(e.target.value)}
          placeholder="Текст осмотра, замечания, рекомендации…"
          rows={Math.max(3, Math.min(notesDraft.split("\n").length + 1, 12))}
          className="w-full text-sm p-2 rounded border border-input bg-background resize-y focus:outline-none focus:ring-2 focus:ring-ring"
        />
        {notesDirty && (
          <div className="flex gap-2 justify-end">
            <button
              type="button"
              onClick={() => setNotesDraft(ins.notes ?? "")}
              className="text-xs text-muted-foreground hover:text-foreground px-3 py-1"
              disabled={notesMutation.isPending}
            >
              Отменить
            </button>
            <button
              type="button"
              onClick={() => notesMutation.mutate(notesDraft)}
              disabled={notesMutation.isPending}
              className="text-xs bg-primary text-primary-foreground rounded px-3 py-1 disabled:opacity-60"
            >
              {notesMutation.isPending ? "Сохраняю…" : "Сохранить"}
            </button>
          </div>
        )}
      </Card>

      <Card className="p-4">
        <h2 className="text-sm font-semibold text-muted-foreground mb-3">
          Схема повреждений
        </h2>
        <VendorVehicleScheme
          markers={ins.markers.map((m: MarkerSummary) => ({
            id: m.id,
            side: m.side,
            damage_type: m.damage_type,
            severity: m.severity,
            resolved: m.resolved,
            polygon: m.polygon,
          }))}
          editable={false}
        />
      </Card>

      <div>
        <h2 className="text-sm font-semibold text-muted-foreground mb-2">
          Фото ({totalPhotoCount})
        </h2>
        {totalPhotoCount === 0 ? (
          <div className="text-sm text-muted-foreground">Нет фото.</div>
        ) : (
          <div className="grid grid-cols-2 gap-2">
            {ins.photos.map((p: PhotoSummary) => (
              <Card
                key={p.id}
                className="overflow-hidden cursor-pointer"
                onClick={() => setPreview({ kind: "photo", id: p.id })}
              >
                <AuthImg
                  src={`photos/${p.id}/thumb`}
                  alt={p.side}
                  className="w-full aspect-[4/3] object-cover bg-muted"
                />
                <div className="text-xs text-muted-foreground p-2">{p.side}</div>
              </Card>
            ))}
            {/* Фото-маркеров, которых нет в основном списке (наши локальные) */}
            {extraMarkerPhotos.map((id) => (
              <Card
                key={`m-${id}`}
                className="overflow-hidden cursor-pointer"
                onClick={() => setPreview({ kind: "photo", id })}
              >
                <AuthImg
                  src={`photos/${id}/thumb`}
                  alt="повреждение"
                  className="w-full aspect-[4/3] object-cover bg-muted"
                />
                <div className="text-xs text-muted-foreground p-2">повреждение</div>
              </Card>
            ))}
            {/* TT-фото carry-over дефектов из Element живут ТОЛЬКО внутри
                секции «Метки», чтобы не дублировать одну и ту же картинку
                в карточке два раза. В счётчике «Фото (N)» они учтены. */}
          </div>
        )}
      </div>

      <div>
        <h2 className="text-sm font-semibold text-muted-foreground mb-2">
          Метки ({ins.markers.length})
        </h2>
        {ins.markers.length === 0 ? (
          <div className="text-sm text-muted-foreground">Нет меток.</div>
        ) : (
          <ul className="space-y-1">
            {ins.markers.map((m: MarkerSummary) => (
              <li key={m.id}>
                <Card className="p-3 text-sm">
                  <div className="flex items-center justify-between">
                    <div>
                      <span className="font-medium capitalize">
                        {humanizeMarkerSide(m.side, zoneLabels)}
                      </span>
                      {" — "}
                      <span>
                        {m.damage_type
                          ? (DAMAGE_TYPE_LABELS[m.damage_type] ?? m.damage_type)
                          : "—"}
                      </span>
                      {m.severity && (
                        <>
                          {" — "}
                          <span className="text-muted-foreground">
                            {SEVERITY_LABELS[m.severity] ?? m.severity}
                          </span>
                        </>
                      )}
                    </div>
                    <div className="flex items-center gap-2">
                      {m.resolved && (
                        <span className="text-xs text-muted-foreground">
                          устранено
                        </span>
                      )}
                      {m.carried_over_from_id && (
                        <span className="text-xs text-muted-foreground">
                          перенесено
                        </span>
                      )}
                    </div>
                  </div>
                  {m.description && (
                    <div className="text-xs text-muted-foreground mt-1">
                      {m.description}
                    </div>
                  )}
                  {m.photo_id ? (
                    <div
                      className="mt-2 max-w-[8rem] cursor-pointer"
                      onClick={() =>
                        setPreview({ kind: "photo", id: m.photo_id as number })
                      }
                    >
                      <AuthImg
                        src={
                          photosById.get(m.photo_id)?.annotated_key
                            ? `photos/${m.photo_id}/annotated`
                            : `photos/${m.photo_id}/thumb`
                        }
                        alt="Фото повреждения"
                        className="w-full aspect-[4/3] object-cover rounded bg-muted"
                      />
                    </div>
                  ) : m.tt_image_id ? (
                    <div
                      className="mt-2 max-w-[8rem] cursor-pointer"
                      onClick={() =>
                        setPreview({ kind: "tt", ttId: m.tt_image_id as string })
                      }
                    >
                      <img
                        src={ttImageUrl(m.tt_image_id)}
                        alt="Фото из Element Mechanic"
                        loading="lazy"
                        className="w-full aspect-[4/3] object-cover rounded bg-muted"
                      />
                    </div>
                  ) : null}
                </Card>
              </li>
            ))}
          </ul>
        )}
      </div>
      {isAdmin && (
        <div className="pt-4">
          <button
            onClick={() => {
              if (
                window.confirm(
                  "Удалить этот осмотр? Все фото будут безвозвратно удалены из хранилища. Действие необратимо."
                )
              ) {
                deleteMutation.mutate();
              }
            }}
            disabled={deleteMutation.isPending}
            className="w-full py-3 rounded-lg border border-destructive text-destructive hover:bg-destructive/10 active:bg-destructive/20 transition-colors font-semibold"
          >
            {deleteMutation.isPending ? "Удаляю…" : "Удалить осмотр"}
          </button>
        </div>
      )}

      {/* Lightbox preview — click photo to enlarge, click background to close.
          Соответствует UX в TtStateDetail (импортированные из Element осмотры). */}
      {preview != null && (
        <div
          className="fixed inset-0 z-50 bg-black/90 flex flex-col"
          onClick={() => setPreview(null)}
        >
          <div className="flex items-center justify-between p-3">
            <button
              onClick={(e) => {
                e.stopPropagation();
                setPreview(null);
              }}
              className="text-white text-2xl px-3"
            >
              ✕
            </button>
          </div>
          <div
            className="flex-1 flex items-center justify-center p-4"
            onClick={(e) => e.stopPropagation()}
          >
            {preview.kind === "photo" ? (
              <AuthImg
                src={`photos/${preview.id}`}
                alt="Просмотр"
                className="max-w-full max-h-full object-contain"
              />
            ) : (
              <img
                src={ttImageUrl(preview.ttId)}
                alt="Просмотр (Element)"
                className="max-w-full max-h-full object-contain"
              />
            )}
          </div>
        </div>
      )}
    </div>
  );
}
