import type { ColumnDef } from "@tanstack/react-table"
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
import { Toaster, toast } from "sonner"
import {
  fetchLineData,
  type LineItem,
  PHP_API_BASE_URL,
  searchLineData,
} from "@/api/linedata"
import DataTable from "@/components/data-table"
import { Button } from "@/components/ui/button"
import Wrap from "@/components/wrap"
import { cn } from "@/lib/utils"

const REFRESH_INTERVAL = 5 * 60 * 1000
const PAGE_SIZE_OPTIONS = [100, 200, 500]

type ProductOption = {
  id: number
  name: string
  l2tp: string
  sstp: string
}

const PRODUCTS: ProductOption[] = [
  { id: 29, name: "极狐IP", l2tp: "8899", sstp: "4430" },
  { id: 3, name: "极光IP", l2tp: "1234", sstp: "4430" },
  // { id: 18, name: "蘑菇IP", l2tp: "8899", sstp: "4430" },
  { id: 27, name: "麒麟IP", l2tp: "123", sstp: "4432" },
  { id: 26, name: "猎豹IP", l2tp: "1234", sstp: "4430" },
  { id: 28, name: "水滴独享IP", l2tp: "123", sstp: "4432" },
  { id: 22, name: "火狐静态IP", l2tp: "888888", sstp: "5908" },
]

function toText(value: string | number): string {
  return value === null || value === undefined ? "" : String(value)
}

function onlineClass(value: string | number): string {
  const text = toText(value)
  if (!text) return "text-gray-400"
  return text.includes("在线") || text.includes("正常")
    ? "text-green-600"
    : "text-red-500"
}

