import { useCallback, useEffect, useState } from "react"
import { Navigate, Outlet, useLocation } from "react-router-dom"
import { KeyOutlined, ReloadOutlined, SafetyCertificateOutlined } from "@ant-design/icons"
import { Alert, Button, Form, Input, Modal, Result, Space, Spin } from "antd"
import {
  activateAdminLicenseCode,
  getAdminLicenseStatus,
  getAdminSystemInfo,
  type AdminSystemInfo,
} from "../api/system"
import { toast } from "../../utils/toast"

type GateState = "checking" | "ready" | "required" | "error"

interface LicenseFormValues {
  license_code: string
}

function isGoBackend(info: AdminSystemInfo) {
  const backendType = (info.app.backend_type || "").trim().toLowerCase()
  return backendType === "go" || Boolean(info.runtime?.go_version)
}

function responseStatus(error: unknown) {
  return (error as { response?: { status?: number } })?.response?.status
}

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

interface LicenseCheckResult {
  configured: boolean | null
  status?: string
  graceUntil?: string
}

async function readLicenseConfigured(): Promise<LicenseCheckResult> {
  try {
    const response = await getAdminLicenseStatus()
    return {
      configured: Boolean(response.data?.configured),
      status: response.data?.status,
      graceUntil: response.data?.grace_until,
    }
  } catch (requestError: unknown) {
    if (responseStatus(requestError) !== 404) throw requestError
  }

  try {
    const response = await getAdminSystemInfo()
    const systemInfo: AdminSystemInfo | null = response.data ?? null
    if (!systemInfo || !isGoBackend(systemInfo)) return { configured: null }
    return { configured: false }
  } catch (requestError: unknown) {
    if (responseStatus(requestError) === 404) return { configured: null }
    throw requestError
  }
}

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

export default function AdminLicenseGate() {
  const [form] = Form.useForm<LicenseFormValues>()
  const location = useLocation()
  const [state, setState] = useState<GateState>("checking")
  const [checking, setChecking] = useState(false)
  const [submitting, setSubmitting] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [graceUntil, setGraceUntil] = useState<string | null>(null)

  const checkLicense = useCallback(async () => {
    setChecking(true)
    setError(null)
    try {
      const result = await readLicenseConfigured()
      setState(result.configured == null || result.configured ? "ready" : "required")
      setGraceUntil(result.status === "grace" ? result.graceUntil ?? null : null)
    } catch (requestError: unknown) {
      setError(errorDetail(requestError, "无法检查商业版授权状态"))
      setState("error")
    } finally {
      setChecking(false)
    }
  }, [])

  useEffect(() => {
    void checkLicense()
  }, [checkLicense])

  const submitLicense = async (values: LicenseFormValues) => {
    const licenseCode = values.license_code.trim()
    if (!licenseCode) return

    setSubmitting(true)
    try {
      const response = await activateAdminLicenseCode(licenseCode)
      if (!response.data?.configured) {
        throw new Error("授权码不可用")
      }
      form.resetFields()
      setState("ready")
      window.dispatchEvent(new Event("admin-license-updated"))
      toast.success("授权码已保存")
    } catch (requestError: unknown) {
      toast.error(errorDetail(requestError, "授权码保存失败"))
    } finally {
      setSubmitting(false)
    }
  }

  if (state === "checking") {
    return (
      <div style={{ minHeight: "100vh", display: "flex", alignItems: "center", justifyContent: "center", background: "#fff" }}>
        <Spin size="large" tip="正在检查授权状态" />
      </div>
    )
  }

  if (state === "error") {
    return (
      <Result
        status="error"
        title="授权状态检查失败"
        subTitle={error || "请检查网络和 Go 后端运行状态"}
        extra={(
          <Button type="primary" icon={<ReloadOutlined />} loading={checking} onClick={() => void checkLicense()}>
            重新检查
          </Button>
        )}
      />
    )
  }

  if (state === "required" && location.pathname !== "/admin/system-info") {
    return <Navigate to="/admin/system-info" replace />
  }

  return (
    <>
      {state === "ready" && graceUntil && (
        <Alert
          type="warning"
          showIcon
          banner
          message={`授权中心暂时不可达，服务在宽限期内继续运行（将于 ${formatGraceUntil(graceUntil)} 前恢复联网或停止服务）`}
        />
      )}
      <Outlet />
      <Modal
        open={state === "required"}
        title={(
          <Space>
            <SafetyCertificateOutlined />
            填写商业授权码
          </Space>
        )}
        closable={false}
        maskClosable={false}
        keyboard={false}
        footer={null}
        width={520}
      >
        <Space direction="vertical" size={16} style={{ width: "100%" }}>
          <Alert
            type="warning"
            showIcon
            title="Go 商业版必须配置授权码"
            description="授权码保存后才能进入管理后台。"
          />
          <Form<LicenseFormValues>
            form={form}
            layout="vertical"
            requiredMark={false}
            onFinish={submitLicense}
            disabled={submitting}
          >
            <Form.Item
              label="授权码"
              name="license_code"
              rules={[
                { required: true, whitespace: true, message: "请输入授权码" },
                { max: 255, message: "授权码不能超过 255 个字符" },
              ]}
            >
              <Input
                prefix={<KeyOutlined />}
                placeholder="请输入商业授权码"
                autoComplete="off"
                size="large"
              />
            </Form.Item>
            <Button type="primary" htmlType="submit" block size="large" loading={submitting}>
              保存授权码
            </Button>
          </Form>
        </Space>
      </Modal>
    </>
  )
}
