"use client";

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

type Release = {
  rgMbid: string;
  album: string;
  primaryType: string | null;
  secondaryTypes: string[];
  firstReleaseDate: string | null;
  monitored: boolean;
  have: boolean;
};
type Preview = { artistName: string; followed: boolean; releases: Release[] };
type Track = { position: number; title: string; lengthMs: number | null };

function fmt(ms: number | null): string {
  if (ms == null) return "";
  const s = Math.round(ms / 1000);
  return `${Math.floor(s / 60)}:${String(s % 60).padStart(2, "0")}`;
}

export function PreviewClient({ mbid, initialName }: { mbid: string; initialName: string }) {
  const [data, setData] = useState<Preview | null>(null);
  const [showAll, setShowAll] = useState(false);
  const [followed, setFollowed] = useState(false);
  const [tracks, setTracks] = useState<Record<string, Track[] | "loading" | "error">>({});
  const [error, setError] = useState(false);

  const load = useCallback(async () => {
    setError(false);
    const qs = new URLSearchParams();
    if (initialName) qs.set("name", initialName);
    if (showAll) qs.set("all", "true");
    const res = await fetch(`/api/discover/preview/${mbid}?${qs.toString()}`);
    if (!res.ok) {
      setError(true);
      return;
    }
    const d: Preview = await res.json();
    setData(d);
    setFollowed(d.followed);
  }, [mbid, initialName, showAll]);

  useEffect(() => {
    load();
  }, [load]);

  // Scroll to the album an album-suggestion deep-linked to (#rg-<rgMbid>) once data is in.
  useEffect(() => {
    if (!data) return;
    const hash = window.location.hash;
    if (!hash) return;
    document.getElementById(hash.slice(1))?.scrollIntoView();
  }, [data]);

  async function follow() {
    const name = data?.artistName || initialName;
    const res = await fetch("/api/artists", {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ mbid, name }),
    });
    if (res.ok || res.status === 409) setFollowed(true);
  }

  async function want(r: Release) {
    await fetch("/api/discover/want", {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({
        rgMbid: r.rgMbid,
        artistMbid: mbid,
        artistName: data?.artistName || initialName,
        album: r.album,
        primaryType: r.primaryType,
        secondaryTypes: r.secondaryTypes,
        firstReleaseDate: r.firstReleaseDate,
      }),
    });
    setData((d) =>
      d ? { ...d, releases: d.releases.map((x) => (x.rgMbid === r.rgMbid ? { ...x, monitored: true } : x)) } : d,
    );
  }

  async function toggleTracks(rgMbid: string) {
    if (tracks[rgMbid]) {
      setTracks((t) => {
        const n = { ...t };
        delete n[rgMbid];
        return n;
      });
      return;
    }
    setTracks((t) => ({ ...t, [rgMbid]: "loading" }));
    const res = await fetch(`/api/mb/release-groups/${rgMbid}/tracks`);
    if (!res.ok) {
      setTracks((t) => ({ ...t, [rgMbid]: "error" }));
      return;
    }
    const { tracks: ts } = await res.json();
    setTracks((t) => ({ ...t, [rgMbid]: ts }));
  }

  if (error)
    return (
      <p>
        Couldn’t load this artist. <button onClick={load}>Retry</button>
      </p>
    );
  if (!data) return <p>Loading…</p>;

  return (
    <div>
      <h1>{data.artistName || "Artist"}</h1>
      <p>
        {followed ? <span>Following</span> : <button onClick={follow}>Follow</button>}
        {" · "}
        <a href={`https://musicbrainz.org/artist/${mbid}`} target="_blank" rel="noreferrer">
          MusicBrainz ↗
        </a>
      </p>
      <label>
        <input type="checkbox" checked={showAll} onChange={(e) => setShowAll(e.target.checked)} /> Show all release
        types
      </label>
      <ul>
        {data.releases.map((r) => (
          <li key={r.rgMbid} id={`rg-${r.rgMbid}`}>
            <strong>{r.album}</strong>{" "}
            <small>
              {r.primaryType}
              {r.firstReleaseDate ? ` · ${r.firstReleaseDate.slice(0, 4)}` : ""}
            </small>{" "}
            {r.have ? <em>In library</em> : r.monitored ? <em>Monitored</em> : null}{" "}
            <button onClick={() => want(r)} disabled={r.have || r.monitored}>
              Want
            </button>{" "}
            <button onClick={() => toggleTracks(r.rgMbid)}>{tracks[r.rgMbid] ? "Hide tracks" : "Tracks"}</button>
            {tracks[r.rgMbid] === "loading" && <p>Loading tracks…</p>}
            {tracks[r.rgMbid] === "error" && <p>Couldn’t load tracks.</p>}
            {Array.isArray(tracks[r.rgMbid]) && (
              <ol>
                {(tracks[r.rgMbid] as Track[]).map((t) => (
                  <li key={t.position}>
                    {t.title} {t.lengthMs != null && <small>({fmt(t.lengthMs)})</small>}
                  </li>
                ))}
              </ol>
            )}
          </li>
        ))}
      </ul>
    </div>
  );
}
