"use client";

import { Suspense, useEffect, useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { Button, Chip, Modal, Pagination, Spinner, Table } from "@heroui/react";
import Link from "next/link";
import { useSearchParams } from "next/navigation";
import { TrashBin, ArrowRotateRight } from "@gravity-ui/icons";
import { api } from "@/lib/api";
import { useSession } from "@/lib/auth-client";
import dayjs from "@/lib/dayjs";

const LIMIT = 15;

const idTagRejectLabelMap: Record<string, string> = {
  Blocked: "卡片不可用或余额不足",
  Expired: "卡片已过期",
  Invalid: "卡片无效",
  ConcurrentTx: "该卡已有进行中的订单",
};

const stopReasonLabelMap: Record<string, string> = {
  EmergencyStop: "紧急停止",
  EVDisconnected: "车辆断开",
  HardReset: "硬重启",
  Local: "本地结束",
  Other: "其他原因",
  PowerLoss: "断电结束",
  Reboot: "重启结束",
  Remote: "远程结束",
  SoftReset: "软重启",
  UnlockCommand: "解锁结束",
};

const stopReasonColorMap: Record<string, "success" | "warning" | "danger" | "default"> = {
  Local: "success",
  EVDisconnected: "success",
  Remote: "warning",
  UnlockCommand: "warning",
  EmergencyStop: "danger",
  PowerLoss: "danger",
  HardReset: "danger",
  SoftReset: "warning",
  Reboot: "warning",
  Other: "default",
};

function formatDuration(start: string, stop: string | null): string {
  if (!stop) return "进行中";
  const min = dayjs(stop).diff(dayjs(start), "minute");
  if (min < 60) return `${min} 分钟`;
  const h = Math.floor(min / 60);
  const m = min % 60;
  return `${h}h ${m}m`;
}

function TransactionsPageContent() {
  const searchParams = useSearchParams();
  const { data: sessionData } = useSession();
  const isAdmin = sessionData?.user?.role === "admin";
  const statusFromQuery = searchParams.get("status");
  const initialStatus: "all" | "active" | "completed" =
    statusFromQuery === "active" || statusFromQuery === "completed" ? statusFromQuery : "all";

  const [page, setPage] = useState(1);
  const [status, setStatus] = useState<"all" | "active" | "completed">(initialStatus);
  const [stoppingId, setStoppingId] = useState<number | null>(null);
  const [deletingId, setDeletingId] = useState<number | null>(null);

  useEffect(() => {
    if (status !== initialStatus) {
      setStatus(initialStatus);
      setPage(1);
    }
    // We intentionally depend on searchParams-derived value only.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [initialStatus]);

  const {
    data,
    isPending: loading,
    isFetching: refreshing,
    refetch,
  } = useQuery({
    queryKey: ["transactions", page, status],
    queryFn: () =>
      api.transactions.list({
        page,
        limit: LIMIT,
        status: status === "all" ? undefined : status,
      }),
    refetchInterval: 3_000,
  });

  const handleStatusChange = (s: typeof status) => {
    setStatus(s);
    setPage(1);
  };

  const handleStop = async (id: number) => {
    setStoppingId(id);
    try {
      await api.transactions.stop(id);
      await refetch();
    } finally {
      setStoppingId(null);
    }
  };

  const handleDelete = async (id: number) => {
    setDeletingId(id);
    try {
      await api.transactions.delete(id);
      await refetch();
    } finally {
      setDeletingId(null);
    }
  };

  const pages = data ? Array.from({ length: data.totalPages }, (_, i) => i + 1) : [];

  return (
    <div className="space-y-4">
      <div className="flex flex-wrap items-start justify-between gap-3">
        <div>
          <h1 className="text-xl font-semibold text-foreground">充电记录</h1>
          <p className="mt-0.5 text-sm text-muted">共 {data?.total ?? "—"} 条</p>
        </div>
        <div className="flex items-center gap-2">
          <Button
            isIconOnly
            size="sm"
            variant="ghost"
            isDisabled={refreshing}
            onPress={() => refetch()}
            aria-label="刷新"
          >
            <ArrowRotateRight className={`size-4 ${refreshing ? "animate-spin" : ""}`} />
          </Button>
          <div className="flex gap-1.5 rounded-xl bg-surface-secondary p-1">
            {(["all", "active", "completed"] as const).map((s) => (
              <button
                key={s}
                onClick={() => handleStatusChange(s)}
                className={`rounded-lg px-3 py-1 text-sm font-medium transition-colors ${
                  status === s
                    ? "bg-surface text-foreground shadow-sm"
                    : "text-muted hover:text-foreground"
                }`}
              >
                {s === "all" ? "全部" : s === "active" ? "进行中" : "已完成"}
              </button>
            ))}{" "}
          </div>{" "}
        </div>
      </div>

      <Table>
        <Table.ScrollContainer>
          <Table.Content aria-label="充电记录" className="min-w-200">
            <Table.Header>
              <Table.Column isRowHeader>ID</Table.Column>
              <Table.Column>充电桩</Table.Column>
              <Table.Column>接口</Table.Column>
              <Table.Column>储值卡</Table.Column>
              <Table.Column>状态</Table.Column>
              <Table.Column>开始时间</Table.Column>
              <Table.Column>时长</Table.Column>
              <Table.Column>电量 (kWh)</Table.Column>
              <Table.Column>费用 (元)</Table.Column>
              <Table.Column>停止原因</Table.Column>
              <Table.Column>{""}</Table.Column>
            </Table.Header>
            <Table.Body
              renderEmptyState={() => (
                <div className="py-8 text-center text-sm text-muted">
                  {loading ? "加载中…" : "暂无记录"}
                </div>
              )}
            >
              {(data?.data ?? []).map((tx) => (
                <Table.Row key={tx.id} id={tx.id}>
                  <Table.Cell className="font-mono text-sm">
                    <Link
                      href={`/dashboard/transactions/${tx.id}`}
                      className="text-accent hover:text-accent/80"
                    >
                      {tx.id}
                    </Link>
                  </Table.Cell>
                  <Table.Cell>
                    <div className="flex flex-col">
                      <span>{tx.chargePointDeviceName ?? tx.chargePointIdentifier ?? "—"}</span>
                      {isAdmin && tx.chargePointDeviceName && tx.chargePointIdentifier && (
                        <span className="font-mono text-xs text-muted">{tx.chargePointIdentifier}</span>
                      )}
                    </div>
                  </Table.Cell>
                  <Table.Cell>{tx.connectorNumber ?? "—"}</Table.Cell>
                  <Table.Cell className="font-mono">{tx.idTag}</Table.Cell>
                  <Table.Cell>
                    {tx.stopTimestamp && tx.stopReason === "DeAuthorized" ? (
                      <Chip color="danger" size="sm" variant="soft">
                        已拒绝
                      </Chip>
                    ) : tx.stopTimestamp ? (
                      <Chip color="success" size="sm" variant="soft">
                        已完成
                      </Chip>
                    ) : (
                      <Chip color="warning" size="sm" variant="soft">
                        进行中
                      </Chip>
                    )}
                  </Table.Cell>
                  <Table.Cell className="whitespace-nowrap text-sm">
                    {dayjs(tx.startTimestamp).format("YYYY/M/D HH:mm:ss")}
                  </Table.Cell>
                  <Table.Cell className="text-sm">
                    {formatDuration(tx.startTimestamp, tx.stopTimestamp)}
                  </Table.Cell>
                  <Table.Cell className="tabular-nums">
                    {tx.energyWh != null ? (
                      (tx.energyWh / 1000).toFixed(3)
                    ) : tx.liveEnergyWh != null ? (
                      <span className="inline-flex items-center gap-1">
                        {(tx.liveEnergyWh / 1000).toFixed(3)}
                        <span className="rounded bg-warning-soft px-1 py-0.5 text-[10px] font-semibold text-warning leading-none text-nowrap">
                          预估
                        </span>
                      </span>
                    ) : (
                      "—"
                    )}
                  </Table.Cell>
                  <Table.Cell className="tabular-nums">
                    {tx.chargeAmount != null ? (
                      `¥${(tx.chargeAmount / 100).toFixed(2)}`
                    ) : tx.estimatedCost != null ? (
                      <span className="inline-flex items-center gap-1">
                        ¥{(tx.estimatedCost / 100).toFixed(2)}
                        <span className="rounded bg-warning-soft px-1 py-0.5 text-[10px] font-semibold text-warning leading-none text-nowrap">
                          预估
                        </span>
                      </span>
                    ) : (
                      "—"
                    )}
                  </Table.Cell>
                  <Table.Cell>
                    {tx.stopReason === "DeAuthorized" ? (
                      <p className="text-xs font-medium text-muted text-nowrap">
                        {tx.idTagStatus && tx.idTagStatus !== "Accepted"
                          ? `${idTagRejectLabelMap[tx.idTagStatus] ?? tx.idTagStatus}`
                          : "鉴权失败"}
                      </p>
                    ) : tx.stopReason ? (
                      <Chip
                        color={stopReasonColorMap[tx.stopReason] ?? "default"}
                        size="sm"
                        variant="soft"
                      >
                        {stopReasonLabelMap[tx.stopReason] ?? tx.stopReason}
                      </Chip>
                    ) : tx.stopTimestamp ? (
                      <Chip color="default" size="sm" variant="soft">
                        本地结束
                      </Chip>
                    ) : (
                      "—"
                    )}
                  </Table.Cell>
                  <Table.Cell>
                    <div className="flex items-center gap-1">
                      {!tx.stopTimestamp && (
                        <Modal>
                          <Button size="sm" variant="danger-soft" isDisabled={stoppingId === tx.id}>
                            {stoppingId === tx.id ? <Spinner size="sm" /> : "中止"}
                          </Button>
                          <Modal.Backdrop>
                            <Modal.Container scroll="outside">
                              <Modal.Dialog className="sm:max-w-96">
                                <Modal.CloseTrigger />
                                <Modal.Header>
                                  <Modal.Heading>确认中止充电</Modal.Heading>
                                </Modal.Header>
                                <Modal.Body>
                                  <p className="text-sm text-muted">
                                    将强制结束交易{" "}
                                    <span className="font-mono font-medium text-foreground">
                                      #{tx.id}
                                    </span>
                                    （储值卡：<span className="font-mono">{tx.idTag}</span>）。
                                    如果充电桩在线，将发送远程结算指令。
                                  </p>
                                </Modal.Body>
                                <Modal.Footer className="flex justify-end gap-2">
                                  <Button slot="close" variant="ghost">
                                    取消
                                  </Button>
                                  <Button
                                    slot="close"
                                    variant="danger"
                                    isDisabled={stoppingId === tx.id}
                                    onPress={() => handleStop(tx.id)}
                                  >
                                    {stoppingId === tx.id ? <Spinner size="sm" /> : "确认中止"}
                                  </Button>
                                </Modal.Footer>
                              </Modal.Dialog>
                            </Modal.Container>
                          </Modal.Backdrop>
                        </Modal>
                      )}
                      {isAdmin && (
                        <Modal>
                          <Button
                            isIconOnly
                            size="sm"
                            variant="tertiary"
                            isDisabled={deletingId === tx.id}
                          >
                            {deletingId === tx.id ? (
                              <Spinner size="sm" />
                            ) : (
                              <TrashBin className="size-4" />
                            )}
                          </Button>
                          <Modal.Backdrop>
                            <Modal.Container scroll="outside">
                              <Modal.Dialog className="sm:max-w-96">
                                <Modal.CloseTrigger />
                                <Modal.Header>
                                  <Modal.Heading>确认删除记录</Modal.Heading>
                                </Modal.Header>
                                <Modal.Body>
                                  <p className="text-sm text-muted">
                                    将永久删除充电记录{" "}
                                    <span className="font-mono font-medium text-foreground">
                                      #{tx.id}
                                    </span>
                                    （储值卡：<span className="font-mono">{tx.idTag}</span>）。
                                    {!tx.stopTimestamp &&
                                      "该记录仍进行中，删除同时将重置接口状态。"}
                                  </p>
                                </Modal.Body>
                                <Modal.Footer className="flex justify-end gap-2">
                                  <Button slot="close" variant="ghost">
                                    取消
                                  </Button>
                                  <Button
                                    slot="close"
                                    variant="danger"
                                    isDisabled={deletingId === tx.id}
                                    onPress={() => handleDelete(tx.id)}
                                  >
                                    {deletingId === tx.id ? <Spinner size="sm" /> : "确认删除"}
                                  </Button>
                                </Modal.Footer>
                              </Modal.Dialog>
                            </Modal.Container>
                          </Modal.Backdrop>
                        </Modal>
                      )}
                    </div>
                  </Table.Cell>
                </Table.Row>
              ))}
            </Table.Body>
          </Table.Content>
        </Table.ScrollContainer>
        {data && data.totalPages > 1 && (
          <Table.Footer>
            <Pagination size="sm">
              <Pagination.Summary>
                第 {(page - 1) * LIMIT + 1}–{Math.min(page * LIMIT, data.total)} 条，共 {data.total}{" "}
                条
              </Pagination.Summary>
              <Pagination.Content>
                <Pagination.Item>
                  <Pagination.Previous
                    isDisabled={page === 1}
                    onPress={() => setPage((p) => Math.max(1, p - 1))}
                  >
                    <Pagination.PreviousIcon />
                    上一页
                  </Pagination.Previous>
                </Pagination.Item>
                {pages.map((p) => (
                  <Pagination.Item key={p}>
                    <Pagination.Link isActive={p === page} onPress={() => setPage(p)}>
                      {p}
                    </Pagination.Link>
                  </Pagination.Item>
                ))}
                <Pagination.Item>
                  <Pagination.Next
                    isDisabled={page === data.totalPages}
                    onPress={() => setPage((p) => Math.min(data.totalPages, p + 1))}
                  >
                    下一页
                    <Pagination.NextIcon />
                  </Pagination.Next>
                </Pagination.Item>
              </Pagination.Content>
            </Pagination>
          </Table.Footer>
        )}
      </Table>
    </div>
  );
}

export default function TransactionsPage() {
  return (
    <Suspense
      fallback={
        <div className="flex h-48 items-center justify-center">
          <Spinner />
        </div>
      }
    >
      <TransactionsPageContent />
    </Suspense>
  );
}
