"use client";

import { useState, useRef, useCallback, useEffect } from "react";
import { SectionEditor } from "../_components/SectionEditor";
import { InputField } from "../_components/FormField";
import { adminFetch } from "@/lib/csrf";
import { Upload, X, Loader2, Smartphone, Monitor, Star } from "lucide-react";

const MAX_VIDEO_SIZE_MB = 10;
const MAX_VIDEO_SIZE_BYTES = MAX_VIDEO_SIZE_MB * 1024 * 1024;

function formatFileSize(bytes: number): string {
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} КБ`;
  return `${(bytes / (1024 * 1024)).toFixed(1)} МБ`;
}

interface HeroData {
  headline: string;
  subheadline: string;
  ctaText: string;
  videos?: string[];
}

const SLOTS = [
  { key: "left", label: "Левое", sublabel: "Диагональ слева" },
  { key: "center", label: "Центр", sublabel: "Главное видео" },
  { key: "right", label: "Правое", sublabel: "Диагональ справа" },
] as const;

function VideoSlot({
  label,
  sublabel,
  src,
  isCenter,
  onUpload,
  onRemove,
  uploading,
}: {
  label: string;
  sublabel: string;
  src: string | null;
  isCenter: boolean;
  onUpload: (file: File) => void;
  onRemove: () => void;
  uploading: boolean;
}) {
  const fileRef = useRef<HTMLInputElement>(null);
  const videoRef = useRef<HTMLVideoElement>(null);
  const [fileSize, setFileSize] = useState<number | null>(null);

  // Fetch file size via HEAD request
  useEffect(() => {
    if (!src) { setFileSize(null); return; }
    fetch(src, { method: "HEAD" })
      .then((r) => {
        const len = r.headers.get("content-length");
        if (len) setFileSize(parseInt(len, 10));
      })
      .catch(() => {});
  }, [src]);

  const isLarge = fileSize !== null && fileSize > MAX_VIDEO_SIZE_BYTES;

  return (
    <div className="space-y-2">
      {/* Label */}
      <div className="flex items-center gap-2">
        <span className="text-sm font-medium text-neutral-300">{label}</span>
        {isCenter && (
          <span className="inline-flex items-center gap-1 rounded-full bg-[#c9a96e]/15 px-2 py-0.5 text-[10px] font-medium text-[#c9a96e]">
            <Smartphone size={10} />
            мобильная версия
          </span>
        )}
      </div>
      <p className="text-xs text-neutral-500">{sublabel}</p>

      {/* Slot */}
      {src ? (
        <div
          className={`group relative overflow-hidden rounded-lg border ${
            isCenter ? "border-[#c9a96e]/40 ring-1 ring-[#c9a96e]/20" : "border-neutral-700"
          }`}
          onMouseEnter={() => videoRef.current?.play()}
          onMouseLeave={() => { videoRef.current?.pause(); }}
        >
          <video
            ref={videoRef}
            src={src}
            muted
            loop
            playsInline
            preload="metadata"
            className="aspect-[9/16] w-full object-cover bg-black"
          />
          <div className="absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/80 to-transparent p-2">
            <p className="truncate text-xs text-neutral-400">
              {src.split("/").pop()}
            </p>
            {fileSize !== null && (
              <p className={`text-[10px] mt-0.5 ${isLarge ? "text-amber-400" : "text-neutral-500"}`}>
                {formatFileSize(fileSize)}{isLarge ? ` — рекомендуем до ${MAX_VIDEO_SIZE_MB} МБ` : ""}
              </p>
            )}
          </div>
          {isCenter && (
            <div className="absolute top-2 left-1/2 -translate-x-1/2 flex items-center gap-1 rounded-full bg-[#c9a96e]/90 px-2 py-0.5 text-[10px] font-bold text-black">
              <Star size={10} fill="currentColor" />
              MAIN
            </div>
          )}
          {/* Play hint */}
          <div className="absolute inset-0 flex items-center justify-center bg-black/20 opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none">
            <span className="text-white/80 text-xs">▶ наведите для просмотра</span>
          </div>
          <button
            onClick={onRemove}
            aria-label={`Удалить видео: ${label}`}
            className="absolute top-2 right-2 rounded-full bg-black/70 p-1.5 text-neutral-400 opacity-0 transition-opacity hover:text-red-400 group-hover:opacity-100"
            title="Удалить"
          >
            <X size={14} />
          </button>
        </div>
      ) : (
        <button
          onClick={() => fileRef.current?.click()}
          disabled={uploading}
          className={`flex aspect-[9/16] w-full items-center justify-center rounded-lg border-2 border-dashed transition-colors disabled:opacity-50 ${
            isCenter
              ? "border-[#c9a96e]/30 text-[#c9a96e]/50 hover:border-[#c9a96e]/60 hover:text-[#c9a96e]"
              : "border-neutral-700 text-neutral-500 hover:border-neutral-500 hover:text-neutral-300"
          }`}
        >
          {uploading ? (
            <Loader2 size={24} className="animate-spin" />
          ) : (
            <div className="flex flex-col items-center gap-2">
              <Upload size={24} />
              <span className="text-xs font-medium">Загрузить</span>
              <span className="text-[10px] opacity-60">MP4, до {MAX_VIDEO_SIZE_MB} МБ</span>
            </div>
          )}
        </button>
      )}

      <input
        ref={fileRef}
        type="file"
        accept="video/mp4,video/webm"
        className="hidden"
        onChange={(e) => {
          const file = e.target.files?.[0];
          if (file) onUpload(file);
          if (fileRef.current) fileRef.current.value = "";
        }}
      />
    </div>
  );
}

function VideoSizeInfo({ totalSize, totalMb, rating }: { totalSize: number; totalMb: number; rating: { label: string; color: string } }) {
  const [open, setOpen] = useState(false);
  return (
    <button
      onClick={() => setOpen((v) => !v)}
      className="w-full text-left rounded-lg bg-neutral-800/50 px-3 py-2 transition-colors hover:bg-neutral-800/80"
    >
      <div className="flex items-center justify-between">
        <span className="text-xs text-neutral-400">Общий вес: <span className={`font-medium ${rating.color}`}>{formatFileSize(totalSize)}</span></span>
        <span className={`text-[11px] ${rating.color}`}>{rating.label} {open ? "▲" : "▼"}</span>
      </div>
      {open && (
        <table className="w-full text-[10px] text-neutral-500 mt-2">
          <tbody>
            <tr className={totalMb <= 15 ? `${rating.color} font-medium` : ""}>
              <td className="py-0.5 w-20">до 15 МБ</td><td>Быстро — видео загружается мгновенно</td>
            </tr>
            <tr className={totalMb > 15 && totalMb <= 24 ? `${rating.color} font-medium` : ""}>
              <td className="py-0.5">15–24 МБ</td><td>Нормально — небольшая задержка на 4G</td>
            </tr>
            <tr className={totalMb > 24 && totalMb <= 40 ? `${rating.color} font-medium` : ""}>
              <td className="py-0.5">24–40 МБ</td><td>Медленно — заметная задержка на телефоне</td>
            </tr>
            <tr className={totalMb > 40 ? `${rating.color} font-medium` : ""}>
              <td className="py-0.5">40+ МБ</td><td>Очень медленно — пользователь может уйти</td>
            </tr>
          </tbody>
        </table>
      )}
    </button>
  );
}

function VideoManager({
  videos,
  onChange,
}: {
  videos: string[];
  onChange: (videos: string[]) => void;
}) {
  const [slots, setSlots] = useState<(string | null)[]>(() => [
    videos[0] || null,
    videos[1] || null,
    videos[2] || null,
  ]);
  const [uploadingIdx, setUploadingIdx] = useState<number | null>(null);

  const syncToParent = useCallback(
    (updated: (string | null)[]) => {
      setSlots(updated);
      // Save all 3 slots (empty string for unfilled) to preserve positions
      onChange(updated.map((s) => s || ""));
    },
    [onChange]
  );

  const [sizeWarning, setSizeWarning] = useState<string | null>(null);
  const [fileSizes, setFileSizes] = useState<(number | null)[]>([null, null, null]);

  // Fetch file sizes for all slots
  useEffect(() => {
    slots.forEach((src, i) => {
      if (!src) { setFileSizes((p) => { const n = [...p]; n[i] = null; return n; }); return; }
      fetch(src, { method: "HEAD" })
        .then((r) => {
          const len = r.headers.get("content-length");
          if (len) setFileSizes((p) => { const n = [...p]; n[i] = parseInt(len, 10); return n; });
        })
        .catch(() => {});
    });
  }, [slots]);

  const totalSize = fileSizes.reduce((sum: number, s) => sum + (s || 0), 0);
  const totalMb = totalSize / (1024 * 1024);

  function getLoadRating(mb: number): { label: string; color: string } {
    if (mb <= 15) return { label: "Быстрая загрузка", color: "text-emerald-400" };
    if (mb <= 24) return { label: "Нормальная загрузка", color: "text-blue-400" };
    if (mb <= 40) return { label: "Медленная загрузка", color: "text-amber-400" };
    return { label: "Очень медленная загрузка", color: "text-red-400" };
  }

  async function handleUpload(idx: number, file: File) {
    if (file.size > MAX_VIDEO_SIZE_BYTES) {
      const sizeMb = (file.size / (1024 * 1024)).toFixed(1);
      alert(`Видео ${sizeMb} МБ — максимум ${MAX_VIDEO_SIZE_MB} МБ. Сожмите видео и попробуйте снова.`);
      return;
    }
    setSizeWarning(null);
    setUploadingIdx(idx);
    try {
      const form = new FormData();
      form.append("file", file);
      form.append("folder", "hero");
      const res = await adminFetch("/api/admin/upload", {
        method: "POST",
        body: form,
      });
      if (!res.ok) {
        const text = await res.text();
        let msg = "Ошибка загрузки";
        try {
          const err = JSON.parse(text);
          msg = err.error || msg;
        } catch { /* empty response */ }
        alert(`${msg} (${res.status})`);
        return;
      }
      const { path } = await res.json();
      const updated = [...slots];
      updated[idx] = path;
      syncToParent(updated);
    } catch (e) {
      alert(`Ошибка сети: ${e instanceof Error ? e.message : "попробуйте снова"}`);
    } finally {
      setUploadingIdx(null);
    }
  }

  function handleRemove(idx: number) {
    const updated = [...slots];
    updated[idx] = null;
    syncToParent(updated);
  }

  const allFilled = slots.every((s) => s !== null);
  const filledCount = slots.filter((s) => s !== null).length;

  return (
    <div className="space-y-4">
      <div className="flex items-center gap-3">
        <label className="text-sm font-medium text-neutral-300">
          Видео на главном экране
        </label>
        {!allFilled && (
          <span className="inline-flex items-center gap-1 rounded bg-amber-500/10 px-2 py-0.5 text-[11px] text-amber-400">
            Загружено {filledCount}/3 — загрузите все для сохранения
          </span>
        )}
        {allFilled && (
          <span className="inline-flex items-center gap-1 rounded bg-emerald-500/10 px-2 py-0.5 text-[11px] text-emerald-400">
            ✓ Все видео загружены
          </span>
        )}
      </div>

      <div className="grid gap-4 sm:grid-cols-3 max-w-3xl">
        {SLOTS.map((slot, i) => (
          <VideoSlot
            key={slot.key}
            label={slot.label}
            sublabel={slot.sublabel}
            src={slots[i]}
            isCenter={i === 1}
            uploading={uploadingIdx === i}
            onUpload={(file) => handleUpload(i, file)}
            onRemove={() => handleRemove(i)}
          />
        ))}
      </div>

      <div className="flex gap-4 text-xs text-neutral-500">
        <div className="flex items-center gap-1.5">
          <Monitor size={13} />
          <span>ПК — диагональный сплит из 3 видео</span>
        </div>
        <div className="flex items-center gap-1.5">
          <Smartphone size={13} />
          <span>Телефон — только центральное видео</span>
        </div>
      </div>

      {sizeWarning && (
        <div className="rounded-lg bg-amber-500/10 border border-amber-500/20 px-3 py-2 text-xs text-amber-400">
          ⚠ {sizeWarning}
        </div>
      )}

      {/* Total size — collapsible */}
      {totalSize > 0 && <VideoSizeInfo totalSize={totalSize} totalMb={totalMb} rating={getLoadRating(totalMb)} />}
    </div>
  );
}

export default function HeroEditorPage() {
  return (
    <SectionEditor<HeroData> sectionKey="hero" title="Главный экран">
      {(data, update) => (
        <>
          <VideoManager
            videos={data.videos || []}
            onChange={(videos) => update({ ...data, videos })}
          />

          <InputField
            label="Заголовок"
            value={data.headline || ""}
            onChange={(v) => update({ ...data, headline: v })}
          />
          <InputField
            label="Подзаголовок"
            value={data.subheadline || ""}
            onChange={(v) => update({ ...data, subheadline: v })}
          />
          <InputField
            label="Текст кнопки"
            value={data.ctaText || ""}
            onChange={(v) => update({ ...data, ctaText: v })}
          />
        </>
      )}
    </SectionEditor>
  );
}
