import * as React from 'react';
import { Link, useParams } from 'react-router-dom';
import { ArrowLeft, History } from 'lucide-react';

import { api, type Skill, type Revision } from '../api';
import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card';
import { Badge } from '../components/ui/badge';
import { Button } from '../components/ui/button';
import { Tabs, TabsList, TabsTrigger, TabsContent } from '../components/ui/tabs';
import { Diff } from '../components/Diff';

export function SkillDetailPage(): React.JSX.Element {
  const { name } = useParams<{ name: string }>();
  const [skill, setSkill] = React.useState<Skill | null>(null);
  const [revisions, setRevisions] = React.useState<Revision[] | null>(null);
  const [error, setError] = React.useState<string | null>(null);
  const [tab, setTab] = React.useState('content');

  React.useEffect(() => {
    let cancelled = false;
    async function load(): Promise<void> {
      try {
        const list = await api.get<Skill[]>('/api/v1/skills');
        const match = list.find((s) => s.name === name);
        if (!match) {
          if (!cancelled) setError(`Skill "${String(name)}" not found`);
          return;
        }
        const full = await api.get<Skill>(`/api/v1/skills/${match.id}`);
        if (!cancelled) setSkill(full);
        const revs = await api.get<Revision[]>(
          `/api/v1/revisions?resourceType=skill&resourceId=${full.id}`,
        );
        if (!cancelled) setRevisions(revs);
      } catch (err) {
        if (!cancelled) setError((err as Error).message);
      }
    }
    void load();
    return () => { cancelled = true; };
  }, [name]);

  if (error !== null) return (
    <div className="space-y-3">
      <Link to="/skills" className="inline-flex items-center gap-1 text-sm text-(--color-primary) hover:underline">
        <ArrowLeft className="size-3.5" /> Skills
      </Link>
      <div className="text-(--color-danger)">Error: {error}</div>
    </div>
  );
  if (skill === null) return <div className="text-(--color-fg-muted)">Loading…</div>;

  const fileEntries = Object.entries(skill.files);
  const metadataKeys = Object.keys(skill.metadata);

  return (
    <div className="space-y-6">
      <Link to="/skills" className="inline-flex items-center gap-1 text-sm text-(--color-primary) hover:underline">
        <ArrowLeft className="size-3.5" /> Skills
      </Link>

      <header className="flex items-start justify-between gap-4">
        <div className="space-y-1">
          <div className="flex items-center gap-3">
            <h1 className="font-mono text-2xl font-semibold tracking-tight">{skill.name}</h1>
            <Badge variant="info">v{skill.semver}</Badge>
          </div>
          {skill.description && (
            <p className="text-sm text-(--color-fg-muted)">{skill.description}</p>
          )}
          <div className="flex items-center gap-3 pt-1 text-xs text-(--color-fg-subtle)">
            <span>id: <code className="font-mono">{skill.id}</code></span>
            {skill.project?.name && <span>project: <code className="font-mono">{skill.project.name}</code></span>}
            {skill.agent?.name && <span>agent: <code className="font-mono">{skill.agent.name}</code></span>}
          </div>
        </div>
      </header>

      <Tabs value={tab} onValueChange={setTab}>
        <TabsList>
          <TabsTrigger value="content">SKILL.md</TabsTrigger>
          {fileEntries.length > 0 && <TabsTrigger value="files">Files ({fileEntries.length})</TabsTrigger>}
          {metadataKeys.length > 0 && <TabsTrigger value="metadata">Metadata</TabsTrigger>}
          <TabsTrigger value="history">History ({revisions?.length ?? '…'})</TabsTrigger>
        </TabsList>

        <TabsContent value="content">
          <Card>
            <CardContent className="p-5">
              <pre className="overflow-x-auto whitespace-pre-wrap font-mono text-xs leading-relaxed text-(--color-fg)">
                {skill.content}
              </pre>
            </CardContent>
          </Card>
        </TabsContent>

        {fileEntries.length > 0 && (
          <TabsContent value="files">
            <div className="space-y-3">
              {fileEntries.map(([path, content]) => (
                <Card key={path}>
                  <CardHeader>
                    <CardTitle className="font-mono text-sm">{path}</CardTitle>
                  </CardHeader>
                  <CardContent>
                    <pre className="overflow-x-auto rounded bg-(--color-canvas) p-3 font-mono text-xs">{content}</pre>
                  </CardContent>
                </Card>
              ))}
            </div>
          </TabsContent>
        )}

        {metadataKeys.length > 0 && (
          <TabsContent value="metadata">
            <Card>
              <CardContent className="p-5">
                <pre className="overflow-x-auto rounded bg-(--color-canvas) p-3 font-mono text-xs">
                  {JSON.stringify(skill.metadata, null, 2)}
                </pre>
              </CardContent>
            </Card>
          </TabsContent>
        )}

        <TabsContent value="history">
          <RevisionHistorySection revisions={revisions} skill={skill} />
        </TabsContent>
      </Tabs>
    </div>
  );
}

function RevisionHistorySection({
  revisions,
  skill,
}: {
  revisions: Revision[] | null;
  skill: Skill;
}): React.JSX.Element {
  const [diffAgainst, setDiffAgainst] = React.useState<string | null>(null);

  if (revisions === null) return <div className="text-(--color-fg-muted)">Loading history…</div>;
  if (revisions.length === 0) {
    return <Card><CardContent className="p-8 text-center text-(--color-fg-muted)">No revisions yet.</CardContent></Card>;
  }

  const target = revisions.find((r) => r.id === diffAgainst);
  const targetContent = (target?.body as { content?: string } | undefined)?.content ?? '';

  return (
    <div className="space-y-4">
      <div className="space-y-2">
        {revisions.map((rev) => (
          <Card key={rev.id} className="cursor-pointer transition-colors hover:bg-(--color-surface-hi)" onClick={() => setDiffAgainst(rev.id === diffAgainst ? null : rev.id)}>
            <CardContent className="flex items-center justify-between gap-3 p-4">
              <div className="flex items-center gap-3">
                <History className="size-4 text-(--color-fg-muted)" />
                <Badge variant={rev.id === diffAgainst ? 'info' : 'outline'}>v{rev.semver}</Badge>
                {rev.note && <span className="text-sm text-(--color-fg-muted)">{rev.note}</span>}
              </div>
              <span className="text-xs text-(--color-fg-subtle)">
                {new Date(rev.createdAt).toLocaleString()}
              </span>
            </CardContent>
          </Card>
        ))}
      </div>

      {target && (
        <Card>
          <CardHeader className="flex-row items-center justify-between space-y-0">
            <CardTitle className="text-sm">
              Diff: v{target.semver} ↔ live (v{skill.semver})
            </CardTitle>
            <Button variant="ghost" size="sm" onClick={() => setDiffAgainst(null)}>Close</Button>
          </CardHeader>
          <CardContent>
            <Diff before={targetContent} after={skill.content} />
          </CardContent>
        </Card>
      )}
    </div>
  );
}
