import { useEffect, useState } from 'react'
import {
  Button, Card, Empty, Form, Input, message, Modal, Popconfirm,
  Select, Space, Table, Tag, Tooltip,
} from 'antd'
import {
  PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined,
  ReloadOutlined, AppstoreAddOutlined,
} from '@ant-design/icons'
import Editor from '@monaco-editor/react'
import { modelConfigsApi, scenariosApi, type Scenario } from '../api'
import FormDrawer from '../components/FormDrawer'
import PageWrapper from '../components/PageWrapper'
import { useResource } from '../hooks/useResource'
import { colors } from '../tokens'
import { formatDateTime } from '../utils/date'
import { MODEL_CONFIGS_CHANGED_EVENT } from '../utils/modelConfigEvents'

const YAML_TEMPLATE = `# 场景用例示例（JSON 格式）
[
  {
    "id": "case-1",
    "type": "single",
    "messages": ["你好，请问挂号怎么操作？"],
    "eval_rules": [
      { "type": "response_time", "params": { "max_ms": 30000 } }
    ]
  },
  {
    "id": "case-dynamic-1",
    "type": "dynamic",
    "prompt": "你是一个来社区医院咨询的患者，请围绕挂号流程提几个问题",
    "turns": 3,
    "eval_rules": [
      { "type": "response_time", "params": { "max_ms": 30000 } }
    ]
  }
]`

