import { useEffect, useMemo, useState } from 'react'
import { Eye, EyeOff, Link2, Pencil, Plus, RefreshCw, Search, Share2, Shield, Terminal, Trash2 } from 'lucide-react'
import type { EnvVar, Task } from '@/api'
import { api } from '@/api'
import { getNodes, type InterconnectNode } from '@/api/interconnect'
import * as interconnect from '@/api/interconnect'
import { useCreateEnv, useDeleteEnv, useEnvs, useUpdateEnv } from '@/api/hooks'
import { TagInput } from '@/components/business/TagInput'
import { Button, Card, Input, Modal, PageHeader, Select, Switch, Tabs, Textarea } from '@/components/ui'
import { ENV_TYPE } from '@/constants'
import { formatDateTime } from '@/lib/format'
import { toast } from '@/lib/toast'

type EnvForm = {
  name: string
  value: string
  remark: string
  type: string
  tags: string
  enabled: boolean
  hidden: boolean
}

const emptyForm = (type: string = ENV_TYPE.NORMAL): EnvForm => ({
  name: '',
  value: '',
  remark: '',
  type,
  tags: '',
  enabled: true,
  hidden: type === ENV_TYPE.SECRET,
})

export default function Environments() {
  const [page, setPage] = useState(1)
  const [pageSize, setPageSize] = useState(() => {
    const n = Number(localStorage.getItem('envs_page_size') || '20')
    return [10, 20, 50, 100].includes(n) ? n : 20
  })
  const [name, setName] = useState('')
  const [debouncedName, setDebouncedName] = useState('')
  const [tags, setTags] = useState('')
  const [type, setType] = useState<string>(ENV_TYPE.NORMAL)
  const [showValues, setShowValues] = useState<Record<string, boolean>>({})
  const [dialogOpen, setDialogOpen] = useState(false)
  const [editing, setEditing] = useState<EnvVar | null>(null)
  const [form, setForm] = useState<EnvForm>(emptyForm())
  const [secretOk, setSecretOk] = useState(true)
  const [showSecretTip, setShowSecretTip] = useState(() => localStorage.getItem('bhp_hide_secret_tip') !== 'true')
  const [tasksOpen, setTasksOpen] = useState(false)
  const [relatedTasks, setRelatedTasks] = useState<Task[]>([])
  const [relatedName, setRelatedName] = useState('')
  const [message, setMessage] = useState('')
  const [syncOpen, setSyncOpen] = useState(false)
  const [syncEnv, setSyncEnv] = useState<EnvVar | null>(null)
  const [syncNodes, setSyncNodes] = useState<InterconnectNode[]>([])
  const [syncSelected, setSyncSelected] = useState<string[]>([])
  const [syncing, setSyncing] = useState(false)

  const { data, isLoading, refetch, isFetching } = useEnvs({
    page,
    page_size: pageSize,
    name: debouncedName || undefined,
    type,
    tags: tags || undefined,
  })
  const createEnv = useCreateEnv()
  const updateEnv = useUpdateEnv()
  const deleteEnv = useDeleteEnv()

  const items = Array.isArray(data?.data) ? data.data : []
  const total = data?.total || 0
  const totalPages = Math.max(1, Math.ceil(total / pageSize))
  const title = useMemo(() => (type === ENV_TYPE.SECRET ? '机密管理' : '环境变量'), [type])

  useEffect(() => {
    localStorage.setItem('envs_page_size', String(pageSize))
  }, [pageSize])

  useEffect(() => {
    const t = setTimeout(() => {
      setDebouncedName(name)
      setPage(1)
    }, 300)
    return () => clearTimeout(t)
  }, [name])

  useEffect(() => {
    if (type !== ENV_TYPE.SECRET) return
    api.env
      .secretStatus()
      .then(setSecretOk)
      .catch(() => setSecretOk(true))
  }, [type])

  function openCreate() {
    setEditing(null)
    setForm(emptyForm(type))
    setDialogOpen(true)
  }

  function openEdit(env: EnvVar) {
    setEditing(env)
    setForm({
      name: env.name,
      value: env.value || '',
      remark: env.remark || '',
      type: env.type || type,
      tags: env.tags || '',
      enabled: env.enabled !== false,
      hidden: !!env.hidden,
    })
    setDialogOpen(true)
  }

  async function save() {
    if (!form.name.trim()) {
      setMessage('请输入名称')
      return
    }
    try {
      const payload: Partial<EnvVar> = {
        name: form.name.trim(),
        value: form.value,
        remark: form.remark,
        type: form.type,
        tags: form.tags,
        enabled: form.enabled,
        hidden: form.type === ENV_TYPE.SECRET ? true : form.hidden,
      }
      if (editing) {
        await updateEnv.mutateAsync({ id: editing.id, data: { ...editing, ...payload } })
      } else {
        await createEnv.mutateAsync(payload)
      }
      setDialogOpen(false)
      setMessage(editing ? '已更新' : '已创建')
      refetch()
    } catch (e: any) {
      setMessage(e?.message || '保存失败')
    }
  }

  async function toggleEnabled(env: EnvVar) {
    await updateEnv.mutateAsync({ id: env.id, data: { ...env, enabled: !env.enabled } })
  }

  async function handleDelete(id: string) {
    if (!confirm('确认删除该变量？')) return
    try {
      const res = await deleteEnv.mutateAsync(id)
      if (res && typeof res === 'object' && 'code' in res && (res as any).code !== 200) {
        throw new Error((res as any).msg || '删除失败')
      }
      toast.success('已删除')
      refetch()
    } catch (e: any) {
      setMessage(e?.message || '删除失败')
      toast.error(e?.message || '删除失败')
    }
  }

  async function openTasks(env: EnvVar) {
    setRelatedName(env.name)
    setTasksOpen(true)
    try {
      const list = await api.env.tasks(env.id)
      setRelatedTasks(Array.isArray(list) ? list : [])
    } catch {
      setRelatedTasks([])
    }
  }

  async function openSyncDialog(env: EnvVar) {
    setSyncEnv(env)
    setSyncSelected([])
    setSyncOpen(true)
    try {
      const nodes = await getNodes()
      setSyncNodes(Array.isArray(nodes) ? nodes : [])
    } catch {
      setSyncNodes([])
      setMessage('获取互联节点失败')
    }
  }

  async function confirmSyncEnv() {
    if (!syncEnv || syncSelected.length === 0) {
      setMessage('请选择至少一个目标节点')
      return
    }
    setSyncing(true)
    try {
      await interconnect.syncEnv(syncSelected, [syncEnv])
      setMessage('变量已同步到所选节点')
      toast.success('变量同步成功')
      setSyncOpen(false)
    } catch (e: any) {
      setMessage(e?.message || '同步失败')
      toast.error(e?.message || '同步失败')
    } finally {
      setSyncing(false)
    }
  }

  function maskValue(value: string) {
    return '•'.repeat(Math.min(value?.length || 8, 20))
  }

  function closeSecretTip() {
    setShowSecretTip(false)
    localStorage.setItem('bhp_hide_secret_tip', 'true')
  }

  return (
    <div>
      <PageHeader
        title={title}
        description={type === ENV_TYPE.SECRET ? '管理加密敏感数据' : '管理脚本执行时的环境变量'}
        actions={
          <>
            <Button variant="secondary" onClick={() => refetch()} disabled={isFetching}>
              <RefreshCw size={14} className={isFetching ? 'animate-spin' : ''} />
              刷新
            </Button>
            <Button onClick={openCreate} disabled={type === ENV_TYPE.SECRET && !secretOk}>
              <Plus size={14} />
              新建{type === ENV_TYPE.SECRET ? '机密' : '变量'}
            </Button>
          </>
        }
      />

      {message ? (
        <div className="mb-3 rounded-md border border-[var(--border)] bg-[var(--bg-tertiary)] px-3 py-2 text-sm">{message}</div>
      ) : null}

      <div className="mb-4 flex flex-wrap items-center gap-2">
        <Tabs
          value={type}
          onValueChange={(v) => {
            setType(v)
            setPage(1)
          }}
          items={[
            { value: ENV_TYPE.NORMAL, label: '变量' },
            { value: ENV_TYPE.SECRET, label: '机密' },
          ]}
        />
        <div className="relative min-w-[180px] flex-1 max-w-xs">
          <Search size={14} className="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-[var(--text-muted)]" />
          <Input className="pl-9" placeholder="搜索名称" value={name} onChange={(e) => setName(e.target.value)} />
        </div>
        <div className="min-w-[160px] max-w-xs flex-1">
          <TagInput value={tags} onChange={setTags} placeholder="标签过滤（回车添加）" />
        </div>
      </div>

      {type === ENV_TYPE.SECRET && secretOk && showSecretTip ? (
        <div className="mb-4 flex items-start justify-between gap-2 rounded-lg border border-amber-500/20 bg-amber-500/10 px-3 py-2 text-sm text-amber-600 dark:text-amber-400">
          <span>
            <Shield size={14} className="mr-1 inline" />
            机密仅在正式任务执行时解密注入，测试运行与临时终端无法获取。
          </span>
          <button className="text-xs opacity-70" onClick={closeSecretTip}>
            关闭
          </button>
        </div>
      ) : null}

      {type === ENV_TYPE.SECRET && !secretOk ? (
        <Card className="p-8 text-center">
          <Shield className="mx-auto mb-3 text-red-400" size={32} />
          <div className="font-medium">未配置加密密钥</div>
          <p className="mt-2 text-sm text-[var(--text-muted)]">
            请在启动时配置 <code className="font-mono">TASKPOOL_SECRET_KEY</code> 环境变量后再使用机密功能。
          </p>
        </Card>
      ) : (
        <Card className="overflow-hidden">
          <div className="border-b border-[var(--border)] px-4 py-3 text-sm text-[var(--text-muted)]">
            共 {total} 条 · 第 {page}/{totalPages} 页
          </div>
          {isLoading ? (
            <div className="p-6 text-[var(--text-muted)]">加载中...</div>
          ) : items.length === 0 ? (
            <div className="p-8 text-center text-sm text-[var(--text-muted)]">
              {type === ENV_TYPE.SECRET ? <Shield className="mx-auto mb-2 opacity-50" size={28} /> : <Terminal className="mx-auto mb-2 opacity-50" size={28} />}
              暂无数据
            </div>
          ) : (
            <div className="divide-y divide-[var(--border)]">
              {items.map((env) => {
                const visible = showValues[env.id] ?? !env.hidden
                return (
                  <div key={env.id} className="flex flex-col gap-3 p-4 md:flex-row md:items-center md:justify-between">
                    <div className="min-w-0 flex-1">
                      <div className="flex flex-wrap items-center gap-2">
                        <span className="font-medium">{env.name}</span>
                        {!env.enabled ? (
                          <span className="rounded bg-zinc-500/15 px-1.5 py-0.5 text-xs text-zinc-400">禁用</span>
                        ) : null}
                        {env.tags
                          ? env.tags
                              .split(',')
                              .filter(Boolean)
                              .map((t) => (
                                <span key={t} className="rounded bg-[var(--bg-tertiary)] px-1.5 py-0.5 text-xs text-[var(--text-muted)]">
                                  {t.trim()}
                                </span>
                              ))
                          : null}
                      </div>
                      <div className="mt-1 break-all font-mono text-xs text-[var(--text-secondary)]">
                        {visible ? env.value || '(空)' : maskValue(env.value || '')}
                      </div>
                      <div className="mt-1 text-xs text-[var(--text-muted)]">
                        {env.remark || '-'} · {formatDateTime(env.updated_at || env.created_at)}
                      </div>
                    </div>
                    <div className="flex flex-wrap items-center gap-2">
                      <Switch checked={env.enabled !== false} onCheckedChange={() => toggleEnabled(env)} />
                      <Button
                        size="sm"
                        variant="ghost"
                        onClick={() => setShowValues((s) => ({ ...s, [env.id]: !visible }))}
                      >
                        {visible ? <EyeOff size={14} /> : <Eye size={14} />}
                      </Button>
                      <Button size="sm" variant="ghost" onClick={() => openTasks(env)} title="关联任务">
                        <Link2 size={14} />
                      </Button>
                      <Button size="sm" variant="ghost" onClick={() => openSyncDialog(env)} title="同步到节点">
                        <Share2 size={14} />
                      </Button>
                      <Button size="sm" variant="secondary" onClick={() => openEdit(env)}>
                        <Pencil size={14} />
                      </Button>
                      <Button size="sm" variant="danger" onClick={() => handleDelete(env.id)}>
                        <Trash2 size={14} />
                      </Button>
                    </div>
                  </div>
                )
              })}
            </div>
          )}
          <div className="flex flex-wrap items-center justify-between gap-3 border-t border-[var(--border)] px-4 py-3">
            <span className="text-sm text-[var(--text-muted)]">
              共 {total} 条 · 第 {page}/{totalPages} 页
            </span>
            <div className="flex flex-wrap items-center gap-2">
              <Select
                className="w-[110px]"
                value={String(pageSize)}
                onChange={(e) => {
                  setPageSize(Number(e.target.value) || 20)
                  setPage(1)
                }}
              >
                <option value="10">10 条/页</option>
                <option value="20">20 条/页</option>
                <option value="50">50 条/页</option>
                <option value="100">100 条/页</option>
              </Select>
              <Button variant="secondary" size="sm" disabled={page <= 1} onClick={() => setPage((p) => p - 1)}>
                上一页
              </Button>
              <Button variant="secondary" size="sm" disabled={page >= totalPages} onClick={() => setPage((p) => p + 1)}>
                下一页
              </Button>
            </div>
          </div>
        </Card>
      )}

      <Modal
        open={dialogOpen}
        title={editing ? '编辑变量' : '新建变量'}
        onClose={() => setDialogOpen(false)}
        size="lg"
        footer={
          <>
            <Button variant="secondary" onClick={() => setDialogOpen(false)}>
              取消
            </Button>
            <Button onClick={save} disabled={createEnv.isPending || updateEnv.isPending}>
              保存
            </Button>
          </>
        }
      >
        <div className="space-y-3">
          <Input placeholder="名称 *" value={form.name} onChange={(e) => setForm((f) => ({ ...f, name: e.target.value }))} />
          <Textarea placeholder="值" value={form.value} onChange={(e) => setForm((f) => ({ ...f, value: e.target.value }))} />
          <Input placeholder="备注" value={form.remark} onChange={(e) => setForm((f) => ({ ...f, remark: e.target.value }))} />
          <TagInput value={form.tags} onChange={(v) => setForm((f) => ({ ...f, tags: v }))} placeholder="标签" />
          <label className="flex items-center justify-between text-sm">
            <span>启用</span>
            <Switch checked={form.enabled} onCheckedChange={(v) => setForm((f) => ({ ...f, enabled: v }))} />
          </label>
        </div>
      </Modal>

      <Modal open={tasksOpen} title={`关联任务 · ${relatedName}`} onClose={() => setTasksOpen(false)} size="lg">
        {relatedTasks.length === 0 ? (
          <div className="text-sm text-[var(--text-muted)]">暂无关联任务</div>
        ) : (
          <div className="divide-y divide-[var(--border)]">
            {relatedTasks.map((t) => (
              <div key={t.id} className="py-2 text-sm">
                <div className="font-medium">{t.name}</div>
                <div className="text-xs text-[var(--text-muted)]">{t.id}</div>
              </div>
            ))}
          </div>
        )}
      </Modal>

      <Modal
        open={syncOpen}
        title="同步变量到节点"
        onClose={() => setSyncOpen(false)}
        footer={
          <>
            <Button variant="secondary" onClick={() => setSyncOpen(false)}>
              取消
            </Button>
            <Button onClick={confirmSyncEnv} disabled={syncing || syncSelected.length === 0}>
              {syncing ? '同步中...' : '确认同步'}
            </Button>
          </>
        }
      >
        <div className="space-y-3">
          <p className="text-sm text-[var(--text-secondary)]">
            将变量 <span className="font-medium">{syncEnv?.name}</span> 同步到所选子节点
          </p>
          {syncNodes.length === 0 ? (
            <div className="text-sm text-[var(--text-muted)]">暂无可用节点，请先在互联管理中添加</div>
          ) : (
            <div className="max-h-56 space-y-2 overflow-y-auto">
              {syncNodes.map((node) => {
                const checked = syncSelected.includes(node.id)
                return (
                  <label key={node.id} className="flex cursor-pointer items-center gap-2 rounded border border-[var(--border)] px-3 py-2 text-sm hover:bg-[var(--bg-hover)]">
                    <input
                      type="checkbox"
                      checked={checked}
                      onChange={(e) => {
                        setSyncSelected((prev) => (e.target.checked ? [...prev, node.id] : prev.filter((id) => id !== node.id)))
                      }}
                    />
                    <span className="min-w-0 flex-1 truncate">{node.name}</span>
                    <span className="text-xs text-[var(--text-muted)]">{node.status || 'unknown'}</span>
                  </label>
                )
              })}
            </div>
          )}
        </div>
      </Modal>
    </div>
  )
}
