import { type ReactNode, useState } from 'react';
import { useNavigate } from '@tanstack/react-router';
import { ArrowRight, BookOpenText, CalendarDays, Map, RadioTower, ScrollText, Users } from 'lucide-react';
import { cn } from '@/lib/cn';
import { campaignsRepo } from '@/lib/db/repositories';
import { seedSampleCampaign } from '@/lib/sample';
import { SYSTEM_OPTIONS } from '@/lib/rules';
import { useUiStore } from '@/stores/uiStore';
import { useCampaigns } from './hooks';
import type { Campaign } from '@/lib/schemas';
import { Page, PageHeader } from '@/components/ui/Page';
import { Button } from '@/components/ui/Button';
import { Badge } from '@/components/ui/Codex';
import { Modal } from '@/components/ui/Modal';
import { Field, Input, Select, Textarea } from '@/components/ui/Input';

export function CampaignsPage() {
  const campaigns = useCampaigns();
  const [creating, setCreating] = useState(false);
  const [editing, setEditing] = useState<Campaign | null>(null);

  return (
    <Page>
      <PageHeader
        eyebrow="Your tables"
        title="Campaigns"
        subtitle="Each campaign holds its own characters, encounters, and dice history."
        actions={
          <Button variant="primary" onClick={() => setCreating(true)}>
            + New campaign
          </Button>
        }
      />

      {campaigns.length === 0 ? (
        <Welcome onCreate={() => setCreating(true)} />
      ) : (
        <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
          {campaigns.map((c) => (
            <CampaignCard key={c.id} campaign={c} onEdit={() => setEditing(c)} />
          ))}
        </div>
      )}

      {creating && <CampaignFormModal onClose={() => setCreating(false)} />}
      {editing && <CampaignFormModal campaign={editing} onClose={() => setEditing(null)} />}
    </Page>
  );
}

function Welcome({ onCreate }: { onCreate: () => void }) {
  const navigate = useNavigate();
  const setActive = useUiStore((s) => s.setActiveCampaign);
  const [loading, setLoading] = useState(false);
  const loadSample = async () => {
    setLoading(true);
    const id = await seedSampleCampaign();
    setActive(id);
    void navigate({ to: '/dashboard' });
  };
  return (
    <div className="paper-grain relative mx-auto max-w-2xl overflow-hidden rounded-xl border border-line bg-panel p-7 text-center">
      <div className="relative z-[1]">
        <div className="font-display text-sm italic text-accent">A local-first companion</div>
        <h2 className="mt-1 font-display text-2xl font-bold text-accent-deep">Welcome to TTRPG Manager</h2>
        <p className="mx-auto mt-2 max-w-xl text-sm text-muted">
          A local-first companion for D&amp;D 5e &amp; Pathfinder 2e — guided character building, combat
          tracking, a full battle-map VTT with fog &amp; dynamic vision, a searchable compendium, and live
          play your players join from their own devices. Everything is stored on this device.
        </p>
        <hr className="gilt-rule mx-auto mt-5 max-w-xs" />
        <div className="mt-5 grid gap-2 text-left sm:grid-cols-3">
          <FeatCard icon={<Users size={20} />} title="Build characters" desc="A friendly, data-driven builder for new players." />
          <FeatCard icon={<Map size={20} />} title="Run battle maps" desc="Fog, line-of-sight vision, tokens, .dd2vtt import." />
          <FeatCard icon={<RadioTower size={20} />} title="Play live" desc="Host a room; players manage their own character." />
        </div>
        <div className="mt-6 flex flex-wrap items-center justify-center gap-2">
          <Button variant="primary" onClick={onCreate}>Start your first campaign</Button>
          <Button variant="secondary" disabled={loading} onClick={() => void loadSample()}>{loading ? 'Loading…' : 'Try the sample campaign'}</Button>
        </div>
      </div>
    </div>
  );
}

function FeatCard({ icon, title, desc }: { icon: ReactNode; title: string; desc: string }) {
  return (
    <div className="rounded-xl border border-line bg-surface-2 p-3 transition-colors hover:border-line-strong">
      <div className="text-accent" aria-hidden>{icon}</div>
      <div className="mt-1 font-display font-semibold text-ink">{title}</div>
      <div className="text-xs text-muted">{desc}</div>
    </div>
  );
}

