import { useState, useMemo, useRef, useEffect } from "react";
import { useParams, useNavigate } from "react-router-dom";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import {
  getTtState,
  deleteTtState,
  ttImageUrl,
  type TtPhotoRef,
  type TtSidePhoto,
} from "@/api/vehicles";
import { getMe } from "@/api/me";
import { Card } from "@/components/ui/card";
import { TtDamageMap } from "@/components/tt/TtDamageMap";

interface ZoneLabels {
  [zoneId: string]: string;
}

interface DamageVocabulary {
  damage_types_ordered: string[];
  [k: string]: unknown;
}

let zoneLabelsCache: ZoneLabels | null = null;
let damageVocabCache: DamageVocabulary | null = null;

async function loadZoneLabels(): Promise<ZoneLabels> {
  if (zoneLabelsCache) return zoneLabelsCache;
  const res = await fetch("/data/zone_labels.json");
  zoneLabelsCache = await res.json();
  return zoneLabelsCache!;
}

async function loadDamageVocabulary(): Promise<DamageVocabulary> {
  if (damageVocabCache) return damageVocabCache;
  const res = await fetch("/data/damage_vocabulary.json");
  damageVocabCache = await res.json();
  return damageVocabCache!;
}

const DEGREE_LABELS: Record<number, string> = {
  0: "Лёгкое",
  1: "Среднее",
  2: "Тяжёлое",
};

function damageTypeName(
  id: number | null,
  vocab: DamageVocabulary | undefined,
): string {
  if (id == null) return "Без типа";
  // Vendor enum is 1-based: type=1 → damage_types_ordered[0] ("Вмятина").
  const idx = id - 1;
  const arr = vocab?.damage_types_ordered;
  if (arr && idx >= 0 && idx < arr.length) return arr[idx];
  return `Тип ${id}`;
}

const SIDE_LABELS: Record<number, string> = {
  1: "Перед",
  2: "Зад",
  3: "Левый борт",
  4: "Правый борт",
  5: "Сверху",
  6: "Передний угол",
  7: "Задний угол",
  8: "Салон",
  9: "Дополнительно",
};

type PreviewItem =
  | { kind: "zone"; photo: TtPhotoRef }
  | { kind: "side"; photo: TtSidePhoto };

