"use client";

/* Загрузка фото квартиры к оценке (#394). */
/* eslint-disable @next/next/no-img-element -- фото отдаёт API, next/image тут лишний */
import { useCallback, useEffect, useRef, useState } from "react";

import { API_BASE_URL } from "@/lib/api";
import { getOrCreateSessionId } from "@/lib/sessionId";

const BASE = "/api/v1/trade-in";
const MAX_PHOTOS = 12;
const MAX_FILE_BYTES = 10 * 1024 * 1024; // match backend `_MAX_PHOTO_BYTES`

/**
 * Возвращает false для placeholder-ID вида «preview-0000-...» или любого
 * значения, не похожего на реальный UUID4 (32 hex-цифры через дефисы).
 * Позволяет избежать GET /photos с фейковым ID → 422 (#1804).
 */
function isRealEstimateId(id: string): boolean {
  return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id) &&
    !id.startsWith("preview-");
}

interface PhotoMeta {
  id: string;
  filename: string | null;
  content_type: string;
  size_bytes: number | null;
  uploaded_at: string;
}

export function PhotoUpload({ estimateId }: { estimateId: string }) {
  const [photos, setPhotos] = useState<PhotoMeta[]>([]);
  const [uploading, setUploading] = useState(false);
  const [errors, setErrors] = useState<string[]>([]);
  const inputRef = useRef<HTMLInputElement>(null);

  const refresh = useCallback(async () => {
    // #1804: не слать запрос с фейковым/preview ID — backend отклоняет 422.
    if (!isRealEstimateId(estimateId)) return;
    try {
      const r = await fetch(`${API_BASE_URL}${BASE}/estimate/${estimateId}/photos`);
      if (r.ok) setPhotos((await r.json()) as PhotoMeta[]);
    } catch {
      /* список фото некритичен — молча игнорируем */
    }
  }, [estimateId]);

  useEffect(() => {
    void refresh();
  }, [refresh]);

  async function handleFiles(files: FileList | null) {
    if (!files || files.length === 0) return;
    // #1804: guard — не слать upload с placeholder-ID (backend 422)
    if (!isRealEstimateId(estimateId)) return;
    setUploading(true);
    setErrors([]); // clear stale errors on every new pick
    const sid = getOrCreateSessionId();
    const collected: string[] = [];

    for (const file of Array.from(files)) {
      // Client-side guards mirror backend filters; reject before bandwidth waste.
      if (file.size > MAX_FILE_BYTES) {
        collected.push(`${file.name}: файл больше 10 МБ (${(file.size / 1024 / 1024).toFixed(1)} МБ)`);
        continue;
      }
      if (file.size === 0) {
        collected.push(`${file.name}: пустой файл`);
        continue;
      }

      const form = new FormData();
      form.append("file", file);
      try {
        const r = await fetch(
          `${API_BASE_URL}${BASE}/estimate/${estimateId}/photos`,
          {
            method: "POST",
            body: form,
            headers: sid ? { "X-Session-Id": sid } : {},
          },
        );
        if (!r.ok) collected.push(`${file.name}: ошибка загрузки (${r.status})`);
      } catch {
        collected.push(`${file.name}: сеть недоступна`);
      }
    }

    setErrors(collected);
    setUploading(false);
    if (inputRef.current) inputRef.current.value = "";
    await refresh();
  }

  const full = photos.length >= MAX_PHOTOS;
  // #1804: upload недоступен для preview/placeholder ID — не слать 422.
  const isPreview = !isRealEstimateId(estimateId);

  return (
    <article className="card">
      <div className="card-body">
        <div
          style={{
            display: "flex",
            justifyContent: "space-between",
            alignItems: "center",
            marginBottom: 12,
          }}
        >
          <h3 style={{ fontSize: 15, fontWeight: 600 }}>Фото квартиры</h3>
          <span style={{ color: "var(--muted)", fontSize: 13 }}>
            {isPreview ? `— / ${MAX_PHOTOS}` : `${photos.length} / ${MAX_PHOTOS}`}
          </span>
        </div>

        <input
          ref={inputRef}
          type="file"
          accept="image/*"
          multiple
          aria-label="Загрузить фото квартиры"
          disabled={uploading || full || isPreview}
          onChange={(e) => handleFiles(e.target.files)}
        />

        {uploading && (
          <p style={{ color: "var(--muted)", fontSize: 13, marginTop: 8 }}>
            Загрузка…
          </p>
        )}
        {full && !uploading && (
          <p style={{ color: "var(--muted)", fontSize: 13, marginTop: 8 }}>
            Достигнут лимит {MAX_PHOTOS} фото.
          </p>
        )}
        {errors.length > 0 && (
          <ul
            style={{
              color: "#c0392b",
              fontSize: 13,
              marginTop: 8,
              paddingLeft: 18,
              listStyleType: "disc",
            }}
          >
            {errors.map((msg, i) => (
              <li key={i}>{msg}</li>
            ))}
          </ul>
        )}

        {photos.length > 0 && (
          <div style={{ display: "flex", gap: 8, flexWrap: "wrap", marginTop: 12 }}>
            {photos.map((p) => (
              <img
                key={p.id}
                src={`${API_BASE_URL}${BASE}/estimate/${estimateId}/photos/${p.id}`}
                alt={p.filename ?? "фото квартиры"}
                style={{
                  width: 96,
                  height: 96,
                  objectFit: "cover",
                  borderRadius: 8,
                  border: "1px solid var(--border, #e2e2e2)",
                }}
              />
            ))}
          </div>
        )}
      </div>
    </article>
  );
}
