'use client';

import { useState } from 'react';
import Link from 'next/link';
import { useParams, useRouter } from 'next/navigation';
import { AgentWorkspaceShell } from '@/components/agent-workspace/agent-workspace-shell';
import { DeleteThreadButton } from '@/components/threads/delete-thread-button';
import { useMutation, useQuery } from 'convex/react';
import { ArrowUpRight, CheckCircle2, Play, XCircle } from 'lucide-react';
import { toast } from 'sonner';

import type { Id } from '@spoon/backend/convex/_generated/dataModel.js';
import { api } from '@spoon/backend/convex/_generated/api.js';
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
  Badge,
  Button,
  Card,
  CardContent,
  CardHeader,
  CardTitle,
} from '@spoon/ui';

const ThreadDetailPage = () => {
  const router = useRouter();
  const params = useParams<{ threadId: string }>();
  const threadId = params.threadId as Id<'threads'>;
  const details = useQuery(api.threads.get, { threadId });
  const createJob = useMutation(api.agentJobs.createForThread);
  const markResolved = useMutation(api.threads.markResolved);
  const cancel = useMutation(api.threads.cancel);
  const [queueing, setQueueing] = useState(false);

  if (details === undefined) {
    return <main className='text-muted-foreground p-6'>Loading thread...</main>;
  }

  const { thread, spoon, latestJob } = details;
  if (latestJob && spoon) {
    return (
      <main className='space-y-4'>
        <Button asChild variant='ghost' size='sm'>
          <Link href={`/spoons/${spoon._id}`}>
            <ArrowUpRight className='size-4 rotate-180' />
            Back to Spoon
          </Link>
        </Button>
        <AgentWorkspaceShell jobId={latestJob._id} />
      </main>
    );
  }

  const terminalThread = [
    'resolved',
    'ignored',
    'failed',
    'cancelled',
  ].includes(thread.status);
  const canQueueRun =
    spoon &&
    (!latestJob ||
      ['failed', 'cancelled', 'timed_out', 'draft_pr_opened'].includes(
        latestJob.status,
      ) ||
      ['stopped', 'expired', 'failed'].includes(
        latestJob.workspaceStatus ?? '',
      ));
  const jobType =
    thread.source === 'merge_conflict'
      ? ('conflict_resolution' as const)
      : thread.source === 'upstream_update'
        ? ('maintenance_review' as const)
        : ('user_change' as const);

  const startRun = async () => {
    setQueueing(true);
    try {
      await createJob({ threadId, jobType });
      toast.success('Workspace run queued.');
      router.replace(`/threads/${threadId}`);
    } catch (error) {
      console.error(error);
      toast.error('Could not queue workspace run.');
    } finally {
      setQueueing(false);
    }
  };

  return (
    <main className='space-y-6'>
      <div className='flex flex-col justify-between gap-4 md:flex-row md:items-start'>
        <div>
          <div className='flex flex-wrap items-center gap-2'>
            <h1 className='text-3xl font-semibold tracking-normal'>
              {thread.title}
            </h1>
            <Badge>{thread.status.replaceAll('_', ' ')}</Badge>
            <Badge variant='outline'>
              {thread.source.replaceAll('_', ' ')}
            </Badge>
            {thread.maintenanceOutcome ? (
              <Badge variant='secondary'>
                {thread.maintenanceOutcome.replaceAll('_', ' ')}
              </Badge>
            ) : null}
          </div>
          <p className='text-muted-foreground mt-2 max-w-3xl'>
            {thread.summary ?? 'No summary has been recorded yet.'}
          </p>
          {spoon ? (
            <Button variant='link' className='mt-2 h-auto p-0' asChild>
              <Link href={`/spoons/${spoon._id}`}>
                {spoon.name}
                <ArrowUpRight className='size-3' />
              </Link>
            </Button>
          ) : null}
        </div>
        <div className='flex flex-wrap gap-2'>
          {latestJob ? (
            <Button variant='outline' asChild>
              <Link href={`/threads/${threadId}`}>Open workspace</Link>
            </Button>
          ) : null}
          {latestJob?.pullRequestUrl ? (
            <Button asChild>
              <a
                href={latestJob.pullRequestUrl}
                target='_blank'
                rel='noreferrer'
              >
                Open PR
              </a>
            </Button>
          ) : null}
          {canQueueRun ? (
            <Button disabled={queueing} onClick={() => void startRun()}>
              <Play className='size-4' />
              {latestJob ? 'Rerun' : 'Start workspace run'}
            </Button>
          ) : null}
          {!terminalThread ? (
            <>
              <AlertDialog>
                <AlertDialogTrigger asChild>
                  <Button variant='outline'>
                    <CheckCircle2 className='size-4' />
                    Resolve
                  </Button>
                </AlertDialogTrigger>
                <AlertDialogContent>
                  <AlertDialogHeader>
                    <AlertDialogTitle>Mark thread resolved?</AlertDialogTitle>
                    <AlertDialogDescription>
                      This closes the thread without deleting its history.
                    </AlertDialogDescription>
                  </AlertDialogHeader>
                  <AlertDialogFooter>
                    <AlertDialogCancel>Keep open</AlertDialogCancel>
                    <AlertDialogAction
                      onClick={() => {
                        void markResolved({ threadId }).then(() =>
                          toast.success('Thread resolved.'),
                        );
                      }}
                    >
                      Resolve thread
                    </AlertDialogAction>
                  </AlertDialogFooter>
                </AlertDialogContent>
              </AlertDialog>
              <AlertDialog>
                <AlertDialogTrigger asChild>
                  <Button variant='outline'>
                    <XCircle className='size-4' />
                    Cancel
                  </Button>
                </AlertDialogTrigger>
                <AlertDialogContent>
                  <AlertDialogHeader>
                    <AlertDialogTitle>Cancel this thread?</AlertDialogTitle>
                    <AlertDialogDescription>
                      This marks the thread as cancelled. It does not delete
                      existing workspace history.
                    </AlertDialogDescription>
                  </AlertDialogHeader>
                  <AlertDialogFooter>
                    <AlertDialogCancel>Keep open</AlertDialogCancel>
                    <AlertDialogAction
                      variant='destructive'
                      onClick={() => {
                        void cancel({ threadId }).then(() =>
                          toast.success('Thread cancelled.'),
                        );
                      }}
                    >
                      Cancel thread
                    </AlertDialogAction>
                  </AlertDialogFooter>
                </AlertDialogContent>
              </AlertDialog>
            </>
          ) : null}
          <DeleteThreadButton threadId={threadId} redirectTo='/threads' />
        </div>
      </div>

      <div className='grid gap-6 xl:grid-cols-[1fr_320px]'>
        <Card className='shadow-none'>
          <CardHeader>
            <CardTitle>Workspace</CardTitle>
          </CardHeader>
          <CardContent className='space-y-4 text-sm'>
            <p className='text-muted-foreground'>
              Threads open into a full workspace where you can review agent
              activity, edit files, inspect diffs, and reply to the agent.
            </p>
            {canQueueRun ? (
              <Button disabled={queueing} onClick={() => void startRun()}>
                <Play className='size-4' />
                {latestJob ? 'Create new workspace run' : 'Start workspace run'}
              </Button>
            ) : (
              <p className='text-muted-foreground'>
                This thread does not currently have a workspace that can be
                opened.
              </p>
            )}
          </CardContent>
        </Card>

        <Card className='shadow-none'>
          <CardHeader>
            <CardTitle>Thread state</CardTitle>
          </CardHeader>
          <CardContent className='space-y-3 text-sm'>
            <div>
              <p className='text-muted-foreground'>Priority</p>
              <p className='font-medium capitalize'>{thread.priority}</p>
            </div>
            <div>
              <p className='text-muted-foreground'>Upstream range</p>
              <p className='font-mono text-xs break-all'>
                {thread.upstreamFrom ?? 'unknown'} →{' '}
                {thread.upstreamTo ?? 'unknown'}
              </p>
            </div>
            <div>
              <p className='text-muted-foreground'>Latest job</p>
              <p className='font-medium'>
                {latestJob?.status.replaceAll('_', ' ') ?? 'No job queued'}
              </p>
            </div>
          </CardContent>
        </Card>
      </div>
    </main>
  );
};

export default ThreadDetailPage;
