"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import { Button, Chip, Input, Label, ListBox, Modal, Select, Spinner, Table, TextField } from "@heroui/react";
import { Plus, Pencil, PlugConnection, TrashBin } from "@gravity-ui/icons";
import { api, type ChargePoint } from "@/lib/api";


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",
};

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 [chargePoints, setChargePoints] = useState<ChargePoint[]>([]);
  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 hasFetched = useRef(false);

  const load = useCallback(async () => {
    const data = await api.chargePoints.list().catch(() => []);
    setChargePoints(data);
  }, []);

  useEffect(() => {
    if (!hasFetched.current) {
      hasFetched.current = true;
      load();
    }
  }, [load]);

  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
        const updated = await api.chargePoints.update(String(formTarget.id), {
          chargePointVendor: formData.chargePointVendor,
          chargePointModel: formData.chargePointModel,
          registrationStatus: formData.registrationStatus,
          feePerKwh: fee,
        });
        setChargePoints((prev) =>
          prev.map((cp) => (cp.id === formTarget.id ? { ...updated, connectors: cp.connectors } : cp)),
        );
      } else {
        // Create
        const created = await api.chargePoints.create({
          chargePointIdentifier: formData.chargePointIdentifier.trim(),
          chargePointVendor: formData.chargePointVendor.trim() || undefined,
          chargePointModel: formData.chargePointModel.trim() || undefined,
          registrationStatus: formData.registrationStatus,
          feePerKwh: fee,
        });
        setChargePoints((prev) => [created, ...prev]);
      }
      setFormOpen(false);
    } finally {
      setFormBusy(false);
    }
  };

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

  const isEdit = formTarget !== null;

  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>
        <Button size="sm" variant="secondary" onPress={openCreate}>
          <Plus className="size-4" />
          新建充电桩
        </Button>
      </div>

      {/* Create / Edit modal */}
      <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>

      <Table>
        <Table.ScrollContainer>
          <Table.Content aria-label="充电桩列表" className="min-w-200">
            <Table.Header>
              <Table.Column isRowHeader>标识符</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>
              {chargePoints.length === 0 && (
                <Table.Row id="empty">
                  <Table.Cell>
                    <span className="text-muted text-sm">暂无设备</span>
                  </Table.Cell>
                  <Table.Cell>{""}</Table.Cell>
                  <Table.Cell>{""}</Table.Cell>
                  <Table.Cell>{""}</Table.Cell>
                  <Table.Cell>{""}</Table.Cell>
                  <Table.Cell>{""}</Table.Cell>
                  <Table.Cell>{""}</Table.Cell>
                </Table.Row>
              )}
              {chargePoints.map((cp) => (
                <Table.Row key={cp.id} id={String(cp.id)}>
                  <Table.Cell className="font-mono font-medium">
                    {cp.chargePointIdentifier}
                  </Table.Cell>
                  <Table.Cell>
                    {cp.chargePointVendor && cp.chargePointModel ? (
                      `${cp.chargePointVendor} / ${cp.chargePointModel}`
                    ) : (
                      <span className="text-muted">—</span>
                    )}
                  </Table.Cell>
                  <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 ? (
                      new Date(cp.lastHeartbeatAt).toLocaleString("zh-CN")
                    ) : (
                      <span className="text-muted">—</span>
                    )}
                  </Table.Cell>
                  <Table.Cell>
                    <div className="flex flex-wrap gap-1.5">
                      {cp.connectors.length === 0 ? (
                        <span className="text-muted text-sm">—</span>
                      ) : (
                        [...cp.connectors].sort((a, b) => a.connectorId - b.connectorId).map((conn) => (
                          <div
                            key={conn.id}
                            className="flex 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-foreground">
                              {statusLabelMap[conn.status] ?? conn.status}
                            </span>
                          </div>
                        ))
                      )}
                    </div>
                  </Table.Cell>
                  <Table.Cell>
                    <div className="flex items-center gap-1">
                      <Button isIconOnly size="sm" variant="tertiary" onPress={() => openEdit(cp)}>
                        <Pencil 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>
  );
}