export default function IpLinePage() {
  const [productId, setProductId] = useState<number | null>(null)
  const [rows, setRows] = useState<LineItem[]>([])
  const [count, setCount] = useState<number | string>(0)
  const [useCount, setUseCount] = useState<number | string>(0)
  const [keyword, setKeyword] = useState("")
  const [searching, setSearching] = useState(false)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [pageIndex, setPageIndex] = useState(0)
  const [pageSize, setPageSize] = useState(100)
  const requestSeq = useRef(0)

  const loadDisplay = useCallback(async (pid: number) => {
    const seq = ++requestSeq.current
    setLoading(true)
    setError(null)
    const result = await fetchLineData(pid)
    if (seq !== requestSeq.current) return
    if (result.success) {
      setRows(result.data.data ?? [])
      setCount(result.data.count ?? 0)
      setUseCount(result.data.use_count ?? 0)
    } else {
      setRows([])
      setCount(0)
      setUseCount(0)
      setError(result.message)
    }
    setLoading(false)
  }, [])

  // 首次进入展示全部产品线路（product=0）
  useEffect(() => {
    loadDisplay(0)
  }, [loadDisplay])

  // 每5分钟自动刷新（搜索状态除外）
  useEffect(() => {
    const timer = setInterval(() => {
      if (!searching) loadDisplay(productId ?? 0)
    }, REFRESH_INTERVAL)
    return () => clearInterval(timer)
  }, [productId, searching, loadDisplay])

  // 数据变化后修正越界页码
  useEffect(() => {
    const totalPages = Math.max(1, Math.ceil(rows.length / pageSize))
    if (pageIndex >= totalPages) setPageIndex(totalPages - 1)
  }, [rows.length, pageIndex, pageSize])

  const handleSelectProduct = (id: number) => {
    const next = productId === id ? null : id
    setProductId(next)
    setSearching(false)
    setKeyword("")
    setPageIndex(0)
    loadDisplay(next ?? 0)
  }

  const handleSearch = async () => {
    const info = keyword.trim()
    if (!info) {
      if (searching) {
        setSearching(false)
        setPageIndex(0)
        await loadDisplay(productId ?? 0)
      }
      return
    }
    setSearching(true)
    setLoading(true)
    setError(null)
    setPageIndex(0)
    const seq = ++requestSeq.current
    const result = await searchLineData(productId ?? 0, info)
    console.log("搜索的result", result)

    if (seq !== requestSeq.current) return
    if (result.success) {
      setRows(result.data.data ?? [])
    } else {
      setRows([])
      setError(result.message)
    }
    setLoading(false)
  }

  const handleCopy = useCallback(async (text: string) => {
    try {
      await navigator.clipboard.writeText(text)
      toast.success("复制成功")
    } catch {
      toast.error("复制失败，请手动复制")
    }
  }, [])

  const handleExport = () => {
    if (rows.length === 0) {
      toast.error("暂无数据可导出")
      return
    }
    const header = [
      "产品",
      "城市",
      "运营商",
      "服务器域名",
      "带宽",
      "服务器状态",
    ]
    const lines = [
      header,
      ...rows.map(r => [
        toText(r.name),
        toText(r.city),
        toText(r.supply),
        toText(r.nasname),
        toText(r.daikuan),
        toText(r.online),
      ]),
    ]
    const csv = lines
      .map(line => line.map(v => `"${v.replaceAll('"', '""')}"`).join(","))
      .join("\r\n")
    const blob = new Blob([`\uFEFF${csv}`], {
      type: "text/csv;charset=utf-8",
    })
    const url = URL.createObjectURL(blob)
    const a = document.createElement("a")
    a.href = url
    a.download = `${currentName || "IP线路表"}.csv`
    a.click()
    URL.revokeObjectURL(url)
    toast.success("导出成功")
  }

  const currentProduct = PRODUCTS.find(p => p.id === productId)
  const currentName = currentProduct?.name ?? "全部产品"

  const pageRows = useMemo(() => {
    const start = pageIndex * pageSize
    return rows.slice(start, start + pageSize)
  }, [rows, pageIndex, pageSize])

  const status = loading ? "load" : error ? "fail" : "done"

  return (
    <>
      <Toaster position="top-center" richColors />
      <Wrap className="flex flex-col gap-4 mt-20 max-w-6xl mx-auto px-4 pb-20 bg-white">
        <div className="grid grid-cols-3 mt-3">
          <div></div>
          <h3 className="text-3xl font-bold text-gray-800 text-center">
            IP线路表
          </h3>
          <div className="flex gap-4 text-sm justify-end items-end text-blue-500">
            <a
              href="/softDownload"
              className="no-underline hover:text-blue-700 active:no-underline focus:no-underline"
            >
              下载客户端
            </a>
            <a
              href="/help"
              className="no-underline hover:text-blue-700 active:no-underline focus:no-underline"
            >
              教程&amp;帮助
            </a>
          </div>
        </div>

        <ul className="flex justify-between gap-4 text-xs text-gray-600 px-2">
          <li className="flex items-center gap-1.5">
            <span className="w-1.5 h-1.5 bg-emerald-500 rounded-full" />
            线路表和账户必须为同一产品才能使用
          </li>
          <li className="flex items-center gap-1.5">
            <span className="w-1.5 h-1.5 bg-emerald-500 rounded-full" />
            请优先选择客户端连接
          </li>
          <li className="flex items-center gap-1.5">
            <span className="w-1.5 h-1.5 bg-emerald-500 rounded-full" />
            无对应客户端时，可通过线路表直连支持所有设备
          </li>
        </ul>

        <div className="flex flex-wrap items-center gap-3">
          {PRODUCTS.map(p => (
            <Button
              key={p.id}
              variant={p.id === productId ? "default" : "outline"}
              onClick={() => handleSelectProduct(p.id)}
              className={cn(
                "px-6 py-1.5 rounded-full",
                p.id === productId
                  ? "text-white bg-linear-to-r from-cyan-400 to-blue-500 shadow-md shadow-blue-200 hover:opacity-90"
                  : "border-gray-200 bg-white text-gray-600 hover:border-blue-400 hover:text-blue-500",
              )}
            >
              {p.name}
            </Button>
          ))}
        </div>

        <div className="flex items-center justify-center gap-4 w-full">
          <div className="relative w-1/2">
            <div className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400">
              <svg
                className="w-4 h-4"
                fill="none"
                viewBox="0 0 24 24"
                stroke="currentColor"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
                />
              </svg>
            </div>
            <input
              type="text"
              value={keyword}
              onChange={e => setKeyword(e.target.value)}
              onKeyDown={e => {
                if (e.key === "Enter") handleSearch()
              }}
              placeholder="请输入线路搜索信息，如：混拨"
              className="w-full pl-10 pr-4 py-2 border border-gray-200 rounded-full focus:outline-none focus:ring-2 focus:ring-cyan-400 text-sm"
            />
          </div>
          <Button
            onClick={handleSearch}
            className="px-8 rounded-full bg-linear-to-r from-cyan-400 to-blue-500 text-white shadow-md shadow-blue-200 hover:opacity-90"
          >
            搜索当前线路表
          </Button>
          <Button
            variant="outline"
            onClick={handleExport}
            className="gap-1.5 px-4 rounded border-blue-400 text-blue-500 bg-white hover:bg-blue-50 hover:text-blue-500"
          >
            <svg
              className="w-4 h-4"
              fill="none"
              viewBox="0 0 24 24"
              stroke="currentColor"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"
              />
            </svg>
            导出
          </Button>
        </div>

        <div className="bg-orange-50 border border-orange-100 rounded-lg p-2 flex justify-center items-center gap-8 text-sm font-medium">
          <div className="flex items-center gap-2 text-orange-500">
            <span>L2TP密钥：</span>
            <span className="text-orange-600">
              {currentProduct?.l2tp || ""}
            </span>
          </div>
          <div className="flex items-center gap-2 text-orange-500">
            <span>STTP端口：</span>
            <span className="text-orange-600">
              {currentProduct?.sstp || ""}
            </span>
          </div>
        </div>

        <div className="flex items-center gap-6 text-xs text-gray-600 px-1">
          {searching ? (
            <div className="flex items-center gap-2">
              <span className="w-1.5 h-1.5 bg-emerald-500 rounded-full" />
              <span>
                搜索结果：
                <span className="font-bold text-gray-800">{rows.length}条</span>
              </span>
            </div>
          ) : (
            <>
              <div className="flex items-center gap-2">
                <span className="w-1.5 h-1.5 bg-emerald-500 rounded-full" />
                <span>
                  实时总线路：
                  <span className="font-bold text-gray-800">{count}条</span>
                </span>
              </div>
              <div className="flex items-center gap-2">
                <span className="w-1.5 h-1.5 bg-emerald-500 rounded-full" />
                <span>
                  实时可用线路：
                  <span className="font-bold text-gray-800">{useCount}条</span>
                </span>
              </div>
            </>
          )}
          <div className="flex items-center gap-2">
            <span className="w-1.5 h-1.5 bg-emerald-500 rounded-full" />
            <span className="text-gray-400 break-all">
              {currentName}- (每5分钟更新一次,禁止频繁访问！) :
              {PHP_API_BASE_URL}/script/linedata/display.php?product=
              {productId ?? 0}
            </span>
          </div>
        </div>

        {error && (
          <div className="flex items-center justify-center gap-3 bg-red-50 border border-red-100 text-red-500 rounded-lg py-2 px-4 text-sm">
            <span>加载失败：{error}</span>
            <Button
              variant="link"
              onClick={() => loadDisplay(productId ?? 0)}
              className="text-blue-500 hover:underline"
            >
              重试
            </Button>
          </div>
        )}

        <DataTable<LineItem>
          data={pageRows}
          status={status}
          columns={useMemo<ColumnDef<LineItem>[]>(
            () => [
              {
                accessorKey: "name",
                header: "产品",
                cell: ({ row }) => toText(row.original.name),
              },
              {
                accessorKey: "city",
                header: "城市",
                cell: ({ row }) => toText(row.original.city),
              },
              {
                accessorKey: "supply",
                header: "运营商",
                cell: ({ row }) => toText(row.original.supply),
              },
              {
                accessorKey: "nasname",
                header: "服务器域名",
                cell: ({ row }) => {
                  const text = toText(row.original.nasname)
                  if (!text) return null
                  return (
                    <span>
                      {text}
                      <Button
                        variant="ghost"
                        onClick={() => handleCopy(text)}
                        className="ml-2 h-auto px-1 py-0 text-green-500 hover:bg-transparent hover:text-green-700 cursor-pointer"
                      >
                        复制
                      </Button>
                    </span>
                  )
                },
              },
              {
                accessorKey: "daikuan",
                header: "带宽",
                cell: ({ row }) => toText(row.original.daikuan),
              },
              {
                accessorKey: "online",
                header: "服务器状态",
                cell: ({ row }) => {
                  const text = toText(row.original.online)
                  return (
                    <span className={onlineClass(row.original.online)}>
                      {text}
                    </span>
                  )
                },
              },
            ],
            [handleCopy],
          )}
          stickyHeader
          maxHeight="max-h-[640px]"
          classNames={{ headRow: "bg-gray-50 text-gray-600" }}
          pagination={
            rows.length > 0
              ? {
                  page: pageIndex + 1,
                  size: pageSize,
                  total: rows.length,
                  sizeOptions: PAGE_SIZE_OPTIONS,
                  onPageChange: page => setPageIndex(page - 1),
                  onSizeChange: size => {
                    setPageSize(size)
                    setPageIndex(0)
                  },
                }
              : undefined
          }
        />
      </Wrap>
    </>
  )
}
