import { useCallback, useEffect, useMemo, useState } from "react"
import { DeleteOutlined, EditOutlined, PlusOutlined, SafetyCertificateOutlined } from "@ant-design/icons"
import { Button, Card, Empty, Form, Input, Modal, Popconfirm, Space, Typography } from "antd"
import { useNavigate } from "react-router-dom"
import {
  createSecurityGroup,
  deleteSecurityGroup,
  listSecurityGroups,
  type SecurityGroupItem,
  updateSecurityGroup,
} from "../api/securityGroups"
import { toast } from "../utils/toast"

const { Title, Paragraph, Text } = Typography

const MAX_SECURITY_GROUPS = 5

interface SecurityGroupFormValues {
  name: string
}

function formatDate(value?: string | null) {
  if (!value) return "-"
  const date = new Date(value)
  if (Number.isNaN(date.getTime())) return value
  return date.toLocaleString("zh-CN", { hour12: false })
}

function errorDetail(error: unknown, fallback: string) {
  return (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail || fallback
}

export default function SecurityGroups() {
  const navigate = useNavigate()
  const [form] = Form.useForm<SecurityGroupFormValues>()
  const [groups, setGroups] = useState<SecurityGroupItem[]>([])
  const [total, setTotal] = useState(0)
  const [loading, setLoading] = useState(true)
  const [modalOpen, setModalOpen] = useState(false)
  const [editingGroup, setEditingGroup] = useState<SecurityGroupItem | null>(null)
  const [submitting, setSubmitting] = useState(false)
  const [deletingId, setDeletingId] = useState<number | string | null>(null)

  const loadGroups = useCallback(async (silent = false) => {
    if (!silent) setLoading(true)
    try {
      const res = await listSecurityGroups({ page: 1, per_page: MAX_SECURITY_GROUPS })
      const payload = res.data.data
      setGroups(payload?.list ?? [])
      setTotal(payload?.meta.total ?? 0)
    } catch (error) {
      toast.error(errorDetail(error, "安全组列表加载失败"))
    } finally {
      setLoading(false)
    }
  }, [])

  useEffect(() => {
    const timer = window.setTimeout(() => {
      void loadGroups()
    }, 0)
    return () => window.clearTimeout(timer)
  }, [loadGroups])

  const canCreate = total < MAX_SECURITY_GROUPS
  const quotaText = useMemo(
    () => `已创建 ${total}/${MAX_SECURITY_GROUPS} 个`,
    [total],
  )

  const openCreateModal = () => {
    if (!canCreate) {
      toast.info(`每个用户最多创建 ${MAX_SECURITY_GROUPS} 个安全组`)
      return
    }
    form.resetFields()
    setEditingGroup(null)
    setModalOpen(true)
  }

  const openEditModal = (group: SecurityGroupItem) => {
    setEditingGroup(group)
    form.setFieldsValue({ name: group.name })
    setModalOpen(true)
  }

  const handleCreate = async () => {
    if (!editingGroup && !canCreate) {
      toast.info(`每个用户最多创建 ${MAX_SECURITY_GROUPS} 个安全组`)
      return
    }

    const values = await form.validateFields()
    const name = values.name.trim()
    if (!name) {
      form.setFields([{ name: "name", errors: ["请输入安全组名称"] }])
      return
    }

    setSubmitting(true)
    try {
      if (editingGroup) {
        await updateSecurityGroup(editingGroup.id, { name })
        toast.success("安全组修改成功")
      } else {
        await createSecurityGroup({ name })
        toast.success("安全组创建成功")
      }
      setModalOpen(false)
      setEditingGroup(null)
      form.resetFields()
      await loadGroups(true)
    } catch (error) {
      toast.error(errorDetail(error, editingGroup ? "安全组修改失败" : "安全组创建失败"))
    } finally {
      setSubmitting(false)
    }
  }

  const handleDelete = async (group: SecurityGroupItem) => {
    setDeletingId(group.id)
    try {
      await deleteSecurityGroup(group.id)
      toast.success("安全组删除成功")
      await loadGroups(true)
    } catch (error) {
      toast.error(errorDetail(error, "安全组删除失败"))
    } finally {
      setDeletingId(null)
    }
  }

  return (
    <Space orientation="vertical" size={20} style={{ width: "100%" }}>
      <div>
        <Title level={3} style={{ margin: 0 }}>安全组管理</Title>
        <Paragraph type="secondary" style={{ marginTop: 8, marginBottom: 0 }}>
          管理云服务器防火墙规则、入站端口和访问来源。
        </Paragraph>
      </div>

      <Card
        variant="outlined"
        loading={loading}
        title={<Space><SafetyCertificateOutlined /> 安全组列表</Space>}
        extra={(
          <Space>
            <Text type="secondary">{quotaText}</Text>
            <Button type="primary" icon={<PlusOutlined />} disabled={!canCreate} onClick={openCreateModal}>
              创建安全组
            </Button>
          </Space>
        )}
      >
        {groups.length === 0 ? (
          <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂无安全组">
            <Button type="primary" icon={<PlusOutlined />} onClick={openCreateModal}>
              创建安全组
            </Button>
          </Empty>
        ) : (
          <Space orientation="vertical" size={0} style={{ width: "100%" }}>
            {groups.map((group, index) => (
              <div
                key={String(group.id)}
                onClick={() => navigate(`/control/security-groups/${group.id}`)}
                style={{
                  minHeight: 64,
                  display: "flex",
                  alignItems: "center",
                  justifyContent: "space-between",
                  gap: 16,
                  padding: "12px 0",
                  borderBottom: index === groups.length - 1 ? "none" : "1px solid #f0f0f0",
                  cursor: "pointer",
                }}
              >
                <Space size={12}>
                  <div
                    style={{
                      width: 36,
                      height: 36,
                      borderRadius: 8,
                      background: "#e6f4ff",
                      color: "#1677ff",
                      display: "flex",
                      alignItems: "center",
                      justifyContent: "center",
                    }}
                  >
                    <SafetyCertificateOutlined />
                  </div>
                  <div>
                    <Text strong>{group.name}</Text>
                  </div>
                </Space>
                <Space size={16} onClick={(event) => event.stopPropagation()}>
                  <Text type="secondary">{group.rule_num} 条规则</Text>
                  <Text type="secondary">{formatDate(group.create_time)}</Text>
                  <Button
                    size="small"
                    icon={<EditOutlined />}
                    onClick={(event) => {
                      event.stopPropagation()
                      openEditModal(group)
                    }}
                  >
                    修改
                  </Button>
                  <Popconfirm
                    title="删除安全组"
                    description="确认删除这个安全组吗？"
                    okText="删除"
                    cancelText="取消"
                    okButtonProps={{ danger: true }}
                    onConfirm={(event) => {
                      event?.stopPropagation()
                      void handleDelete(group)
                    }}
                  >
                    <Button
                      danger
                      size="small"
                      icon={<DeleteOutlined />}
                      loading={deletingId === group.id}
                      onClick={(event) => event.stopPropagation()}
                    >
                      删除
                    </Button>
                  </Popconfirm>
                </Space>
              </div>
            ))}
          </Space>
        )}
      </Card>

      <Modal
        title={editingGroup ? "修改安全组" : "创建安全组"}
        open={modalOpen}
        okText={editingGroup ? "保存" : "创建"}
        cancelText="取消"
        confirmLoading={submitting}
        onOk={handleCreate}
        onCancel={() => {
          setModalOpen(false)
          setEditingGroup(null)
        }}
        destroyOnHidden
      >
        <Form<SecurityGroupFormValues> form={form} layout="vertical" style={{ marginTop: 20 }}>
          <Form.Item
            name="name"
            label="安全组名称"
            rules={[
              { required: true, message: "请输入安全组名称" },
              { max: 64, message: "安全组名称不能超过 64 个字符" },
            ]}
          >
            <Input placeholder="请输入安全组名称" allowClear autoFocus />
          </Form.Item>
        </Form>
      </Modal>
    </Space>
  )
}
