import { useEffect, useState } from 'react';
import { Link } from '@tanstack/react-router';
import { useLiveQuery } from 'dexie-react-hooks';
import { db } from '@/lib/db/db';
import { campaignSchema, characterSchema, type Character } from '@/lib/schemas';
import { decodeClaim } from '@/lib/sync/playerLink';
import { useUiStore } from '@/stores/uiStore';
import { Page, PageHeader, EmptyState } from '@/components/ui/Page';
import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input';

type Status = { kind: 'idle' } | { kind: 'importing' } | { kind: 'error' } | { kind: 'done'; characterId: string; name: string };

/** Player home: claim a shared character, develop it offline, and join a game. */
export function PlayerSetupPage() {
  const claimRaw = new URLSearchParams(window.location.search).get('c');
  const [status, setStatus] = useState<Status>({ kind: claimRaw ? 'importing' : 'idle' });
  const setActiveCampaign = useUiStore((s) => s.setActiveCampaign);
  const localPcs = useLiveQuery(() => db.characters.where('kind').equals('pc').toArray(), [], [] as Character[]);

  useEffect(() => {
    if (!claimRaw) return;
    const payload = decodeClaim(claimRaw);
    if (!payload) { setStatus({ kind: 'error' }); return; }
    void (async () => {
      try {
        const ts = new Date().toISOString();
        const existing = await db.campaigns.get(payload.character.campaignId);
        const campaign = campaignSchema.parse({
          id: payload.character.campaignId,
          name: payload.campaignName,
          system: payload.campaignSystem,
          description: '',
          createdAt: existing?.createdAt ?? ts,
          updatedAt: ts,
        });
        await db.campaigns.put(campaign);
        await db.characters.put(characterSchema.parse(payload.character));
        setActiveCampaign(campaign.id);
        setStatus({ kind: 'done', characterId: payload.character.id, name: payload.character.name });
      } catch {
        setStatus({ kind: 'error' });
      }
    })();
  }, [claimRaw, setActiveCampaign]);

  return (
    <Page>
      <PageHeader title="Player" subtitle="Develop your character and join your table" />
      {status.kind === 'importing' && <p className="text-sm text-muted">Saving your character…</p>}
      {status.kind === 'error' && <EmptyState title="That link didn't work" hint="Ask your GM to share the character link again." />}
      {status.kind === 'done' && (
        <div className="mb-6 rounded-lg border border-accent/40 bg-accent/5 p-4">
          <p className="text-ink"><span className="font-semibold">{status.name}</span> is saved on this device.</p>
          <p className="mt-1 text-sm text-muted">Edit it any time below. When your GM starts the session, enter the room code to play live — your offline changes come with you.</p>
          <Link to="/characters/$characterId" params={{ characterId: status.characterId }} className="mt-3 inline-block">
            <Button variant="primary">Develop your character →</Button>
          </Link>
        </div>
      )}

      <JoinBox />

      <section className="mt-6">
        <h2 className="mb-2 text-sm font-semibold uppercase tracking-wide text-muted">Your characters</h2>
        {(localPcs ?? []).length === 0 ? (
          <p className="text-sm text-muted">No characters yet. Open the “Share with player” link your GM sends you.</p>
        ) : (
          <ul className="grid gap-2 sm:grid-cols-2">
            {(localPcs ?? []).map((c) => (
              <li key={c.id}>
                <Link to="/characters/$characterId" params={{ characterId: c.id }} className="flex items-center justify-between rounded-lg border border-line bg-panel p-3 hover:border-accent">
                  <span className="font-display text-lg font-semibold text-ink">{c.name}</span>
                  <span className="text-xs text-muted">Lv {c.level} {c.className}</span>
                </Link>
              </li>
            ))}
          </ul>
        )}
      </section>
    </Page>
  );
}

function JoinBox() {
  const [code, setCode] = useState('');
  const join = () => { const r = code.trim().toUpperCase(); if (r) window.location.href = `/play?room=${encodeURIComponent(r)}`; };
  return (
    <div className="rounded-lg border border-line bg-panel p-4">
      <h2 className="mb-2 text-sm font-semibold uppercase tracking-wide text-muted">Join a live session</h2>
      <div className="flex max-w-sm gap-2">
        <Input value={code} onChange={(e) => setCode(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') join(); }} placeholder="Room code (e.g. AB12CD)" aria-label="Room code" />
        <Button variant="primary" disabled={!code.trim()} onClick={join}>Join</Button>
      </div>
    </div>
  );
}
