"use client";

import { useState, useEffect, useCallback, useRef } from "react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  apiBase,
  financeApi,
  type FinanceRecordRead,
  type FinanceSyncResponse,
  type FinanceSyncResult,
} from "@/lib/api/client";
import { Download, Inbox, Loader2, Mail, FileText, Upload } from "lucide-react";
import { toast } from "sonner";

export default function FinancePage() {
  const [months, setMonths] = useState<string[]>([]);
  const [selectedMonth, setSelectedMonth] = useState<string>("");
  const [records, setRecords] = useState<FinanceRecordRead[]>([]);
  const [loadingMonths, setLoadingMonths] = useState(true);
  const [loadingRecords, setLoadingRecords] = useState(false);
  const [syncing, setSyncing] = useState(false);
  const [lastSync, setLastSync] = useState<FinanceSyncResponse | null>(null);
  const [uploadDialogOpen, setUploadDialogOpen] = useState(false);
  const [uploadFile, setUploadFile] = useState<File | null>(null);
  const [previewUrl, setPreviewUrl] = useState<string | null>(null);
  const [uploading, setUploading] = useState(false);
  const [reviewRecord, setReviewRecord] = useState<FinanceRecordRead | null>(null);
  const [reviewAmount, setReviewAmount] = useState("");
  const [reviewDate, setReviewDate] = useState("");
  const [savingReview, setSavingReview] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const previewUrlRef = useRef<string | null>(null);

  const loadMonths = useCallback(async () => {
    try {
      const list = await financeApi.listMonths();
      setMonths(list);
      if (list.length > 0 && !selectedMonth) setSelectedMonth(list[0]);
    } catch {
      toast.error("加载月份列表失败");
    } finally {
      setLoadingMonths(false);
    }
  }, [selectedMonth]);

  const loadRecords = useCallback(async () => {
    if (!selectedMonth) {
      setRecords([]);
      return;
    }
    setLoadingRecords(true);
    try {
      const list = await financeApi.listRecords(selectedMonth);
      setRecords(list);
    } catch {
      toast.error("加载记录失败");
    } finally {
      setLoadingRecords(false);
    }
  }, [selectedMonth]);

  useEffect(() => {
    loadMonths();
  }, [loadMonths]);

  useEffect(() => {
    loadRecords();
  }, [loadRecords]);

  const handleSync = async () => {
    setSyncing(true);
    toast.loading("正在同步邮箱…", { id: "finance-sync" });
    try {
      const res: FinanceSyncResponse = await financeApi.sync();
      setLastSync(res);
      toast.dismiss("finance-sync");
      if (res.new_files > 0) {
        toast.success(`发现 ${res.new_files} 个新文件`);
        await loadMonths();
        if (selectedMonth) await loadRecords();
      } else {
        toast.info("收件箱已是最新，无新文件");
      }
    } catch (e) {
      toast.dismiss("finance-sync");
      toast.error(e instanceof Error ? e.message : "同步失败");
    } finally {
      setSyncing(false);
    }
  };

  const resetUploadDialog = useCallback(() => {
    setUploadFile(null);
    if (previewUrlRef.current) {
      URL.revokeObjectURL(previewUrlRef.current);
      previewUrlRef.current = null;
    }
    setPreviewUrl(null);
    setReviewRecord(null);
    setReviewAmount("");
    setReviewDate("");
    if (fileInputRef.current) fileInputRef.current.value = "";
  }, []);

  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    const allowed = ["application/pdf", "image/jpeg", "image/png", "image/webp"];
    if (!allowed.includes(file.type) && !file.name.match(/\.(pdf|jpg|jpeg|png|webp)$/i)) {
      toast.error("仅支持 PDF、JPG、PNG、WEBP");
      return;
    }
    if (previewUrlRef.current) {
      URL.revokeObjectURL(previewUrlRef.current);
      previewUrlRef.current = null;
    }
    setUploadFile(file);
    setReviewRecord(null);
    setReviewAmount("");
    setReviewDate("");
    if (file.type.startsWith("image/")) {
      const url = URL.createObjectURL(file);
      previewUrlRef.current = url;
      setPreviewUrl(url);
    } else {
      setPreviewUrl(null);
    }
  };

  const handleUploadSubmit = async () => {
    if (!uploadFile) return;
    setUploading(true);
    try {
      const record = await financeApi.uploadInvoice(uploadFile);
      setReviewRecord(record);
      setReviewAmount(record.amount != null ? String(record.amount) : "");
      setReviewDate(record.billing_date || "");
      toast.success("已上传，请核对金额与日期");
      await loadMonths();
      if (selectedMonth === record.month) await loadRecords();
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "上传失败");
    } finally {
      setUploading(false);
    }
  };

  const handleReviewSave = async () => {
    if (!reviewRecord) return;
    const amount = reviewAmount.trim() ? parseFloat(reviewAmount) : null;
    const billing_date = reviewDate.trim() || null;
    setSavingReview(true);
    try {
      await financeApi.updateRecord(reviewRecord.id, { amount, billing_date });
      toast.success("已保存");
      setUploadDialogOpen(false);
      resetUploadDialog();
      if (selectedMonth) await loadRecords();
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "保存失败");
    } finally {
      setSavingReview(false);
    }
  };

  const handleDownloadZip = async () => {
    if (!selectedMonth) {
      toast.error("请先选择月份");
      return;
    }
    try {
      await financeApi.downloadMonth(selectedMonth);
      toast.success(`已下载 ${selectedMonth}.zip`);
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "下载失败");
    }
  };

  const formatDate = (s: string) =>
    new Date(s).toLocaleString("zh-CN", {
      year: "numeric",
      month: "2-digit",
      day: "2-digit",
      hour: "2-digit",
      minute: "2-digit",
    });

  const typeLabel: Record<string, string> = {
    invoices: "发票",
    bank_records: "流水",
    statements: "流水",
    receipts: "回执",
    manual: "手动上传",
    others: "其他",
  };

  const monthlyTotal = records.reduce((sum, r) => sum + (r.amount ?? 0), 0);
  const totalInvoicesThisMonth = records.filter(
    (r) => r.amount != null && (r.type === "manual" || r.type === "invoices")
  ).reduce((s, r) => s + (r.amount ?? 0), 0);

  return (
    <div className="p-6 max-w-5xl">
      <div className="flex flex-col gap-6">
        <div className="flex flex-wrap items-center justify-between gap-4">
          <div>
            <h1 className="text-xl font-semibold">财务归档</h1>
            <p className="text-sm text-muted-foreground mt-0.5">
              从网易邮箱同步发票、回执、流水等附件，或手动上传发票
            </p>
          </div>
          <div className="flex flex-wrap items-center gap-3">
            {selectedMonth && (
              <Card className="py-2 px-4">
                <p className="text-xs text-muted-foreground">本月发票合计</p>
                <p className="text-lg font-semibold">
                  ¥{totalInvoicesThisMonth.toLocaleString("zh-CN", { minimumFractionDigits: 2 })}
                </p>
              </Card>
            )}
            <Button
              variant="outline"
              onClick={() => {
                setUploadDialogOpen(true);
                resetUploadDialog();
              }}
            >
              <Upload className="h-4 w-4" />
              <span className="ml-2">上传发票</span>
            </Button>
            <Button onClick={handleSync} disabled={syncing} size="default">
              {syncing ? (
                <Loader2 className="h-4 w-4 animate-spin" />
              ) : (
                <Mail className="h-4 w-4" />
              )}
              <span className="ml-2">同步邮箱</span>
            </Button>
          </div>
        </div>

        {/* Upload Invoice Dialog */}
        <Dialog open={uploadDialogOpen} onOpenChange={(open) => {
          setUploadDialogOpen(open);
          if (!open) resetUploadDialog();
        }}>
          <DialogContent className="sm:max-w-md">
            <DialogHeader>
              <DialogTitle>{reviewRecord ? "核对金额与日期" : "上传发票"}</DialogTitle>
            </DialogHeader>
            {!reviewRecord ? (
              <>
                <div
                  onClick={() => fileInputRef.current?.click()}
                  className="border-2 border-dashed rounded-lg p-6 text-center cursor-pointer hover:bg-muted/50"
                >
                  <input
                    ref={fileInputRef}
                    type="file"
                    accept=".pdf,.jpg,.jpeg,.png,.webp"
                    className="hidden"
                    onChange={handleFileSelect}
                  />
                  {previewUrl ? (
                    <img src={previewUrl} alt="预览" className="max-h-48 mx-auto object-contain" />
                  ) : uploadFile ? (
                    <p className="text-sm font-medium">{uploadFile.name}</p>
                  ) : (
                    <p className="text-sm text-muted-foreground">点击或拖拽 PDF/图片到此处</p>
                  )}
                </div>
                <DialogFooter>
                  <Button variant="outline" onClick={() => setUploadDialogOpen(false)}>
                    取消
                  </Button>
                  <Button onClick={handleUploadSubmit} disabled={!uploadFile || uploading}>
                    {uploading ? <Loader2 className="h-4 w-4 animate-spin" /> : null}
                    <span className="ml-2">上传并识别</span>
                  </Button>
                </DialogFooter>
              </>
            ) : (
              <>
                {previewUrl && (
                  <img src={previewUrl} alt="预览" className="max-h-32 rounded border object-contain" />
                )}
                <div className="grid gap-2">
                  <Label>金额</Label>
                  <Input
                    type="number"
                    step="0.01"
                    value={reviewAmount}
                    onChange={(e) => setReviewAmount(e.target.value)}
                    placeholder="可手动修改"
                  />
                </div>
                <div className="grid gap-2">
                  <Label>开票日期</Label>
                  <Input
                    type="date"
                    value={reviewDate}
                    onChange={(e) => setReviewDate(e.target.value)}
                  />
                </div>
                <DialogFooter>
                  <Button variant="outline" onClick={() => { setReviewRecord(null); setReviewAmount(""); setReviewDate(""); }}>
                    继续上传
                  </Button>
                  <Button onClick={handleReviewSave} disabled={savingReview}>
                    {savingReview ? <Loader2 className="h-4 w-4 animate-spin" /> : null}
                    <span className="ml-2">保存并关闭</span>
                  </Button>
                </DialogFooter>
              </>
            )}
          </DialogContent>
        </Dialog>

        {/* Sync History / Last sync */}
        <Card>
          <CardHeader className="py-3">
            <CardTitle className="text-base flex items-center gap-2">
              <Inbox className="h-4 w-4" />
              同步记录
            </CardTitle>
          </CardHeader>
          <CardContent className="py-2">
            {lastSync !== null ? (
              <>
                <p className="text-sm text-muted-foreground">
                  最近一次同步：发现 <strong>{lastSync.new_files}</strong> 个新文件
                </p>
                {lastSync.details && lastSync.details.length > 0 && (
                  <div className="mt-2 space-y-2">
                    {Object.entries(
                      lastSync.details.reduce<Record<string, FinanceSyncResult[]>>(
                        (acc, item) => {
                          const t = item.type || "others";
                          if (!acc[t]) acc[t] = [];
                          acc[t].push(item);
                          return acc;
                        },
                        {},
                      ),
                    ).map(([t, items]) => (
                      <div key={t}>
                        <p className="text-xs font-medium text-muted-foreground">
                          {typeLabel[t] ?? t}（{items.length}）
                        </p>
                        <ul className="mt-1 ml-4 list-disc space-y-0.5 text-xs text-muted-foreground">
                          {items.map((it) => (
                            <li key={it.id}>
                              {it.file_name}
                              <span className="ml-1 text-[11px] text-muted-foreground/80">
                                [{it.month}]
                              </span>
                            </li>
                          ))}
                        </ul>
                      </div>
                    ))}
                  </div>
                )}
              </>
            ) : (
              <p className="text-sm text-muted-foreground">
                点击「同步邮箱」后，将显示本次同步结果
              </p>
            )}
          </CardContent>
        </Card>

        {/* Month + Download */}
        <Card>
          <CardHeader className="py-3">
            <div className="flex flex-wrap items-center justify-between gap-3">
              <CardTitle className="text-base">按月份查看</CardTitle>
              <div className="flex items-center gap-2">
                <Select
                  value={selectedMonth}
                  onValueChange={setSelectedMonth}
                  disabled={loadingMonths}
                >
                  <SelectTrigger className="w-[160px]">
                    <SelectValue placeholder="选择月份" />
                  </SelectTrigger>
                  <SelectContent>
                    {months.map((m) => (
                      <SelectItem key={m} value={m}>
                        {m}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <Button
                  variant="outline"
                  size="sm"
                  onClick={handleDownloadZip}
                  disabled={!selectedMonth || records.length === 0}
                >
                  <Download className="h-4 w-4" />
                  <span className="ml-1.5">下载本月全部 (.zip)</span>
                </Button>
              </div>
            </div>
          </CardHeader>
          <CardContent>
            {loadingRecords ? (
              <p className="text-sm text-muted-foreground flex items-center gap-1 py-4">
                <Loader2 className="h-4 w-4 animate-spin" />
                加载中…
              </p>
            ) : records.length === 0 ? (
              <p className="text-sm text-muted-foreground py-4">
                {selectedMonth ? "该月份暂无归档文件" : "请选择月份或先同步邮箱"}
              </p>
            ) : (
              <>
                <p className="text-xs text-muted-foreground mb-2">
                  类型：发票 / 回执 / 流水。同步的发票已按「日期_金额_原文件名」重命名。
                </p>
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>类型</TableHead>
                    <TableHead>文件名</TableHead>
                    <TableHead>金额</TableHead>
                    <TableHead>开票/归档时间</TableHead>
                    <TableHead className="w-[100px]">操作</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {records.map((r) => (
                    <TableRow key={r.id}>
                      <TableCell>
                        <span className="text-muted-foreground">
                          {typeLabel[r.type] ?? r.type}
                        </span>
                      </TableCell>
                      <TableCell className="font-medium">{r.file_name}</TableCell>
                      <TableCell>
                        {r.amount != null
                          ? `¥${Number(r.amount).toLocaleString("zh-CN", { minimumFractionDigits: 2 })}`
                          : "—"}
                      </TableCell>
                      <TableCell className="text-muted-foreground text-sm">
                        {r.billing_date || formatDate(r.created_at)}
                      </TableCell>
                      <TableCell>
                        <a
                          href={`${apiBase()}${r.file_path.startsWith("/") ? "" : "/"}${r.file_path}`}
                          target="_blank"
                          rel="noopener noreferrer"
                          className="text-primary text-sm hover:underline inline-flex items-center gap-1"
                        >
                          <FileText className="h-3.5 w-3.5" />
                          下载
                        </a>
                      </TableCell>
                    </TableRow>
                  ))}
                  <TableRow className="bg-muted/30 font-medium">
                    <TableCell colSpan={2}>本月合计</TableCell>
                    <TableCell>
                      ¥{monthlyTotal.toLocaleString("zh-CN", { minimumFractionDigits: 2 })}
                    </TableCell>
                    <TableCell colSpan={2} />
                  </TableRow>
                </TableBody>
              </Table>
              </>
            )}
          </CardContent>
        </Card>
      </div>
    </div>
  );
}