function CampaignCard({ campaign, onEdit }: { campaign: Campaign; onEdit: () => void }) {
  const navigate = useNavigate();
  const setActive = useUiStore((s) => s.setActiveCampaign);
  const activeId = useUiStore((s) => s.activeCampaignId);
  const [confirming, setConfirming] = useState(false);

  const open = () => {
    setActive(campaign.id);
    void navigate({ to: '/dashboard' });
  };

  const isActive = activeId === campaign.id;
  const systemLabel = campaign.system === '5e' ? 'D&D 5e' : 'Pathfinder 2e';
  const created = new Date(campaign.createdAt).toLocaleDateString(undefined, {
    month: 'short',
    day: 'numeric',
    year: 'numeric',
  });

  return (
    <div
      className={cn(
        'paper-grain group relative flex flex-col overflow-hidden rounded-xl border bg-panel transition-colors',
        isActive ? 'border-accent' : 'border-line hover:border-line-strong',
      )}
    >
      {/* Cover band */}
      <div className="relative h-24 border-b border-line bg-gradient-to-br from-accent-glow via-panel-2 to-surface-2">
        <BookOpenText
          aria-hidden
          className="absolute right-3 top-3 h-12 w-12 text-accent/25"
          strokeWidth={1.25}
        />
        <div className="absolute left-4 top-3">
          <Badge tone="gold">{systemLabel}</Badge>
        </div>
        {isActive && (
          <span className="absolute right-3 bottom-3 rounded-full bg-accent/15 px-2 py-0.5 text-xs text-accent">
            Active
          </span>
        )}
      </div>

      <div className="relative z-[1] flex flex-1 flex-col p-4">
        <h3 className="font-display text-lg font-semibold tracking-tight text-ink">{campaign.name}</h3>
        {campaign.description && (
          <p className="mt-1 line-clamp-3 text-sm text-muted">{campaign.description}</p>
        )}

        <hr className="gilt-rule my-4" />

        {/* Stats footer */}
        <div className="flex items-center gap-4 text-xs text-faint">
          <span className="inline-flex items-center gap-1.5">
            <ScrollText aria-hidden className="h-4 w-4" />
            {systemLabel}
          </span>
          <span className="inline-flex items-center gap-1.5">
            <CalendarDays aria-hidden className="h-4 w-4" />
            <span className="font-mono">{created}</span>
          </span>
          <ArrowRight
            aria-hidden
            className="ml-auto h-4 w-4 text-accent-deep transition-transform group-hover:translate-x-0.5"
          />
        </div>

        <div className="mt-4 flex items-center gap-2">
          <Button size="sm" variant="primary" onClick={open}>
            Open
          </Button>
          <Button size="sm" variant="ghost" onClick={onEdit}>
            Edit
          </Button>
          <Button
            size="sm"
            variant="ghost"
            className="ml-auto text-danger hover:bg-danger/10"
            onClick={() => setConfirming(true)}
          >
            Delete
          </Button>
        </div>
      </div>

      <Modal
        open={confirming}
        onClose={() => setConfirming(false)}
        title="Delete campaign?"
        footer={
          <>
            <Button variant="ghost" onClick={() => setConfirming(false)}>
              Cancel
            </Button>
            <Button
              variant="danger"
              onClick={async () => {
                await campaignsRepo.remove(campaign.id);
                if (activeId === campaign.id) setActive(null);
                setConfirming(false);
              }}
            >
              Delete everything
            </Button>
          </>
        }
      >
        <p className="text-sm text-muted">
          This permanently deletes <strong className="text-ink">{campaign.name}</strong> and all of its
          characters, encounters, and dice history. This cannot be undone.
        </p>
      </Modal>
    </div>
  );
}

function CampaignFormModal({ campaign, onClose }: { campaign?: Campaign; onClose: () => void }) {
  const setActive = useUiStore((s) => s.setActiveCampaign);
  const [name, setName] = useState(campaign?.name ?? '');
  const [system, setSystem] = useState(campaign?.system ?? '5e');
  const [description, setDescription] = useState(campaign?.description ?? '');
  const [error, setError] = useState<string | null>(null);

  const save = async () => {
    if (name.trim() === '') {
      setError('Name is required');
      return;
    }
    if (campaign) {
      await campaignsRepo.update(campaign.id, { name: name.trim(), system, description });
    } else {
      const created = await campaignsRepo.create({ name: name.trim(), system, description });
      setActive(created.id);
    }
    onClose();
  };

  return (
    <Modal
      open
      onClose={onClose}
      title={campaign ? 'Edit campaign' : 'New campaign'}
      footer={
        <>
          <Button variant="ghost" onClick={onClose}>
            Cancel
          </Button>
          <Button variant="primary" onClick={save}>
            {campaign ? 'Save' : 'Create'}
          </Button>
        </>
      }
    >
      <div className="space-y-4">
        <Field label="Name">
          <Input
            data-autofocus
            value={name}
            onChange={(e) => {
              setName(e.target.value);
              setError(null);
            }}
            placeholder="Curse of Strahd"
          />
        </Field>
        {/* System is fixed once a campaign exists (content + characters depend on it). */}
        {!campaign && (
          <Field label="System">
            <Select value={system} onChange={(e) => setSystem(e.target.value as typeof system)}>
              {SYSTEM_OPTIONS.map((o) => (
                <option key={o.id} value={o.id}>
                  {o.label}
                </option>
              ))}
            </Select>
          </Field>
        )}
        <Field label="Description">
          <Textarea
            value={description}
            onChange={(e) => setDescription(e.target.value)}
            placeholder="A gothic horror campaign in the mists of Barovia…"
          />
        </Field>
        {error && <p className="text-sm text-danger">{error}</p>}
      </div>
    </Modal>
  );
}
