"use client";

import { useState, useEffect } from "react";
import { useQuery } from "@tanstack/react-query";
import {
  Button,
  Chip,
  Input,
  Label,
  ListBox,
  Modal,
  Select,
  Spinner,
  Table,
  TextField,
} from "@heroui/react";
import {
  Plus,
  Pencil,
  PlugConnection,
  TrashBin,
  ArrowRotateRight,
  QrCode,
} from "@gravity-ui/icons";
import { QRCodeSVG } from "qrcode.react";
import Link from "next/link";
import { ScrollFade } from "@/components/scroll-fade";
import { api, type ChargePoint } from "@/lib/api";
import { useSession } from "@/lib/auth-client";
import dayjs from "@/lib/dayjs";

const statusLabelMap: Record<string, string> = {
  Available: "空闲中",
  Charging: "充电中",
  Preparing: "准备中",
  Finishing: "结束中",
  SuspendedEV: "EV 暂停",
  SuspendedEVSE: "EVSE 暂停",
  Reserved: "已预约",
  Faulted: "故障",
  Unavailable: "不可用",
  Occupied: "占用",
};

const statusDotClass: Record<string, string> = {
  Available: "bg-success",
  Charging: "bg-accent animate-pulse",
  Preparing: "bg-warning animate-pulse",
  Finishing: "bg-warning",
  SuspendedEV: "bg-warning",
  SuspendedEVSE: "bg-warning",
  Reserved: "bg-warning",
  Faulted: "bg-danger",
  Unavailable: "bg-danger",
  Occupied: "bg-warning",
};

function ConnectorCell({ connectors }: { connectors: ChargePoint["connectors"] }) {
  return (
    <ScrollFade maxWidth="max-w-2xs">
      {connectors.length === 0 ? (
        <span className="text-muted text-sm">—</span>
      ) : (
        [...connectors]
          .sort((a, b) => a.connectorId - b.connectorId)
          .map((conn) => (
            <div
              key={conn.id}
              className="flex shrink-0 items-center gap-1.5 rounded-lg border border-border bg-surface-secondary px-2 py-1"
            >
              <PlugConnection className="size-3 shrink-0 text-muted" />
              <span className="text-xs font-medium tabular-nums text-muted">
                #{conn.connectorId}
              </span>
              <span className="h-3 w-px bg-border" />
              <span
                className={`size-1.5 shrink-0 rounded-full ${
                  statusDotClass[conn.status] ?? "bg-warning"
                }`}
              />
              <span className="text-xs text-nowrap text-foreground">
                {statusLabelMap[conn.status] ?? conn.status}
              </span>
            </div>
          ))
      )}
    </ScrollFade>
  );
}

const registrationColorMap: Record<string, "success" | "warning" | "danger"> = {
  Accepted: "success",
  Pending: "warning",
  Rejected: "danger",
};

type FormData = {
  chargePointIdentifier: string;
  chargePointVendor: string;
  chargePointModel: string;
  registrationStatus: "Accepted" | "Pending" | "Rejected";
  feePerKwh: string;
};

const EMPTY_FORM: FormData = {
  chargePointIdentifier: "",
  chargePointVendor: "",
  chargePointModel: "",
  registrationStatus: "Pending",
  feePerKwh: "0",
};

