import { useCoreServices } from '@learnitive/context';
import type { SourceAnchor } from '@learnitive/latex-source';
import { projectFilePath } from '@learnitive/project-storage';
import type {
  ProjectPaperMemoryCitationContext,
  ProjectPaperMemoryCitationVerification,
} from '@learnitive/service-core';
import { Button, Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@learnitive/ui-components';
import { WsPath } from '@learnitive/ws-path';
import { BookOpen, CheckCircle2, LoaderCircle, MoreHorizontal, ShieldCheck } from 'lucide-react';
import React from 'react';

function verificationLabel(status: ProjectPaperMemoryCitationVerification['status']): string {
  if (status === 'strongly-supported') return 'Strongly supported';
  if (status === 'partial') return 'Partial';
  if (status === 'weak-conflicting') return 'Weak/conflicting';
  return 'Not verified';
}

export function CitationContextDialog({
  open,
  onOpenChange,
  wsName,
  citationKey,
  citationAnchor,
  onEdit,
  onOpenPaper,
  onOpenSufficiency,
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  wsName: string;
  citationKey?: string;
  citationAnchor?: SourceAnchor;
  onEdit?: () => void;
  onOpenPaper?: (paperId: string, page?: number) => void;
  onOpenSufficiency?: () => void;
}) {
  const { latexSource, navigation, projectPaperMemory } = useCoreServices();
  const [context, setContext] = React.useState<ProjectPaperMemoryCitationContext>();
  const [verification, setVerification] = React.useState<ProjectPaperMemoryCitationVerification>();
  const [loading, setLoading] = React.useState(false);
  const [verifying, setVerifying] = React.useState(false);
  const [error, setError] = React.useState<string>();

  React.useEffect(() => {
    if (!open || !citationKey) return;
    let cancelled = false;
    setContext(undefined);
    setVerification(undefined);
    setError(undefined);
    setLoading(true);
    void projectPaperMemory.citationContext(wsName, citationKey, citationAnchor).then((value) => {
      if (!cancelled) setContext(value);
    }).catch((reason) => {
      if (!cancelled) setError(reason instanceof Error ? reason.message : 'Unable to resolve citation context.');
    }).finally(() => {
      if (!cancelled) setLoading(false);
    });
    return () => { cancelled = true; };
  }, [citationAnchor, citationKey, open, projectPaperMemory, wsName]);

  const openBibliography = React.useCallback(() => {
    if (!context?.entry) return;
    navigation.goWsPath(WsPath.fromParts(wsName, projectFilePath(context.entry.file)).wsPath);
    onOpenChange(false);
  }, [context?.entry, navigation, onOpenChange, wsName]);

  const openLocation = React.useCallback((location: ProjectPaperMemoryCitationContext['locations'][number]) => {
    const target = WsPath.fromParts(wsName, projectFilePath(location.file)).wsPath;
    latexSource.requestSelect(target, location.line);
    navigation.goWsPath(target);
    onOpenChange(false);
  }, [latexSource, navigation, onOpenChange, wsName]);

  const verify = React.useCallback(async () => {
    if (!citationKey) return;
    setVerifying(true);
    setError(undefined);
    try {
      setVerification(await projectPaperMemory.verifyCitation(wsName, citationKey, citationAnchor));
    } catch (reason) {
      setError(reason instanceof Error ? reason.message : 'Unable to verify this citation locally.');
    } finally {
      setVerifying(false);
    }
  }, [citationAnchor, citationKey, projectPaperMemory, wsName]);

  const firstEvidencePage = verification?.evidence[0]?.pageStart;

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-h-[min(80vh,720px)] max-w-xl overflow-y-auto" data-testid="citation-context-dialog">
        <DialogHeader>
          <DialogTitle>Citation {citationKey ? `· ${citationKey}` : ''}</DialogTitle>
          <DialogDescription>Bibliography context and local evidence verification, without changing the manuscript.</DialogDescription>
        </DialogHeader>

        {loading && <div className="flex items-center gap-2 py-4 text-sm text-muted-foreground"><LoaderCircle className="size-4 animate-spin" />Loading citation context…</div>}
        {error && <div className="rounded-md border border-destructive/30 bg-destructive/5 p-2 text-xs text-destructive">{error}</div>}

        {context && (
          <div className="space-y-3 text-sm">
            <div className="rounded-lg border p-3">
              <div className="font-medium">{context.entry?.title || context.key}</div>
              {context.entry?.authors && <div className="mt-1 text-xs text-muted-foreground">{context.entry.authors}{context.entry.year ? ` · ${context.entry.year}` : ''}</div>}
              {!context.entry && <div className="mt-1 text-xs text-muted-foreground">No matching project bibliography entry.</div>}
              {context.entry?.doi && <div className="mt-1 break-all text-[11px] text-muted-foreground">DOI {context.entry.doi}</div>}
              {context.claim?.text && <div className="mt-3 rounded bg-muted/40 p-2 text-xs leading-5"><span className="font-medium">Surrounding claim:</span> {context.claim.text}</div>}
            </div>

            <div className="flex flex-wrap gap-2">
              <Button size="sm" variant="outline" disabled={!context.entry} onClick={openBibliography}>
                <BookOpen className="mr-1 size-3.5" />Open
              </Button>
              <Button size="sm" disabled={verifying || !context.localPaper?.ready || !context.claim} onClick={() => void verify()}>
                {verifying ? <LoaderCircle className="mr-1 size-3.5 animate-spin" /> : <ShieldCheck className="mr-1 size-3.5" />}
                Verify
              </Button>
              <details className="relative">
                <summary className="flex h-8 cursor-pointer list-none items-center rounded-md border px-3 text-xs font-medium hover:bg-accent">
                  <MoreHorizontal className="mr-1 size-3.5" />More
                </summary>
                <div className="absolute right-0 z-30 mt-1 min-w-52 rounded-md border bg-popover p-1 shadow-md">
                  {context.localPaper && onOpenPaper && (
                    <button type="button" className="block w-full rounded px-2 py-1.5 text-left text-xs hover:bg-accent" onClick={() => { onOpenPaper(context.localPaper!.paperId); onOpenChange(false); }}>
                      Open paper in Papers
                    </button>
                  )}
                  {onEdit && <button type="button" className="block w-full rounded px-2 py-1.5 text-left text-xs hover:bg-accent" onClick={() => { onEdit(); onOpenChange(false); }}>Edit citation</button>}
                  {onOpenSufficiency && <button type="button" className="block w-full rounded px-2 py-1.5 text-left text-xs hover:bg-accent" onClick={() => { onOpenSufficiency(); onOpenChange(false); }}>Citation sufficiency</button>}
                </div>
              </details>
            </div>

            {!context.localPaper && (
              <div className="rounded-md bg-muted/40 p-2 text-xs text-muted-foreground">
                Local verification is unavailable because this bibliography entry is not mapped to a paper in Papers. External scholarly verification is intentionally deferred to the scholarly-search phases.
              </div>
            )}
            {context.localPaper && !context.localPaper.ready && (
              <div className="rounded-md bg-muted/40 p-2 text-xs text-muted-foreground">The matching local paper exists, but its index is not ready yet.</div>
            )}

            {verification && (
              <div className="rounded-lg border p-3" data-testid="citation-verification-result">
                <div className="flex items-center gap-2 font-medium"><CheckCircle2 className="size-4" />{verificationLabel(verification.status)}</div>
                <p className="mt-2 text-xs leading-5">{verification.rationale}</p>
                {verification.evidence.length > 0 && (
                  <div className="mt-3 space-y-2">
                    {verification.evidence.map((evidence) => (
                      <button
                        type="button"
                        key={evidence.sourceId}
                        className="block w-full rounded border p-2 text-left text-xs hover:bg-accent"
                        onClick={() => onOpenPaper?.(evidence.paperId, evidence.pageStart)}
                      >
                        <div className="font-medium">{evidence.paperTitle} · p. {evidence.pageStart}{evidence.pageEnd !== evidence.pageStart ? `–${evidence.pageEnd}` : ''}</div>
                        <div className="mt-1 line-clamp-3 text-muted-foreground">{evidence.excerpt}</div>
                      </button>
                    ))}
                  </div>
                )}
                {verification.paperId && onOpenPaper && (
                  <Button className="mt-3" size="sm" variant="outline" onClick={() => onOpenPaper(verification.paperId!, firstEvidencePage)}>Open evidence</Button>
                )}
              </div>
            )}

            {context.locations.length > 1 && (
              <div className="rounded-lg border p-3">
                <div className="text-xs font-medium">Also cited at {context.locations.length - 1} other manuscript location{context.locations.length === 2 ? '' : 's'}</div>
                <div className="mt-2 flex flex-wrap gap-1.5">
                  {context.locations.slice(0, 12).map((location) => (
                    <Button key={`${location.file}:${location.anchor.from}:${location.anchor.to}`} size="sm" variant="ghost" onClick={() => openLocation(location)}>{location.file}:{location.line}</Button>
                  ))}
                </div>
              </div>
            )}
          </div>
        )}
      </DialogContent>
    </Dialog>
  );
}
