import { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import { apiFetch } from '../lib/api';

interface Playlist {
  id: string;
  title: string;
  description: string | null;
  visibility: 'private' | 'shared' | 'public';
}

interface Invitation {
  shareId: string;
  playlistId: string;
  playlistTitle: string;
  permission: 'view' | 'edit';
}

interface PlaylistsResponse {
  success: boolean;
  data: {
    owned: Playlist[];
    shared: (Playlist & { permission: 'view' | 'edit' })[];
    invitations?: Invitation[];
  };
}

export default function PlaylistsPage() {
  const [owned, setOwned] = useState<Playlist[]>([]);
  const [shared, setShared] = useState<(Playlist & { permission: 'view' | 'edit' })[]>([]);
  const [invitations, setInvitations] = useState<Invitation[]>([]);
  const [loading, setLoading] = useState(true);
  const [fetchError, setFetchError] = useState<string | null>(null);
  const [createTitle, setCreateTitle] = useState('');
  const [creating, setCreating] = useState(false);
  const [createError, setCreateError] = useState<string | null>(null);
  const [inviteError, setInviteError] = useState<string | null>(null);
  const [respondingId, setRespondingId] = useState<string | null>(null);

  useEffect(() => {
    apiFetch<PlaylistsResponse>('/playlists')
      .then((res) => {
        setOwned(res.data.owned);
        setShared(res.data.shared);
        setInvitations(res.data.invitations ?? []);
      })
      .catch(() => setFetchError('Impossible de charger les playlists.'))
      .finally(() => setLoading(false));
  }, []);

  async function handleCreate(e: React.FormEvent) {
    e.preventDefault();
    if (!createTitle.trim() || creating) return;
    setCreating(true);
    setCreateError(null);
    try {
      const res = await apiFetch<{ success: boolean; data: { playlist: Playlist } }>(
        '/playlists',
        { method: 'POST', body: JSON.stringify({ title: createTitle.trim() }) }
      );
      setOwned((prev) => [res.data.playlist, ...prev]);
      setCreateTitle('');
    } catch {
      setCreateError('Impossible de créer la playlist.');
    }
    setCreating(false);
  }

  async function respondInvitation(inv: Invitation, status: 'accepted' | 'revoked') {
    if (respondingId) return;
    setRespondingId(inv.shareId);
    setInviteError(null);
    try {
      await apiFetch(`/playlists/${inv.playlistId}/share/${inv.shareId}`, {
        method: 'PATCH',
        body: JSON.stringify({ status }),
      });
      setInvitations((prev) => prev.filter((i) => i.shareId !== inv.shareId));
      if (status === 'accepted') {
        const res = await apiFetch<PlaylistsResponse>('/playlists');
        setOwned(res.data.owned);
        setShared(res.data.shared);
        setInvitations(res.data.invitations ?? []);
      }
    } catch {
      setInviteError("Impossible de répondre à l'invitation.");
    }
    setRespondingId(null);
  }

  if (loading) {
    return (
      <div className="flex flex-col gap-3">
        {[...Array(3)].map((_, i) => (
          <div key={i} className="h-14 rounded border border-od-border bg-od-surface animate-pulse" />
        ))}
      </div>
    );
  }

  if (fetchError) {
    return <p className="text-sm text-od-crit">{fetchError}</p>;
  }

  return (
    <div className="flex flex-col gap-10">

      <section className="border-b border-od-border pb-8">
        <h1 className="text-2xl font-semibold text-od-text">Mes playlists</h1>
      </section>

      {/* Créer */}
      <div className="flex flex-col gap-1">
        <form onSubmit={handleCreate} className="flex gap-2">
          <input
            type="text"
            value={createTitle}
            onChange={(e) => setCreateTitle(e.target.value)}
            placeholder="Nouvelle playlist…"
            className="flex-1 rounded border border-od-border bg-od-surface px-3 py-2 text-sm text-od-text placeholder-od-muted outline-none focus:border-od-accent"
          />
          <button
            type="submit"
            disabled={!createTitle.trim() || creating}
            className="rounded border border-od-border px-4 py-2 font-mono text-xs text-od-muted hover:border-od-accent hover:text-od-accent transition-colors disabled:opacity-40"
          >
            +
          </button>
        </form>
        {createError && <p className="font-mono text-xs text-od-crit">{createError}</p>}
      </div>

      {/* Invitations reçues */}
      {invitations.length > 0 && (
        <section className="flex flex-col gap-2">
          <h2 className="font-mono text-xs uppercase tracking-widest text-od-muted">Invitations</h2>
          {inviteError && <p className="font-mono text-xs text-od-crit">{inviteError}</p>}
          {invitations.map((inv) => (
            <div
              key={inv.shareId}
              className="flex items-center justify-between gap-4 rounded border border-od-border bg-od-surface px-4 py-3"
            >
              <div className="flex flex-col gap-0.5 min-w-0">
                <span className="text-sm text-od-text truncate">{inv.playlistTitle}</span>
                <span className="font-mono text-xs text-od-muted">{inv.permission}</span>
              </div>
              <div className="flex gap-2 shrink-0">
                <button
                  disabled={respondingId === inv.shareId}
                  onClick={() => respondInvitation(inv, 'accepted')}
                  className="rounded border border-od-ok px-3 py-1 font-mono text-xs text-od-ok hover:bg-od-ok hover:text-od-bg transition-colors disabled:opacity-40"
                >
                  {respondingId === inv.shareId ? '…' : 'Accepter'}
                </button>
                <button
                  disabled={respondingId === inv.shareId}
                  onClick={() => respondInvitation(inv, 'revoked')}
                  className="rounded border border-od-border px-3 py-1 font-mono text-xs text-od-muted hover:border-od-crit hover:text-od-crit transition-colors disabled:opacity-40"
                >
                  Refuser
                </button>
              </div>
            </div>
          ))}
        </section>
      )}

      {/* Mes playlists */}
      {owned.length > 0 && (
        <section className="flex flex-col gap-2">
          <h2 className="font-mono text-xs uppercase tracking-widest text-od-muted">Créées</h2>
          {owned.map((p) => <PlaylistRow key={p.id} playlist={p} />)}
        </section>
      )}

      {/* Partagées */}
      {shared.length > 0 && (
        <section className="flex flex-col gap-2">
          <h2 className="font-mono text-xs uppercase tracking-widest text-od-muted">Partagées avec moi</h2>
          {shared.map((p) => <PlaylistRow key={p.id} playlist={p} badge={p.permission} />)}
        </section>
      )}

      {owned.length === 0 && shared.length === 0 && invitations.length === 0 && (
        <p className="text-sm text-od-muted">Aucune playlist pour l'instant.</p>
      )}

    </div>
  );
}

function PlaylistRow({ playlist, badge }: { playlist: Playlist; badge?: string }) {
  return (
    <Link
      to={`/playlists/${playlist.id}`}
      className="flex items-center justify-between rounded border border-od-border bg-od-surface px-4 py-3 hover:border-od-accent/40 transition-colors"
    >
      <span className="text-sm text-od-text">{playlist.title}</span>
      <div className="flex items-center gap-2">
        {badge && (
          <span className="font-mono text-xs text-od-muted">{badge}</span>
        )}
        <span className="font-mono text-xs text-od-muted">
          {playlist.visibility === 'private' ? '⊠' : playlist.visibility === 'shared' ? '⊡' : '⊞'}
        </span>
      </div>
    </Link>
  );
}