export default function ChargePointsPage() {
  const [formOpen, setFormOpen] = useState(false);
  const [formTarget, setFormTarget] = useState<ChargePoint | null>(null);
  const [formData, setFormData] = useState<FormData>(EMPTY_FORM);
  const [formBusy, setFormBusy] = useState(false);
  const [deleteTarget, setDeleteTarget] = useState<ChargePoint | null>(null);
  const [deleting, setDeleting] = useState(false);
  const [qrTarget, setQrTarget] = useState<ChargePoint | null>(null);
  const {
    data: chargePoints = [],
    refetch: refetchList,
    isFetching: refreshing,
  } = useQuery({
    queryKey: ["chargePoints"],
    queryFn: () => api.chargePoints.list().catch(() => []),
    refetchInterval: 3_000,
  });

  const openCreate = () => {
    setFormTarget(null);
    setFormData(EMPTY_FORM);
    setFormOpen(true);
  };

  const openEdit = (cp: ChargePoint) => {
    setFormTarget(cp);
    setFormData({
      chargePointIdentifier: cp.chargePointIdentifier,
      chargePointVendor: cp.chargePointVendor ?? "",
      chargePointModel: cp.chargePointModel ?? "",
      registrationStatus: cp.registrationStatus as FormData["registrationStatus"],
      feePerKwh: String(cp.feePerKwh),
    });
    setFormOpen(true);
  };

  const handleSubmit = async () => {
    if (!formData.chargePointIdentifier.trim()) return;
    setFormBusy(true);
    try {
      const fee = Math.max(0, Math.round(Number(formData.feePerKwh) || 0));
      if (formTarget) {
        // Edit
        await api.chargePoints.update(String(formTarget.id), {
          chargePointVendor: formData.chargePointVendor,
          chargePointModel: formData.chargePointModel,
          registrationStatus: formData.registrationStatus,
          feePerKwh: fee,
        });
      } else {
        // Create
        await api.chargePoints.create({
          chargePointIdentifier: formData.chargePointIdentifier.trim(),
          chargePointVendor: formData.chargePointVendor.trim() || undefined,
          chargePointModel: formData.chargePointModel.trim() || undefined,
          registrationStatus: formData.registrationStatus,
          feePerKwh: fee,
        });
      }
      await refetchList();
      setFormOpen(false);
    } finally {
      setFormBusy(false);
    }
  };

  const handleDelete = async () => {
    if (!deleteTarget) return;
    setDeleting(true);
    try {
      await api.chargePoints.delete(String(deleteTarget.id));
      await refetchList();
      setDeleteTarget(null);
    } finally {
      setDeleting(false);
    }
  };

  const isEdit = formTarget !== null;

  const { data: sessionData } = useSession();
  const isAdmin = sessionData?.user?.role === "admin";

  const [qrOrigin, setQrOrigin] = useState("");
  useEffect(() => {
    setQrOrigin(window.location.origin);
  }, []);

  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">共 {chargePoints.length} 台设备</p>
        </div>
        <div className="flex items-center gap-2">
          <Button
            isIconOnly
            size="sm"
            variant="ghost"
            isDisabled={refreshing}
            onPress={() => refetchList()}
            aria-label="刷新"
          >
            <ArrowRotateRight className={`size-4 ${refreshing ? "animate-spin" : ""}`} />
          </Button>
          {isAdmin && (
            <Button size="sm" variant="secondary" onPress={openCreate}>
              <Plus className="size-4" />
              新建充电桩
            </Button>
          )}
        </div>
      </div>

      {/* Create / Edit modal — admin only */}
      {isAdmin && (
        <>
          <Modal
            isOpen={formOpen}
            onOpenChange={(open) => {
              if (!formBusy) setFormOpen(open);
            }}
          >
            <Modal.Backdrop>
              <Modal.Container scroll="outside">
                <Modal.Dialog className="sm:max-w-md">
                  <Modal.CloseTrigger />
                  <Modal.Header>
                    <Modal.Heading>{isEdit ? "编辑充电桩" : "新建充电桩"}</Modal.Heading>
                  </Modal.Header>
                  <Modal.Body className="space-y-3">
                    <TextField fullWidth isRequired isReadOnly={isEdit}>
                      <Label className="text-sm font-medium">标识符</Label>
                      <Input
                        placeholder="CP001"
                        value={formData.chargePointIdentifier}
                        onChange={(e) =>
                          setFormData((f) => ({ ...f, chargePointIdentifier: e.target.value }))
                        }
                      />
                    </TextField>
                    <div className="grid grid-cols-2 gap-3">
                      <TextField fullWidth>
                        <Label className="text-sm font-medium">品牌</Label>
                        <Input
                          placeholder="ABB"
                          value={formData.chargePointVendor}
                          onChange={(e) =>
                            setFormData((f) => ({ ...f, chargePointVendor: e.target.value }))
                          }
                        />
                      </TextField>
                      <TextField fullWidth>
                        <Label className="text-sm font-medium">型号</Label>
                        <Input
                          placeholder="Terra AC"
                          value={formData.chargePointModel}
                          onChange={(e) =>
                            setFormData((f) => ({ ...f, chargePointModel: e.target.value }))
                          }
                        />
                      </TextField>
                    </div>
                    <div className="space-y-1.5">
                      <Label className="text-sm font-medium">注册状态</Label>
                      <Select
                        fullWidth
                        selectedKey={formData.registrationStatus}
                        onSelectionChange={(key) =>
                          setFormData((f) => ({
                            ...f,
                            registrationStatus: String(key) as FormData["registrationStatus"],
                          }))
                        }
                      >
                        <Select.Trigger>
                          <Select.Value />
                          <Select.Indicator />
                        </Select.Trigger>
                        <Select.Popover>
                          <ListBox>
                            <ListBox.Item id="Accepted">Accepted</ListBox.Item>
                            <ListBox.Item id="Pending">Pending</ListBox.Item>
                            <ListBox.Item id="Rejected">Rejected</ListBox.Item>
                          </ListBox>
                        </Select.Popover>
                      </Select>
                    </div>
                    <TextField fullWidth>
                      <Label className="text-sm font-medium">电价（分/kWh）</Label>
                      <Input
                        type="number"
                        min="0"
                        step="1"
                        placeholder="0"
                        value={formData.feePerKwh}
                        onChange={(e) => setFormData((f) => ({ ...f, feePerKwh: e.target.value }))}
                      />
                    </TextField>
                    {!isEdit && (
                      <p className="text-xs text-muted">
                        自动注册的充电桩默认状态为 Pending，需手动改为 Accepted 后才可正常上线。
                      </p>
                    )}
                  </Modal.Body>
                  <Modal.Footer className="flex justify-end gap-2">
                    <Button variant="ghost" onPress={() => setFormOpen(false)}>
                      取消
                    </Button>
                    <Button
                      isDisabled={formBusy || !formData.chargePointIdentifier.trim()}
                      onPress={handleSubmit}
                    >
                      {formBusy ? <Spinner size="sm" /> : isEdit ? "保存" : "创建"}
                    </Button>
                  </Modal.Footer>
                </Modal.Dialog>
              </Modal.Container>
            </Modal.Backdrop>
          </Modal>
        </>
      )}

      {/* QR Code Modal */}
      {isAdmin && (
        <Modal
          isOpen={qrTarget !== null}
          onOpenChange={(open) => {
            if (!open) setQrTarget(null);
          }}
        >
          <Modal.Backdrop>
            <Modal.Container scroll="outside">
              <Modal.Dialog className="sm:max-w-lg">
                <Modal.CloseTrigger />
                <Modal.Header>
                  <Modal.Heading>{qrTarget?.chargePointIdentifier} — 充电二维码</Modal.Heading>
                </Modal.Header>
                <Modal.Body className="space-y-4">
                  <p className="text-sm text-muted">
                    将以下二维码张贴在对应充电口上，用户扫码后可直接选卡启动充电。
                  </p>
                  {qrTarget &&
                    qrTarget.connectors.filter((c) => c.connectorId > 0).length === 0 && (
                      <p className="text-sm text-muted">
                        该充电桩暂无接口信息，请等待设备上线后再尝试。
                      </p>
                    )}
                  <div className="grid gap-4 grid-cols-2 sm:grid-cols-3">
                    {qrTarget?.connectors
                      .filter((c) => c.connectorId > 0)
                      .sort((a, b) => a.connectorId - b.connectorId)
                      .map((conn) => {
                        const url = `${qrOrigin}/dashboard/charge?cpId=${qrTarget.id}&connector=${conn.connectorId}`;
                        return (
                          <div
                            key={conn.id}
                            className="flex flex-col items-center gap-2 rounded-xl border border-border p-3"
                          >
                            <p className="text-xs font-medium text-foreground">
                              接口 #{conn.connectorId}
                            </p>
                            <QRCodeSVG value={url} size={120} className="rounded" />
                            <p className="break-all text-center font-mono text-[9px] text-muted leading-tight">
                              {url}
                            </p>
                          </div>
                        );
                      })}
                  </div>
                </Modal.Body>
                <Modal.Footer className="flex justify-end">
                  <Button variant="ghost" onPress={() => setQrTarget(null)}>
                    关闭
                  </Button>
                </Modal.Footer>
              </Modal.Dialog>
            </Modal.Container>
          </Modal.Backdrop>
        </Modal>
      )}

      <Table>
        <Table.ScrollContainer>
          <Table.Content aria-label="充电桩列表" className="min-w-200">
            <Table.Header>
              <Table.Column isRowHeader>标识符</Table.Column>
              {isAdmin && <Table.Column>品牌 / 型号</Table.Column>}
              {isAdmin && <Table.Column>注册状态</Table.Column>}
              <Table.Column>电价（分/kWh）</Table.Column>
              <Table.Column>最后发现</Table.Column>
              <Table.Column>状态</Table.Column>
              <Table.Column>接口</Table.Column>
              {isAdmin && <Table.Column>{""}</Table.Column>}
            </Table.Header>
            <Table.Body>
              {chargePoints.length === 0 && (
                <Table.Row id="empty">
                  <Table.Cell>
                    <span className="text-muted text-sm">暂无设备</span>
                  </Table.Cell>
                  {isAdmin && <Table.Cell>{""}</Table.Cell>}
                  {isAdmin && <Table.Cell>{""}</Table.Cell>}
                  <Table.Cell>{""}</Table.Cell>
                  <Table.Cell>{""}</Table.Cell>
                  <Table.Cell>{""}</Table.Cell>
                  <Table.Cell>{""}</Table.Cell>
                  {isAdmin && <Table.Cell>{""}</Table.Cell>}
                </Table.Row>
              )}
              {chargePoints.map((cp) => (
                <Table.Row key={cp.id} id={String(cp.id)} className={"group"}>
                  <Table.Cell>
                    <Link
                      href={`/dashboard/charge-points/${cp.id}`}
                      className="font-medium text-accent"
                    >
                      {cp.chargePointIdentifier}
                    </Link>
                  </Table.Cell>
                  {isAdmin && (
                    <Table.Cell>
                      {cp.chargePointVendor || cp.chargePointModel ? (
                        <div className="flex flex-col">
                          {cp.chargePointVendor && (
                            <span className="text-xs text-muted font-medium">
                              {cp.chargePointVendor}
                            </span>
                          )}
                          {cp.chargePointModel && (
                            <span className="text-sm text-foreground">{cp.chargePointModel}</span>
                          )}
                        </div>
                      ) : (
                        <span className="text-muted">—</span>
                      )}
                    </Table.Cell>
                  )}
                  {isAdmin && (
                    <Table.Cell>
                      <Chip
                        color={registrationColorMap[cp.registrationStatus] ?? "warning"}
                        size="sm"
                        variant="soft"
                      >
                        {cp.registrationStatus}
                      </Chip>
                    </Table.Cell>
                  )}
                  <Table.Cell className="tabular-nums">
                    {cp.feePerKwh > 0 ? (
                      <span>
                        {cp.feePerKwh} 分
                        <span className="ml-1 text-xs text-muted">
                          (¥{(cp.feePerKwh / 100).toFixed(2)}/kWh)
                        </span>
                      </span>
                    ) : (
                      <span className="text-muted">免费</span>
                    )}
                  </Table.Cell>
                  <Table.Cell>
                    {cp.lastHeartbeatAt ? (
                      dayjs(cp.lastHeartbeatAt).format("YYYY/M/D HH:mm:ss")
                    ) : (
                      <span className="text-muted">—</span>
                    )}
                  </Table.Cell>
                  <Table.Cell>
                    {cp.chargePointStatus ? (
                      <div className="flex items-center gap-1.5">
                        <span
                          className={`size-1.5 shrink-0 rounded-full ${statusDotClass[cp.chargePointStatus] ?? "bg-warning"}`}
                        />
                        <span className="text-sm text-foreground text-nowrap">
                          {cp.chargePointStatus === "Available"
                            ? "正常"
                            : (statusLabelMap[cp.chargePointStatus] ?? cp.chargePointStatus)}
                        </span>
                      </div>
                    ) : (
                      <span className="text-muted">—</span>
                    )}
                  </Table.Cell>
                  <Table.Cell>
                    <ConnectorCell connectors={cp.connectors} />
                  </Table.Cell>
                  {isAdmin && (
                    <Table.Cell>
                      <div className="flex items-center gap-1">
                        <Button
                          isIconOnly
                          size="sm"
                          variant="tertiary"
                          onPress={() => openEdit(cp)}
                        >
                          <Pencil className="size-4" />
                        </Button>
                        <Button
                          isIconOnly
                          size="sm"
                          variant="tertiary"
                          onPress={() => setQrTarget(cp)}
                          aria-label="查看二维码"
                        >
                          <QrCode className="size-4" />
                        </Button>
                        <Modal>
                          <Button
                            isIconOnly
                            size="sm"
                            variant="danger-soft"
                            onPress={() => setDeleteTarget(cp)}
                          >
                            <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">
                                      {cp.chargePointIdentifier}
                                    </span>
                                    及其所有连接器和充电记录，此操作不可恢复。
                                  </p>
                                </Modal.Body>
                                <Modal.Footer className="flex justify-end gap-2">
                                  <Button slot="close" variant="ghost">
                                    取消
                                  </Button>
                                  <Button
                                    slot="close"
                                    variant="danger"
                                    isDisabled={deleting}
                                    onPress={handleDelete}
                                  >
                                    {deleting ? <Spinner size="sm" /> : "确认删除"}
                                  </Button>
                                </Modal.Footer>
                              </Modal.Dialog>
                            </Modal.Container>
                          </Modal.Backdrop>
                        </Modal>
                      </div>
                    </Table.Cell>
                  )}
                </Table.Row>
              ))}
            </Table.Body>
          </Table.Content>
        </Table.ScrollContainer>
      </Table>
    </div>
  );
}
