"use client";

import { useEffect, useMemo, useState } from "react";

type Asset = {
  id: string;
  media_type: "image" | "video";
  mime_type: string;
  capture_ts_utc: string | null;
  thumb_small_key: string | null;
  thumb_med_key: string | null;
  poster_key: string | null;
  status: "new" | "processing" | "ready" | "failed";
  error_message: string | null;
};

type AssetsResponse = {
  items: Asset[];
};

type SignedUrlResponse = {
  url: string;
  expiresSeconds: number;
};

type PreviewUrlState = Record<string, string | undefined>;
type VideoPlaybackVariant = { kind: "original" } | { kind: "video_mp4"; size: 720 };

function startOfDayUtc(iso: string) {
  const d = new Date(iso);
  return new Date(
    Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), 0, 0, 0),
  );
}

function endOfDayUtc(iso: string) {
  const start = startOfDayUtc(iso);
  return new Date(start.getTime() + 24 * 60 * 60 * 1000);
}

export function MediaPanel(props: { selectedDayIso: string | null }) {
  const [assets, setAssets] = useState<Asset[] | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [previews, setPreviews] = useState<PreviewUrlState>({});

  const [viewer, setViewer] = useState<{
    asset: Asset;
    url: string;
    variant: "original" | "thumb_med" | "poster" | "video_mp4";
  } | null>(null);

  const [viewerError, setViewerError] = useState<string | null>(null);
  const [videoFallback, setVideoFallback] = useState<{
    posterUrl: string | null;
  } | null>(null);
  const [retryKey, setRetryKey] = useState(0);

  const range = useMemo(() => {
    if (!props.selectedDayIso) return null;
    const start = startOfDayUtc(props.selectedDayIso);
    const end = endOfDayUtc(props.selectedDayIso);
    return { start, end };
  }, [props.selectedDayIso]);

  useEffect(() => {
    let cancelled = false;

    async function load() {
      if (!range) {
        setAssets(null);
        return;
      }

      try {
        setError(null);
        setAssets(null);

        const qs = new URLSearchParams({
          start: range.start.toISOString(),
          end: range.end.toISOString(),
          limit: "120",
        });

        const res = await fetch(`/api/assets?${qs.toString()}`, {
          cache: "no-store",
        });
        if (!res.ok) throw new Error(`assets_fetch_failed:${res.status}`);
        const json = (await res.json()) as AssetsResponse;

        if (!cancelled) {
          setAssets(json.items);
          setPreviews({});
        }
      } catch (e) {
        if (!cancelled) setError(e instanceof Error ? e.message : String(e));
      }
    }

    void load();
    return () => {
      cancelled = true;
    };
  }, [range]);

  async function loadSignedUrl(
    assetId: string,
    variant:
      | "original"
      | "thumb_small"
      | "thumb_med"
      | "poster"
      | "video_mp4_720",
  ) {
    const url =
      variant === "video_mp4_720"
        ? `/api/assets/${assetId}/url?kind=video_mp4&size=720`
        : `/api/assets/${assetId}/url?variant=${variant}`;
    const res = await fetch(url, { cache: "no-store" });
    if (!res.ok) throw new Error(`presign_failed:${res.status}`);
    const json = (await res.json()) as SignedUrlResponse;
    return json.url;
  }

  async function loadVideoPlaybackUrl(
    assetId: string,
  ): Promise<{ url: string; variant: VideoPlaybackVariant }> {
    try {
      const url = await loadSignedUrl(assetId, "video_mp4_720");
      return { url, variant: { kind: "video_mp4", size: 720 } };
    } catch {
      const url = await loadSignedUrl(assetId, "original");
      return { url, variant: { kind: "original" } };
    }
  }

  async function openViewer(asset: Asset) {
    if (asset.status === "failed") {
      setViewerError(`${asset.id}: ${asset.error_message ?? "asset_failed"}`);
      setViewer(null);
      return;
    }

    setViewerError(null);
    setVideoFallback(null);

    if (asset.media_type === "video") {
      const playback = await loadVideoPlaybackUrl(asset.id);
      const variantLabel =
        playback.variant.kind === "video_mp4"
          ? "video_mp4"
          : playback.variant.kind;
      setViewer({ asset, url: playback.url, variant: variantLabel });
      return;
    }

    const variant: "original" | "thumb_med" | "poster" = "original";
    const url = await loadSignedUrl(asset.id, variant);
    setViewer({ asset, url, variant });
  }

  return (
    <div style={{ display: "grid", gap: 12 }}>
      <div
        style={{
          display: "flex",
          alignItems: "baseline",
          justifyContent: "space-between",
        }}
      >
        <strong>Media</strong>
        <span style={{ color: "#666", fontSize: 12 }}>
          {props.selectedDayIso
            ? startOfDayUtc(props.selectedDayIso).toISOString().slice(0, 10)
            : "(select a day)"}
        </span>
      </div>

      {error ? <div style={{ color: "#b00" }}>Error: {error}</div> : null}
      {!assets && props.selectedDayIso && !error ? (
        <div className="space-y-2">
          {[1, 2, 3].map((i) => (
            <div
              key={i}
              className="flex items-center gap-2.5 rounded-lg border border-gray-200 bg-white p-2.5"
            >
              <div
                className="h-18 w-18 animate-pulse rounded-lg bg-gray-200"
                style={{ width: 72, height: 72 }}
              />
              <div className="flex-1 space-y-2">
                <div className="h-4 w-32 animate-pulse rounded bg-gray-200" />
                <div className="h-3 w-20 animate-pulse rounded bg-gray-200" />
              </div>
            </div>
          ))}
        </div>
      ) : null}

      {assets ? (
        <div style={{ display: "grid", gap: 8 }}>
          {assets.length === 0 ? (
            <div style={{ color: "#666" }}>No assets.</div>
          ) : null}
          {assets.map((a) => (
            <button
              key={a.id}
              type="button"
              onClick={() => void openViewer(a)}
              onPointerEnter={() => {
                if (previews[a.id] !== undefined) return;

                const variant =
                  a.media_type === "image" ? "thumb_small" : "poster";
                const promise = loadSignedUrl(a.id, variant).catch(
                  () => undefined,
                );

                void promise.then((url) => {
                  setPreviews((prev) => ({ ...prev, [a.id]: url }));
                });
              }}
              style={{
                textAlign: "left",
                padding: 10,
                border:
                  a.status === "failed"
                    ? "2px solid #ef4444"
                    : "1px solid #ddd",
                borderRadius: 8,
                background: "white",
              }}
            >
              <div
                style={{
                  display: "grid",
                  gridTemplateColumns: "72px 1fr",
                  gap: 10,
                  alignItems: "center",
                }}
              >
                <div
                  style={{
                    width: 72,
                    height: 72,
                    borderRadius: 8,
                    background: a.status === "failed" ? "#fef2f2" : "#f2f2f2",
                    border: "1px solid #eee",
                    overflow: "hidden",
                    display: "grid",
                    placeItems: "center",
                    color: "#888",
                    fontSize: 12,
                  }}
                >
                  {a.status === "failed" ? (
                    <span style={{ fontSize: 24, color: "#ef4444" }}>⚠</span>
                  ) : previews[a.id] ? (
                    // eslint-disable-next-line @next/next/no-img-element
                    <img
                      src={previews[a.id]}
                      alt=""
                      style={{
                        width: "100%",
                        height: "100%",
                        objectFit: "cover",
                      }}
                    />
                  ) : (
                    <span>{a.media_type}</span>
                  )}
                </div>

                <div>
                  <div
                    style={{
                      display: "flex",
                      justifyContent: "space-between",
                      gap: 12,
                    }}
                  >
                    <span>
                      {a.media_type} · {a.status}
                    </span>
                    <span style={{ color: "#666", fontSize: 12 }}>
                      {a.id.slice(0, 8)}
                    </span>
                  </div>
                  {a.status === "failed" && a.error_message ? (
                    <div
                      style={{ color: "#ef4444", fontSize: 12, marginTop: 6 }}
                    >
                      {a.error_message}
                    </div>
                  ) : null}
                </div>
              </div>
            </button>
          ))}
        </div>
      ) : null}

      {viewer || viewerError ? (
        <div
          role="dialog"
          aria-modal="true"
          onClick={() => {
            setViewer(null);
            setViewerError(null);
            setVideoFallback(null);
          }}
          style={{
            position: "fixed",
            inset: 0,
            background: "rgba(0,0,0,0.6)",
            display: "grid",
            placeItems: "center",
            padding: 16,
          }}
        >
          <div
            onClick={(e) => e.stopPropagation()}
            style={{
              width: "min(1000px, 98vw)",
              maxHeight: "90vh",
              overflow: "auto",
              background: "white",
              borderRadius: 12,
              padding: 12,
              display: "grid",
              gap: 12,
            }}
          >
            <div
              style={{
                display: "flex",
                justifyContent: "space-between",
                alignItems: "baseline",
              }}
            >
              <strong>
                {viewer
                  ? `${viewer.asset.media_type} (${viewer.variant})`
                  : "Viewer"}
              </strong>
              <button
                type="button"
                onClick={() => {
                  setViewer(null);
                  setViewerError(null);
                  setVideoFallback(null);
                }}
              >
                Close
              </button>
            </div>

            {viewer ? (
              <>
                {viewer.asset.media_type === "image" ? (
                  // eslint-disable-next-line @next/next/no-img-element
                  <img
                    key={retryKey}
                    src={viewer.url}
                    alt={viewer.asset.id}
                    style={{ width: "100%", height: "auto" }}
                    onError={() => setViewerError("image_load_failed")}
                  />
                ) : (
                  <video
                    key={retryKey}
                    src={viewer.url}
                    controls
                    style={{ width: "100%" }}
                    poster={videoFallback?.posterUrl ?? undefined}
                    onError={() => {
                      setViewerError("video_playback_failed");
                      if (videoFallback !== null) return;
                      setVideoFallback({ posterUrl: null });
                      void loadSignedUrl(viewer.asset.id, "poster")
                        .then((posterUrl) => setVideoFallback({ posterUrl }))
                        .catch(() => setVideoFallback({ posterUrl: null }));
                    }}
                  />
                )}

                {viewerError ? (
                  <div className="flex items-center justify-between gap-4 rounded border border-red-200 bg-red-50 p-3">
                    <div style={{ color: "#b00", fontSize: 12 }}>
                      {viewerError}
                      {viewer.asset.media_type === "video"
                        ? " (try a different browser/codec)"
                        : null}
                    </div>
                    <button
                      type="button"
                      onClick={() => {
                        setViewerError(null);
                        setRetryKey((k) => k + 1);
                      }}
                      className="rounded bg-red-600 px-3 py-1 text-sm text-white hover:bg-red-700"
                    >
                      Retry
                    </button>
                  </div>
                ) : null}

                <div style={{ color: "#666", fontSize: 12 }}>
                  {viewer.asset.id}
                </div>
              </>
            ) : (
              <div style={{ color: "#b00" }}>
                {viewerError ?? "unknown_error"}
              </div>
            )}
          </div>
        </div>
      ) : null}
    </div>
  );
}
