import { useEffect, useMemo, useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useNavigate, useParams, useSearchParams, Link } from 'react-router-dom';
import { ArrowLeft, Plus, Save, Send, Trash2 } from 'lucide-react';
import { toast } from 'sonner';

import {
  Button,
  Card,
  CardContent,
  Checkbox,
  Input,
  Label,
  Separator,
  Textarea,
  useAuth,
} from '@ump/shared';

import { getProjectResearch, savePapers } from '@/features/papers/api/papersApi';
import {
  emptyPaper,
  emptySource,
  findPaper,
  publishPaper,
  touchPaper,
  upsertPaper,
  type Paper,
} from '@/features/papers/domain/paperModel';
import { ProvenanceIntegrityPanel } from '@/features/papers/presentation/ProvenanceIntegrityPanel';
import { PublishGateDialog } from '@/features/papers/presentation/PublishGateDialog';

export function PaperComposerPage() {
  const { projectId = '' } = useParams();
  const [searchParams] = useSearchParams();
  const paperId = searchParams.get('paperId');
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const { user } = useAuth();

  const { data, isLoading, isError } = useQuery({
    queryKey: ['publisher', 'project-research', projectId],
    queryFn: () => getProjectResearch(projectId),
    enabled: !!projectId,
  });

  const [paper, setPaper] = useState<Paper | null>(null);
  const [gateOpen, setGateOpen] = useState(false);

  // Initialise the editing paper once research data arrives (existing paper or a fresh draft).
  useEffect(() => {
    if (!data || paper) return;
    const existing = paperId ? findPaper(data.papers, paperId) : undefined;
    setPaper(existing ?? emptyPaper());
  }, [data, paper, paperId]);

  const allPapers = data?.papers ?? [];

  // Research results available to cite (from the cockpit bundle).
  const research = useMemo(() => {
    const b = data?.bundle;
    return {
      models: b?.models ?? [],
      datasets: b?.datasets ?? [],
      milestones: b?.milestones ?? [],
    };
  }, [data]);

  const saveMutation = useMutation({
    mutationFn: (papers: Paper[]) => savePapers(projectId, papers),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['publisher'] });
    },
  });

  if (isLoading || !paper) return <p className="p-6 text-sm text-muted-foreground">Đang tải…</p>;
  if (isError) return <p className="p-6 text-sm text-destructive">Không tải được dữ liệu đề tài.</p>;

  const set = <K extends keyof Paper>(key: K, value: Paper[K]) =>
    setPaper((p) => (p ? { ...p, [key]: value } : p));

  const addSource = () => set('sources', [...paper.sources, emptySource()]);
  const removeSource = (id: string) =>
    set(
      'sources',
      paper.sources.filter((s) => s.id !== id),
    );
  const patchSource = (id: string, patch: Partial<Paper['sources'][number]>) =>
    set(
      'sources',
      paper.sources.map((s) => (s.id === id ? { ...s, ...patch } : s)),
    );

  const handleSaveDraft = async () => {
    const next = touchPaper(paper, 'Lưu bản thảo');
    try {
      await saveMutation.mutateAsync(upsertPaper(allPapers, next));
      setPaper(next);
      toast.success('Đã lưu bản thảo.');
    } catch {
      toast.error('Lưu bản thảo thất bại.');
    }
  };

  const handlePublish = async (note: string) => {
    if (!user) {
      toast.error('Phiên đăng nhập không hợp lệ.');
      return;
    }
    try {
      const published = publishPaper(paper, { id: user.id, name: user.name }, note);
      await saveMutation.mutateAsync(upsertPaper(allPapers, published));
      setPaper(published);
      setGateOpen(false);
      toast.success('Đã xuất bản bài báo.');
      navigate(`/dashboard/papers/${projectId}/${published.id}`);
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Xuất bản thất bại.');
    }
  };

  return (
    <div className="mx-auto max-w-6xl space-y-4">
      <div className="flex flex-wrap items-center justify-between gap-3">
        <Button asChild variant="ghost" size="sm" className="h-8">
          <Link to="/dashboard/papers">
            <ArrowLeft className="mr-1.5 h-4 w-4" /> Danh sách
          </Link>
        </Button>
        <div className="flex gap-2">
          <Button variant="outline" onClick={handleSaveDraft} disabled={saveMutation.isPending}>
            <Save className="mr-1.5 h-4 w-4" /> Lưu bản thảo
          </Button>
          <Button onClick={() => setGateOpen(true)}>
            <Send className="mr-1.5 h-4 w-4" /> Xuất bản…
          </Button>
        </div>
      </div>

      <div className="grid gap-4 lg:grid-cols-3">
        {/* Editor */}
        <div className="space-y-4 lg:col-span-2">
          <Card>
            <CardContent className="space-y-4 p-5">
              <div className="space-y-1.5">
                <Label htmlFor="title">Tiêu đề (tiếng Việt)</Label>
                <Input id="title" value={paper.title} onChange={(e) => set('title', e.target.value)} />
              </div>
              <div className="space-y-1.5">
                <Label htmlFor="titleEn">Title (English)</Label>
                <Input
                  id="titleEn"
                  value={paper.titleEn ?? ''}
                  onChange={(e) => set('titleEn', e.target.value)}
                />
              </div>
              <div className="grid gap-4 md:grid-cols-2">
                <div className="space-y-1.5">
                  <Label htmlFor="absVi">Tóm tắt (tiếng Việt)</Label>
                  <Textarea
                    id="absVi"
                    rows={4}
                    value={paper.abstractVi}
                    onChange={(e) => set('abstractVi', e.target.value)}
                  />
                </div>
                <div className="space-y-1.5">
                  <Label htmlFor="absEn">Abstract (English)</Label>
                  <Textarea
                    id="absEn"
                    rows={4}
                    value={paper.abstractEn ?? ''}
                    onChange={(e) => set('abstractEn', e.target.value)}
                  />
                </div>
              </div>
              <div className="space-y-1.5">
                <Label htmlFor="body">Nội dung</Label>
                <Textarea
                  id="body"
                  rows={14}
                  value={paper.body}
                  onChange={(e) => set('body', e.target.value)}
                  placeholder="Mở đầu, phương pháp, kết quả, bàn luận, kết luận…"
                />
              </div>
            </CardContent>
          </Card>

          {/* Sources editor */}
          <Card>
            <CardContent className="space-y-3 p-5">
              <div className="flex items-center justify-between">
                <h3 className="font-serif text-sm font-semibold">Nguồn tham khảo</h3>
                <Button variant="outline" size="sm" className="h-8" onClick={addSource}>
                  <Plus className="mr-1.5 h-4 w-4" /> Thêm nguồn
                </Button>
              </div>
              {paper.sources.length === 0 ? (
                <p className="text-sm text-muted-foreground">
                  Chưa có nguồn. Mọi luận điểm cần có nguồn trước khi xuất bản (INV-3).
                </p>
              ) : (
                paper.sources.map((s) => (
                  <div key={s.id} className="space-y-2 rounded-md border border-border p-3">
                    <div className="grid gap-2 md:grid-cols-2">
                      <Input
                        placeholder="Tiêu đề nguồn"
                        value={s.title}
                        onChange={(e) => patchSource(s.id, { title: e.target.value })}
                      />
                      <Input
                        placeholder="Tác giả"
                        value={s.authors ?? ''}
                        onChange={(e) => patchSource(s.id, { authors: e.target.value })}
                      />
                    </div>
                    <Input
                      placeholder="DOI hoặc URL"
                      value={s.doiOrUrl ?? ''}
                      onChange={(e) => patchSource(s.id, { doiOrUrl: e.target.value })}
                    />
                    <div className="flex items-center justify-between">
                      <label className="flex items-center gap-2 text-sm">
                        <Checkbox
                          checked={s.verifiedReal}
                          onCheckedChange={(v) => patchSource(s.id, { verifiedReal: v === true })}
                        />
                        Đã xác minh nguồn có thật
                      </label>
                      <Button
                        variant="ghost"
                        size="sm"
                        className="h-8 text-destructive"
                        onClick={() => removeSource(s.id)}
                      >
                        <Trash2 className="h-4 w-4" />
                      </Button>
                    </div>
                  </div>
                ))
              )}
            </CardContent>
          </Card>
        </div>

        {/* Right column: research results + integrity */}
        <div className="space-y-4">
          <Card>
            <CardContent className="space-y-3 p-4">
              <h3 className="font-serif text-sm font-semibold">Kết quả nghiên cứu</h3>
              <Separator />
              <ResearchList label="Mô hình" rows={research.models} field="name" />
              <ResearchList label="Bộ dữ liệu" rows={research.datasets} field="name" />
              <ResearchList label="Tiến độ" rows={research.milestones} field="title" />
            </CardContent>
          </Card>
          <ProvenanceIntegrityPanel paper={paper} />
        </div>
      </div>

      <PublishGateDialog
        paper={paper}
        open={gateOpen}
        onOpenChange={setGateOpen}
        onConfirm={handlePublish}
        publishing={saveMutation.isPending}
      />
    </div>
  );
}

function ResearchList({
  label,
  rows,
  field,
}: {
  label: string;
  rows: Array<Record<string, unknown>>;
  field: string;
}) {
  return (
    <div>
      <div className="text-xs font-medium text-muted-foreground">
        {label} ({rows.length})
      </div>
      {rows.length > 0 && (
        <ul className="mt-1 space-y-0.5">
          {rows.slice(0, 6).map((r, i) => (
            <li key={(r.id as string) ?? i} className="truncate text-sm text-foreground">
              {String(r[field] ?? r.title ?? r.name ?? '—')}
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}