export default function TtStateDetail() {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const stateId = Number(id);
  const zoneRefs = useRef<Record<string, HTMLDivElement | null>>({});

  const { data: state, isLoading, isError } = useQuery({
    queryKey: ["tt-state", stateId],
    queryFn: () => getTtState(stateId),
    enabled: Number.isFinite(stateId),
  });

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

  const { data: vocab } = useQuery({
    queryKey: ["damage-vocabulary"],
    queryFn: loadDamageVocabulary,
    staleTime: Infinity,
  });

  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: () => deleteTtState(stateId),
    onSuccess: () => {
      toast.success("Осмотр удалён");
      // Drop any cached tt-history for vehicle list so новый рендер не покажет удалённый.
      queryClient.invalidateQueries({ queryKey: ["vehicle"] });
      navigate(-1);
    },
    onError: () => toast.error("Не удалось удалить осмотр"),
  });

  const [preview, setPreview] = useState<PreviewItem | null>(null);
  const [showLines, setShowLines] = useState(false);

  const damagedZoneIds = useMemo(() => {
    if (!state) return [];
    return Object.keys(state.damages_by_zone).map((k) => Number(k));
  }, [state]);

  const damageOverlays = useMemo(() => {
    if (!state) return [];
    return Object.entries(state.damages_by_zone).flatMap(([zid, dmgs]) =>
      dmgs.map((d) => ({ zoneId: Number(zid), points: d.points || [] }))
    );
  }, [state]);

  // Reset refs when state changes
  useEffect(() => {
    zoneRefs.current = {};
  }, [stateId]);

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

  const date = state.unix_time
    ? new Date(state.unix_time * 1000).toLocaleString("ru-RU")
    : "—";

  const zoneIds = Array.from(
    new Set([
      ...Object.keys(state.photos_by_zone),
      ...Object.keys(state.damages_by_zone),
    ])
  ).sort((a, b) => Number(a) - Number(b));

  function scrollToZone(zoneId: number) {
    const el = zoneRefs.current[String(zoneId)];
    if (el) {
      el.scrollIntoView({ behavior: "smooth", block: "start" });
    }
  }

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

      <Card className="p-4">
        <div className="text-xs text-muted-foreground">Element Mechanic</div>
        <div className="text-lg font-semibold mt-1">
          {state.mechanic_name || "Осмотр"}
        </div>
        <div className="text-sm text-muted-foreground mt-1">
          {date}
          {state.mileage != null && (
            <> · {state.mileage.toLocaleString("ru-RU")} км</>
          )}
        </div>
      </Card>

      {/* Общие 9 ракурсов */}
      {state.side_photos.length > 0 && (
        <div>
          <h2 className="text-sm font-semibold text-muted-foreground mb-2">
            Общие фото
          </h2>
          <div className="grid grid-cols-3 gap-2">
            {state.side_photos.map((p) => {
              const label = p.photo_type
                ? SIDE_LABELS[p.photo_type] || `Ракурс ${p.photo_type}`
                : "Ракурс";
              const thumbSrc = p.miniature_id
                ? ttImageUrl(p.miniature_id)
                : ttImageUrl(p.image_id);
              return (
                <button
                  key={p.image_id}
                  onClick={() => {
                    setPreview({ kind: "side", photo: p });
                    setShowLines(false);
                  }}
                  className="aspect-square overflow-hidden rounded-lg bg-muted hover:opacity-80 transition-opacity relative"
                >
                  <img
                    src={thumbSrc}
                    alt={label}
                    loading="lazy"
                    className="w-full h-full object-cover"
                  />
                  <div className="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/60 to-transparent p-1">
                    <div className="text-white text-[10px] font-medium truncate">
                      {label}
                    </div>
                  </div>
                </button>
              );
            })}
          </div>
        </div>
      )}

      {/* Карта повреждений */}
      {damagedZoneIds.length > 0 && (
        <div>
          <h2 className="text-sm font-semibold text-muted-foreground mb-2">
            Карта повреждений
            <span className="ml-2 text-xs font-normal">
              {damagedZoneIds.length}{" "}
              {damagedZoneIds.length === 1 ? "зона" : "зон"}
            </span>
          </h2>
          <TtDamageMap
            damagedZoneIds={damagedZoneIds}
            damages={damageOverlays}
            onZoneClick={scrollToZone}
          />
          <div className="text-[11px] text-muted-foreground mt-1 text-center">
            Тап на зону — прокрутка к деталям
          </div>
        </div>
      )}

      {/* Детали по зонам с повреждениями */}
      {zoneIds.length === 0 ? (
        <Card className="p-4 text-sm text-muted-foreground">
          В осмотре нет ни фото, ни повреждений.
        </Card>
      ) : (
        zoneIds.map((zid) => {
          const photos = state.photos_by_zone[zid] || [];
          const damages = state.damages_by_zone[zid] || [];
          const label = labels?.[zid] || `Зона ${zid}`;
          return (
            <div
              key={zid}
              ref={(el) => {
                zoneRefs.current[zid] = el;
              }}
              className="scroll-mt-4"
            >
              <h2 className="text-sm font-semibold text-muted-foreground mb-2 capitalize flex items-center justify-between">
                <span>{label}</span>
                {damages.length > 0 && (
                  <span className="text-destructive text-xs">
                    ⚠ {damages.length}{" "}
                    {damages.length === 1 ? "повреждение" : "повреждений"}
                  </span>
                )}
              </h2>
              {damages.length > 0 && (
                <div className="flex flex-wrap gap-1.5 mb-2">
                  {damages.map((d, idx) => {
                    const tname = damageTypeName(d.damage_type_id, vocab);
                    const dname =
                      d.degree != null ? DEGREE_LABELS[d.degree] : null;
                    return (
                      <span
                        key={(d.guid ?? "g") + "_" + idx}
                        className="inline-flex items-center gap-1 text-xs px-2 py-0.5 rounded-full bg-destructive/10 text-destructive border border-destructive/30"
                      >
                        <span className="font-medium">{tname}</span>
                        {dname && (
                          <>
                            <span className="opacity-50">·</span>
                            <span>{dname}</span>
                          </>
                        )}
                      </span>
                    );
                  })}
                </div>
              )}
              {photos.length > 0 ? (
                <div className="grid grid-cols-3 gap-2">
                  {photos.map((p, idx) => (
                    <button
                      key={p.image_id + "_" + idx}
                      onClick={() => {
                        setPreview({ kind: "zone", photo: p });
                        setShowLines(false);
                      }}
                      className="aspect-square overflow-hidden rounded-lg bg-muted hover:opacity-80 transition-opacity"
                    >
                      <img
                        src={ttImageUrl(p.image_id)}
                        alt={`Зона ${zid}`}
                        loading="lazy"
                        className="w-full h-full object-cover"
                      />
                    </button>
                  ))}
                </div>
              ) : (
                <Card className="p-3 text-xs text-muted-foreground">
                  Фото нет — только координаты повреждений
                </Card>
              )}
            </div>
          );
        })
      )}

      {isAdmin && (
        <div className="pt-4">
          <button
            onClick={() => {
              if (
                window.confirm(
                  "Скрыть этот осмотр из истории? Будет помечен как игнорируемый — sync не вернёт. Действие обратимо только из БД."
                )
              ) {
                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>
      )}

      {preview && (
        <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>
            {preview.kind === "zone" &&
              preview.photo.image_with_lines_id && (
                <button
                  onClick={(e) => {
                    e.stopPropagation();
                    setShowLines((v) => !v);
                  }}
                  className="text-white text-sm border border-white/40 px-3 py-1 rounded-lg"
                >
                  {showLines ? "Без линий" : "С линиями"}
                </button>
              )}
          </div>
          <div
            className="flex-1 flex items-center justify-center p-4"
            onClick={(e) => e.stopPropagation()}
          >
            <img
              src={ttImageUrl(
                preview.kind === "zone" &&
                  showLines &&
                  preview.photo.image_with_lines_id
                  ? preview.photo.image_with_lines_id
                  : preview.photo.image_id
              )}
              alt="Просмотр"
              className="max-w-full max-h-full object-contain"
            />
          </div>
        </div>
      )}
    </div>
  );
}
