"use client";

import { useCallback, useEffect, useState } from "react";
import { PageHead } from "../_ui/page-head";
import { SectionHeader } from "../_ui/section-header";
import { ArtistModal } from "../_ui/artist-modal";
import { AlbumModal } from "../_ui/album-modal";
import { CoverArt } from "../_ui/cover-art";
import { toast } from "../_ui/toast";

type Suggestion = {
  id: string;
  artistMbid: string;
  artistName: string;
  rgMbid: string | null;
  album: string | null;
  score: number;
  seedCount: number;
  sources: string[];
};

type Feed = { artists: Suggestion[]; albums: Suggestion[] };
type SearchResult = {
  seed: { mbid: string; name: string } | null;
  similar: { mbid: string; name: string; score: number }[];
};

export function DiscoverClient() {
  const [feed, setFeed] = useState<Feed>({ artists: [], albums: [] });
  const [result, setResult] = useState<string | null>(null);
  const [running, setRunning] = useState(false);
  const [query, setQuery] = useState("");
  const [search, setSearch] = useState<SearchResult | null>(null);
  const [busy, setBusy] = useState(false);
  const [followedSimilar, setFollowedSimilar] = useState<Set<string>>(new Set());
  const [artistModal, setArtistModal] = useState<{ mbid: string; name: string } | null>(null);
  const [albumModal, setAlbumModal] = useState<Suggestion | null>(null);

  const loadFeed = useCallback(async () => {
    setFeed(await (await fetch("/api/discover")).json());
  }, []);

  useEffect(() => {
    loadFeed();
    fetch("/api/discover/run")
      .then((r) => r.json())
      .then((s: { result: string | null; requested: boolean }) => {
        setResult(s.result);
        setRunning(s.requested);
      });
  }, [loadFeed]);

  useEffect(() => {
    if (!running) return;
    const id = setInterval(async () => {
      const s = await (await fetch("/api/discover/run")).json();
      setResult(s.result);
      if (!s.requested) {
        setRunning(false);
        loadFeed();
      }
    }, 2000);
    return () => clearInterval(id);
  }, [running, loadFeed]);

  async function discoverNow() {
    await fetch("/api/discover/run", { method: "POST" });
    setRunning(true);
  }

  async function runSearch(e: React.FormEvent) {
    e.preventDefault();
    if (!query.trim()) return;
    setBusy(true);
    try {
      setSearch(await (await fetch(`/api/discover/search?artist=${encodeURIComponent(query.trim())}`)).json());
    } finally {
      setBusy(false);
    }
  }

  async function followSimilar(a: { mbid: string; name: string }) {
    const res = await fetch("/api/artists", {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ mbid: a.mbid, name: a.name }),
    });
    if (res.ok || res.status === 409) {
      setFollowedSimilar((s) => new Set(s).add(a.mbid));
      toast(`Following ${a.name}`);
    }
  }

  async function act(id: string, action: "follow" | "want" | "dismiss") {
    await fetch(`/api/discover/${id}`, {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ action }),
    });
    toast(action === "follow" ? "Following" : action === "want" ? "Added to wanted" : "Dismissed");
    loadFeed();
  }

  return (
    <div>
      <PageHead title="Discover" eyebrow="A&R · similar artists & new releases" />

      <div className="tool-row">
        <button className="btn accent" onClick={discoverNow} disabled={running}>
          {running ? "Discovering…" : "Discover now"}
        </button>
        {result ? <span className="rmeta">last run · {result}</span> : null}
      </div>

      <SectionHeader title="Find similar" />
      <form className="request-form" onSubmit={runSearch}>
        <label className="field">
          <span>Seed artist</span>
          <input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Artist name…" aria-label="Seed artist" />
        </label>
        <button type="submit" className="btn" disabled={busy}>
          {busy ? "Searching…" : "Find similar"}
        </button>
      </form>
      {search && !search.seed ? <p className="muted-note">No MusicBrainz match.</p> : null}
      {search?.seed ? (
        <ul className="list">
          {search.similar.map((s) => (
            <li key={s.mbid} className="list-row">
              <div className="main">
                <div className="rtitle">
                  <button className="linkish" onClick={() => setArtistModal({ mbid: s.mbid, name: s.name })}>
                    {s.name}
                  </button>
                </div>
                <div className="rmeta">
                  <span className="score">similarity {s.score.toFixed(1)}</span>
                </div>
              </div>
              <div className="actions">
                {followedSimilar.has(s.mbid) ? (
                  <span className="following">Following</span>
                ) : (
                  <button className="btn sm" onClick={() => followSimilar(s)}>
                    Follow
                  </button>
                )}
              </div>
            </li>
          ))}
        </ul>
      ) : null}

      <SectionHeader title="Suggested artists" note={`${feed.artists.length}`} />
      {feed.artists.length === 0 ? (
        <p className="muted-note">No suggestions yet — run Discover, or follow a few artists to seed it.</p>
      ) : (
        <ul className="list">
          {feed.artists.map((s) => (
            <li key={s.id} className="list-row">
              <div className="main">
                <div className="rtitle">
                  <button className="linkish" onClick={() => setArtistModal({ mbid: s.artistMbid, name: s.artistName })}>
                    {s.artistName}
                  </button>
                </div>
                <div className="rmeta">
                  <span className="score">score {s.score.toFixed(2)}</span>
                  <span className="dot">·</span>
                  <span>{s.seedCount} seed{s.seedCount === 1 ? "" : "s"}</span>
                  <span className="dot">·</span>
                  <span>{s.sources.join(", ")}</span>
                </div>
              </div>
              <div className="actions">
                <button className="btn sm" onClick={() => act(s.id, "follow")}>
                  Follow
                </button>
                <button className="btn sm ghost" onClick={() => act(s.id, "dismiss")}>
                  Dismiss
                </button>
              </div>
            </li>
          ))}
        </ul>
      )}

      <SectionHeader title="Suggested albums" note={`${feed.albums.length}`} />
      {feed.albums.length === 0 ? (
        <p className="muted-note">No album suggestions yet.</p>
      ) : (
        <ul className="list">
          {feed.albums.map((s) => (
            <li key={s.id} className="list-row">
              <div className="main">
                <button className="disco-open" onClick={() => setAlbumModal(s)} aria-label={`Open ${s.album ?? ""}`}>
                  <CoverArt rgMbid={s.rgMbid} alt={s.album ?? ""} className="thumb" />
                  <span>
                    <span className="rtitle">
                      {s.album} <span className="artist">· {s.artistName}</span>
                    </span>
                    <span className="rmeta">
                      <span className="score">score {s.score.toFixed(2)}</span>
                    </span>
                  </span>
                </button>
              </div>
              <div className="actions">
                <button className="btn sm" onClick={() => act(s.id, "want")}>
                  Want
                </button>
                <button className="btn sm ghost" onClick={() => act(s.id, "dismiss")}>
                  Dismiss
                </button>
              </div>
            </li>
          ))}
        </ul>
      )}
      {artistModal ? (
        <ArtistModal open onClose={() => setArtistModal(null)} mbid={artistModal.mbid} initialName={artistModal.name} />
      ) : null}
      {albumModal ? (
        <AlbumModal
          open
          onClose={() => setAlbumModal(null)}
          album={{ rgMbid: albumModal.rgMbid, album: albumModal.album ?? "", artist: albumModal.artistName, year: null, type: null }}
          actions={
            <button
              className="btn sm"
              onClick={() => {
                act(albumModal.id, "want");
                setAlbumModal(null);
              }}
            >
              Want
            </button>
          }
        />
      ) : null}
    </div>
  );
}