export default function ScenariosPage() {
  const { data: scenarios, loading, reload } = useResource(
    () => scenariosApi.list().then((r) => r.data),
    { tabPath: '/scenarios' },
  )
  const {
    data: modelConfigs,
    loading: modelConfigsLoading,
    reload: reloadModelConfigs,
  } = useResource(() => modelConfigsApi.list({ enabled: true }).then((r) => r.data))
  const [drawerOpen, setDrawerOpen] = useState(false)
  const [previewOpen, setPreviewOpen] = useState(false)
  const [previewData, setPreviewData] = useState<any>(null)
  const [editingScenario, setEditingScenario] = useState<Scenario | null>(null)
  const [submitting, setSubmitting] = useState(false)
  const [casesJson, setCasesJson] = useState(YAML_TEMPLATE)
  const [modelBindings, setModelBindings] = useState<Record<string, string>>({})
  const [form] = Form.useForm()

  // Template picker
  const [tplModalOpen, setTplModalOpen] = useState(false)
  const [templates, setTemplates] = useState<any[]>([])
  const [tplLoading, setTplLoading] = useState(false)

  useEffect(() => {
    const onChanged = () => void reloadModelConfigs()
    window.addEventListener(MODEL_CONFIGS_CHANGED_EVENT, onChanged)
    return () => window.removeEventListener(MODEL_CONFIGS_CHANGED_EVENT, onChanged)
  }, [reloadModelConfigs])

  const openCreate = () => {
    reloadModelConfigs()
    setEditingScenario(null)
    form.resetFields()
    setCasesJson(YAML_TEMPLATE)
    setModelBindings({})
    setDrawerOpen(true)
  }

  const openTemplateModal = async () => {
    setTplModalOpen(true)
    if (templates.length === 0) {
      setTplLoading(true)
      try {
        const res = await scenariosApi.listTemplates()
        setTemplates(res.data)
      } catch { /* handled by interceptor */ }
      finally { setTplLoading(false) }
    }
  }

  const applyTemplate = (tpl: any) => {
    reloadModelConfigs()
    setTplModalOpen(false)
    setEditingScenario(null)
    form.resetFields()
    form.setFieldsValue({ name: `${tpl.name}（副本）`, description: tpl.description, tags: tpl.tags.join(', ') })
    setCasesJson(JSON.stringify(tpl.cases, null, 2))
    setModelBindings(tpl.model_bindings || {})
    setDrawerOpen(true)
  }

  const openEdit = (scenario: Scenario) => {
    reloadModelConfigs()
    setEditingScenario(scenario)
    form.setFieldsValue({
      name: scenario.name,
      description: scenario.description,
      tags: scenario.tags.join(', '),
    })
    setCasesJson(JSON.stringify(scenario.cases, null, 2))
    setModelBindings(scenario.model_bindings || {})
    setDrawerOpen(true)
  }

  const openPreview = (scenario: Scenario) => {
    setPreviewData(scenario)
    setPreviewOpen(true)
  }

  const handleSubmit = async () => {
    const values = await form.validateFields()
    let cases: any[]
    try {
      cases = JSON.parse(casesJson)
    } catch {
      message.error('用例 JSON 格式错误')
      return
    }

    const tags = values.tags
      ? values.tags.split(',').map((t: string) => t.trim()).filter(Boolean)
      : []

    const payload = {
      name: values.name,
      description: values.description || '',
      tags,
      cases,
      model_bindings: modelBindings,
    }

    if (editingScenario) {
      setSubmitting(true)
      try {
        await scenariosApi.update(editingScenario.id, payload)
        message.success('更新成功')
      } finally {
        setSubmitting(false)
      }
    } else {
      setSubmitting(true)
      try {
        await scenariosApi.create(payload)
        message.success('创建成功')
      } finally {
        setSubmitting(false)
      }
    }
    setDrawerOpen(false)
    reload()
  }

  const handleDelete = async (id: string) => {
    await scenariosApi.delete(id)
    message.success('已删除')
    reload()
  }

  const columns = [
    { title: '名称', dataIndex: 'name', key: 'name', width: 200,
      render: (v: string) => <span style={{ fontWeight: 500 }}>{v}</span>,
    },
    { title: '版本', dataIndex: 'version', key: 'version', width: 70,
      render: (v: number) => <Tag color="geekblue">v{v ?? 1}</Tag>,
    },
    { title: '描述', dataIndex: 'description', key: 'description', ellipsis: true },
    { title: '标签', dataIndex: 'tags', key: 'tags', width: 200,
      render: (tags: string[]) => tags.map((t) => <Tag key={t}>{t}</Tag>),
    },
    { title: '用例数', key: 'cases', width: 80,
      render: (_: any, r: Scenario) => r.cases.length,
    },
    { title: '创建时间', dataIndex: 'created_at', key: 'created_at', width: 180,
      render: (t: string) => formatDateTime(t),
    },
    { title: '操作', key: 'action', width: 140, fixed: 'right' as const,
      render: (_: any, record: Scenario) => (
        <Space size={4}>
          <Tooltip title="预览">
            <Button size="small" type="text" icon={<EyeOutlined />} onClick={() => openPreview(record)} />
          </Tooltip>
          <Tooltip title="编辑">
            <Button size="small" type="text" icon={<EditOutlined />} onClick={() => openEdit(record)} />
          </Tooltip>
          <Popconfirm title="删除该评测场景？" onConfirm={() => handleDelete(record.id)}>
            <Tooltip title="删除">
              <Button size="small" type="text" danger icon={<DeleteOutlined />} />
            </Tooltip>
          </Popconfirm>
        </Space>
      ),
    },
  ]

  return (
    <PageWrapper
      title="评测场景"
      description="管理评测用例集合与评测规则"
      inline
      fullHeight
      extra={
        <Space>
          <Tooltip title="刷新">
            <Button
              size="middle"
              icon={<ReloadOutlined />}
              onClick={() => {
                reload()
                reloadModelConfigs()
              }}
            />
          </Tooltip>
          <Button icon={<AppstoreAddOutlined />} onClick={openTemplateModal}>
            从模板新建
          </Button>
          <Button type="primary" icon={<PlusOutlined />} onClick={openCreate}>
            新增
          </Button>
        </Space>
      }
    >
      <div style={{ height: '100%', overflowY: 'auto', padding: '0 16px 16px' }}>
        <Table
          dataSource={scenarios ?? []}
          columns={columns}
          rowKey="id"
          loading={loading}
          pagination={(scenarios?.length ?? 0) > 20 ? { pageSize: 20, showTotal: (t) => `共 ${t} 个` } : false}
          locale={{ emptyText: <Empty description="还没有评测场景" /> }}
        />
      </div>

      <FormDrawer
        title={editingScenario ? `编辑评测场景（当前 v${editingScenario.version ?? 1}）` : '新增评测场景'}
        open={drawerOpen}
        onClose={() => setDrawerOpen(false)}
        onSubmit={handleSubmit}
        submitting={submitting}
        okText={editingScenario ? '更新' : '创建'}
        width={720}
      >
        <Form form={form} layout="vertical">
          <Form.Item name="name" label="名称" rules={[{ required: true, message: '请输入场景名称' }]}>
            <Input placeholder="例如：健康咨询基础场景" />
          </Form.Item>
          <Form.Item name="description" label="描述">
            <Input.TextArea rows={2} placeholder="场景描述" />
          </Form.Item>
          <Form.Item name="tags" label="标签（逗号分隔）">
            <Input placeholder="例如：health, basic, single-turn" />
          </Form.Item>
        </Form>

        <div style={{
          border: `1px solid ${colors.border}`, borderRadius: 8,
          padding: '12px 16px', marginBottom: 16,
        }}>
          <div style={{ fontWeight: 600, fontSize: 13, marginBottom: 12, color: colors.text }}>
            模型引用
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
            {[
              { purpose: 'generator', label: '动态用例生成', capability: 'chat' },
              { purpose: 'judge', label: 'LLM 评分', capability: 'chat' },
              { purpose: 'embedding', label: '语义相似度', capability: 'embedding' },
              { purpose: 'moderation', label: '内容审核', capability: 'moderation' },
            ].map((item) => (
              <div key={item.purpose}>
                <label style={{ fontSize: 12, color: '#666', display: 'block', marginBottom: 4 }}>{item.label}</label>
                <Select
                  allowClear
                  showSearch
                  loading={modelConfigsLoading}
                  optionFilterProp="label"
                  style={{ width: '100%' }}
                  placeholder="未绑定"
                  value={modelBindings[item.purpose]}
                  onChange={(value) => {
                    const next = { ...modelBindings }
                    if (value) next[item.purpose] = value
                    else delete next[item.purpose]
                    setModelBindings(next)
                  }}
                  options={(modelConfigs ?? [])
                    .filter((config) => config.capability === item.capability)
                    .map((config) => ({ value: config.id, label: `${config.name} · ${config.model_name || config.capability}` }))}
                />
              </div>
            ))}
          </div>
        </div>

        <div style={{ marginBottom: 8, fontWeight: 500, fontSize: 13, color: '#666' }}>用例定义（JSON）</div>
        <div style={{ border: '1px solid #d9d9d9', borderRadius: 8, overflow: 'hidden' }}>
          <Editor
            height="400px"
            defaultLanguage="json"
            theme="vs-dark"
            value={casesJson}
            onChange={(v) => setCasesJson(v || '')}
            options={{
              minimap: { enabled: false },
              fontSize: 13,
              lineNumbers: 'on',
              scrollBeyondLastLine: false,
              automaticLayout: true,
            }}
          />
        </div>
      </FormDrawer>

      <Modal
        title={`场景预览: ${previewData?.name || ''}${previewData?.version != null ? `（v${previewData.version}）` : ''}`}
        open={previewOpen}
        onCancel={() => setPreviewOpen(false)}
        footer={null}
        width={700}
      >
        {previewData && (
          <div>
            <p style={{ marginBottom: 8 }}><strong>描述：</strong>{previewData.description || '无'}</p>
            <p style={{ marginBottom: 8 }}><strong>标签：</strong>{previewData.tags?.join(', ') || '无'}</p>
            <p style={{ marginBottom: 12 }}><strong>用例数：</strong>{previewData.cases?.length || 0}</p>
            <div style={{ background: '#1e1e2e', borderRadius: 8, padding: 16, maxHeight: 400, overflow: 'auto' }}>
              <pre style={{ color: '#d4d4d4', fontSize: 12, margin: 0 }}>
                {JSON.stringify(previewData.cases, null, 2)}
              </pre>
            </div>
          </div>
        )}
      </Modal>

      {/* Template picker */}
      <Modal
        title="从模板新建场景"
        open={tplModalOpen}
        onCancel={() => setTplModalOpen(false)}
        footer={null}
        width={680}
      >
        {tplLoading ? (
          <div style={{ textAlign: 'center', padding: 40, color: colors.textMuted }}>加载模板…</div>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            {templates.map((tpl) => (
              <Card
                key={tpl.id}
                size="small"
                hoverable
                onClick={() => applyTemplate(tpl)}
                style={{ cursor: 'pointer', borderColor: colors.border }}
              >
                <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between' }}>
                  <div>
                    <div style={{ fontWeight: 600, fontSize: 14, color: colors.text, marginBottom: 4 }}>
                      {tpl.name}
                    </div>
                    <div style={{ fontSize: 12, color: colors.textSecondary, marginBottom: 6 }}>
                      {tpl.description}
                    </div>
                    <Space size={4} wrap>
                      {tpl.tags.map((t: string) => <Tag key={t} style={{ margin: 0 }}>{t}</Tag>)}
                    </Space>
                  </div>
                  <div style={{ fontSize: 12, color: colors.textMuted, flexShrink: 0, marginLeft: 12 }}>
                    {tpl.cases?.length ?? 0} 个用例
                  </div>
                </div>
              </Card>
            ))}
          </div>
        )}
      </Modal>
    </PageWrapper>
  )
}
