'use client';

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

import Link from 'next/link';

import {
  btn,
  btnDanger,
  card,
  error as errorClass,
  formWide,
  hr,
  input,
  label,
  metaLine,
  rowActions,
  sectionBlock,
  sectionTitle,
  textarea,
  title,
} from '@/lib/adminUi';

type Char = { id: number; name_id: string; name: string; name_jp: string };
type PlayerRow = {
  id: number;
  player_key: string;
  player_name: string;
  description: string | null;
  image: string | null;
  character_id: string | null;
  name_id?: string;
  name_jp?: string;
};

const field = `${input} ${textarea}`;

export function PlayersAdminClient() {
  const [players, setPlayers] = useState<PlayerRow[]>([]);
  const [characters, setCharacters] = useState<Char[]>([]);
  const [error, setError] = useState('');
  const [loading, setLoading] = useState(true);

  const [playerKey, setPlayerKey] = useState('');
  const [playerName, setPlayerName] = useState('');
  const [description, setDescription] = useState('');
  const [image, setImage] = useState('');
  const [characterId, setCharacterId] = useState('');

  const load = useCallback(async () => {
    setError('');
    const [pr, cr] = await Promise.all([
      fetch('/api/admin/players', { credentials: 'include' }),
      fetch('/api/admin/characters', { credentials: 'include' }),
    ]);
    const pj = await pr.json().catch(() => ({}));
    const cj = await cr.json().catch(() => ({}));
    if (!pr.ok) {
      setError((pj as { error?: string }).error ?? 'Failed to load players');
      setLoading(false);
      return;
    }
    if (!cr.ok) {
      setError((cj as { error?: string }).error ?? 'Failed to load characters');
      setLoading(false);
      return;
    }
    setPlayers((pj as { players: PlayerRow[] }).players ?? []);
    setCharacters((cj as { characters: Char[] }).characters ?? []);
    setLoading(false);
  }, []);

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

  async function addPlayer(e: React.FormEvent) {
    e.preventDefault();
    setError('');
    const res = await fetch('/api/admin/players', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      credentials: 'include',
      body: JSON.stringify({
        player_key: playerKey,
        player_name: playerName,
        description,
        image: image || null,
        character_id: characterId,
      }),
    });
    const data = await res.json().catch(() => ({}));
    if (!res.ok) {
      setError((data as { error?: string }).error ?? 'Create failed');
      return;
    }
    setPlayerKey('');
    setPlayerName('');
    setDescription('');
    setImage('');
    setCharacterId('');
    await load();
  }

  function updateLocal(id: number, patch: Partial<PlayerRow>) {
    setPlayers((prev) => prev.map((r) => (r.id === id ? { ...r, ...patch } : r)));
  }

  async function save(row: PlayerRow) {
    setError('');
    const cid = row.character_id != null && row.character_id !== '' ? String(row.character_id) : '';
    if (!cid) {
      setError('Character is required');
      return;
    }
    const res = await fetch(`/api/admin/players/${row.id}`, {
      method: 'PATCH',
      headers: { 'Content-Type': 'application/json' },
      credentials: 'include',
      body: JSON.stringify({
        player_key: row.player_key,
        player_name: row.player_name,
        description: row.description ?? '',
        image: row.image === '' || row.image == null ? null : row.image,
        character_id: cid,
      }),
    });
    const data = await res.json().catch(() => ({}));
    if (!res.ok) {
      setError((data as { error?: string }).error ?? 'Save failed');
      return;
    }
    await load();
  }

  async function remove(id: number) {
    if (!window.confirm('Delete this player?')) return;
    setError('');
    const res = await fetch(`/api/admin/players/${id}`, { method: 'DELETE', credentials: 'include' });
    const data = await res.json().catch(() => ({}));
    if (!res.ok) {
      setError((data as { error?: string }).error ?? 'Delete failed');
      return;
    }
    await load();
  }

  return (
    <div className={card}>
      <p>
        <Link href="/admin">← Dashboard</Link>
      </p>
      <h1 className={title}>Players</h1>
      {error ? <p className={errorClass}>{error}</p> : null}
      {loading ? <p>Loading…</p> : null}
      {!loading && (
        <>
          {players.map((p) => (
            <div key={p.id} className={sectionBlock}>
              <p className={metaLine}>
                id: {p.id}
                {p.name_jp ? ` · ${p.name_jp}` : ''}
              </p>
              <label className={label}>
                player_key
                <input
                  className={input}
                  value={p.player_key}
                  onChange={(e) => updateLocal(p.id, { player_key: e.target.value })}
                />
              </label>
              <label className={label}>
                player_name
                <input
                  className={input}
                  value={p.player_name}
                  onChange={(e) => updateLocal(p.id, { player_name: e.target.value })}
                />
              </label>
              <label className={label}>
                description
                <textarea
                  className={field}
                  value={p.description ?? ''}
                  onChange={(e) => updateLocal(p.id, { description: e.target.value })}
                />
              </label>
              <label className={label}>
                image URL (optional)
                <input
                  className={input}
                  value={p.image ?? ''}
                  onChange={(e) => updateLocal(p.id, { image: e.target.value || null })}
                />
              </label>
              <label className={label}>
                character
                <select
                  className={input}
                  value={p.character_id != null && p.character_id !== '' ? String(p.character_id) : ''}
                  onChange={(e) => updateLocal(p.id, { character_id: e.target.value })}
                  required
                >
                  <option value="">—</option>
                  {characters.map((c) => (
                    <option key={c.id} value={c.id}>
                      {c.name_jp} ({c.name_id})
                    </option>
                  ))}
                </select>
              </label>
              <div className={rowActions}>
                <button type="button" className={btn} onClick={() => save(p)}>
                  Save
                </button>
                <button type="button" className={btnDanger} onClick={() => remove(p.id)}>
                  Delete
                </button>
              </div>
            </div>
          ))}

          <hr className={hr} />
          <h2 className={sectionTitle}>Add player</h2>
          <form className={formWide} onSubmit={addPlayer}>
            <label className={label}>
              player_key
              <input className={input} value={playerKey} onChange={(e) => setPlayerKey(e.target.value)} required />
            </label>
            <label className={label}>
              player_name
              <input className={input} value={playerName} onChange={(e) => setPlayerName(e.target.value)} required />
            </label>
            <label className={label}>
              description
              <textarea className={field} value={description} onChange={(e) => setDescription(e.target.value)} />
            </label>
            <label className={label}>
              image URL (optional)
              <input className={input} value={image} onChange={(e) => setImage(e.target.value)} />
            </label>
            <label className={label}>
              character
              <select
                className={input}
                value={characterId}
                onChange={(e) => setCharacterId(e.target.value)}
                required
              >
                <option value="">—</option>
                {characters.map((c) => (
                  <option key={c.id} value={c.id}>
                    {c.name_jp} ({c.name_id})
                  </option>
                ))}
              </select>
            </label>
            <button className={btn} type="submit">
              Add
            </button>
          </form>
        </>
      )}
    </div>
  );
}
