import { Button, Card, Space, Table, Tag, Toast, Typography } from '@douyinfe/semi-ui';
import { IconCopy } from '@douyinfe/semi-icons';
import { useEffect, useState } from 'react';
import { api } from '../api/client';
import type { OpsHealth, QualityAlertRule, QualityNotificationPlan, QualityNotificationPolicy, QualityPriorityIssue } from '../api/types';
import { PageHeader } from '../components/PageHeader';
import { qualityIssueLabel } from '../domain/qualityIssue';

function formatEscalationMinutes(minutes?: number) {
  if (!Number.isFinite(minutes) || Number(minutes) <= 0) return '-';
  const value = Number(minutes);
  if (value < 60) return `${value} 分钟升级`;
  const hours = Math.floor(value / 60);
  const rest = value % 60;
  return rest > 0 ? `${hours} 小时 ${rest} 分钟升级` : `${hours} 小时升级`;
}

function ruleColor(rule: QualityAlertRule): 'green' | 'orange' | 'red' | 'grey' {
  if ((rule.count ?? 0) <= 0) return 'green';
  if (rule.level === 'P0') return 'red';
  if (rule.level === 'P1') return 'orange';
  return 'grey';
}

function ruleTitle(rule: QualityAlertRule) {
  return rule.title || qualityIssueLabel(rule.issueType);
}

function notificationRulesRunbook(plan: QualityNotificationPlan | null, release?: string) {
  const rules = plan?.rules ?? [];
  const policies = plan?.policies ?? [];
  const lines = [
    '【通知规则Runbook】',
    `运行版本：${release?.trim() || '-'}`,
    `活跃规则：${(plan?.activeRuleCount ?? rules.filter((rule) => rule.count > 0).length).toLocaleString()} 类`,
    `P0规则：${(plan?.p0RuleCount ?? rules.filter((rule) => rule.count > 0 && rule.level === 'P0').length).toLocaleString()} 类`,
    '',
    '触发规则：',
    ...rules.map((rule, index) => [
      `${index + 1}. ${ruleTitle(rule)} / ${rule.level} / ${rule.owner}`,
      `   触发：${rule.trigger}`,
      `   通知：${rule.notify}`,
      `   SLA：${rule.sla}`,
      `   当前命中：${Number(rule.count ?? 0).toLocaleString()}`
    ].join('\n')),
    '',
    '通知策略：',
    ...policies.map((policy, index) => [
      `${index + 1}. ${policy.name} / ${policy.target}`,
      `   条件：${policy.condition}`,
      `   渠道：${policy.channel}`,
      `   升级：${formatEscalationMinutes(policy.escalationMinutes)}`,
      `   验收：${policy.acceptanceCriteria || '-'}`
    ].join('\n'))
  ];
  return lines.join('\n');
}

function priorityIssueDigest(plan: QualityNotificationPlan | null, release?: string) {
  const issues = plan?.priorityIssues ?? [];
  return [
    '【当前待通知告警】',
    `运行版本：${release?.trim() || '-'}`,
    `待通知：${issues.length.toLocaleString()} 条`,
    ...issues.map((issue, index) => [
      `${index + 1}. [${issue.priority}] ${issue.vehicleLabel}`,
      `   问题：${qualityIssueLabel(issue.issueType)} / ${issue.protocol}`,
      `   SLA：${issue.sla}`,
      `   建议动作：${issue.actionLabel}`,
      `   详情：${issue.detail || '-'}`,
      `   车辆服务：${window.location.origin}${window.location.pathname}${issue.vehicleHash}`,
      `   实时定位：${window.location.origin}${window.location.pathname}${issue.realtimeHash}`,
      `   轨迹证据：${window.location.origin}${window.location.pathname}${issue.historyHash}`,
      `   RAW证据：${window.location.origin}${window.location.pathname}${issue.rawHash}`
    ].join('\n'))
  ].join('\n');
}

function navigateHash(hash: string) {
  if (!hash) return;
  window.location.hash = hash;
}

async function copyText(value: string, label: string) {
  try {
    await navigator.clipboard.writeText(value);
    Toast.success(`已复制${label}`);
  } catch {
    Toast.error(`复制${label}失败`);
  }
}

export function NotificationRules() {
  const [plan, setPlan] = useState<QualityNotificationPlan | null>(null);
  const [health, setHealth] = useState<OpsHealth | null>(null);
  const [loading, setLoading] = useState(true);

  const load = () => {
    setLoading(true);
    Promise.all([
      api.alertEventNotificationPlan(new URLSearchParams({ limit: '50' })),
      api.opsHealth().catch(() => null)
    ])
      .then(([nextPlan, nextHealth]) => {
        setPlan(nextPlan);
        setHealth(nextHealth);
      })
      .catch((error: Error) => Toast.error(error.message))
      .finally(() => setLoading(false));
  };

  useEffect(() => {
    load();
  }, []);

  const rules = plan?.rules ?? [];
  const policies = plan?.policies ?? [];
  const priorityIssues = plan?.priorityIssues ?? [];
  const activeRuleCount = plan?.activeRuleCount ?? rules.filter((rule) => rule.count > 0).length;
  const p0RuleCount = plan?.p0RuleCount ?? rules.filter((rule) => rule.count > 0 && rule.level === 'P0').length;
  const release = health?.runtime?.platformRelease ?? '';

  return (
    <div className="vp-page">
      <PageHeader title="通知规则" description="集中管理告警触发条件、通知对象、升级时间和验收标准，让断链与数据质量问题可追踪、可通知、可闭环" />
      <div className="vp-kpi-grid">
        <Card bordered loading={loading}>
          <div className="vp-kpi-value">{activeRuleCount.toLocaleString()}</div>
          <div className="vp-kpi-label">活跃规则</div>
        </Card>
        <Card bordered loading={loading}>
          <div className="vp-kpi-value">{p0RuleCount.toLocaleString()}</div>
          <div className="vp-kpi-label">P0规则</div>
        </Card>
        <Card bordered loading={loading}>
          <div className="vp-kpi-value">{policies.length.toLocaleString()}</div>
          <div className="vp-kpi-label">通知策略</div>
        </Card>
        <Card bordered loading={loading}>
          <div className="vp-kpi-value">{priorityIssues.length.toLocaleString()}</div>
          <div className="vp-kpi-label">待通知告警</div>
        </Card>
        <Card bordered loading={loading}>
          <div className="vp-kpi-value">{release || '-'}</div>
          <div className="vp-kpi-label">运行版本</div>
        </Card>
      </div>

      <Card
        bordered
        title={<Space><span>规则运行手册</span><Button size="small" aria-label="复制通知规则Runbook" icon={<IconCopy />} onClick={() => copyText(notificationRulesRunbook(plan, release), '通知规则Runbook')}>复制通知规则Runbook</Button><Button size="small" loading={loading} onClick={load}>刷新</Button></Space>}
      >
        <div className="vp-alert-flow">
          {[
            { label: '触发', value: `${activeRuleCount} 类规则`, detail: '规则从车辆服务质量、来源断链、字段缺失和容量风险中生成。' },
            { label: '通知', value: `${policies.length} 套策略`, detail: '策略定义目标人群、渠道、升级窗口和验收口径。' },
            { label: '闭环', value: `${p0RuleCount} 类 P0`, detail: 'P0 问题必须有证据链接、恢复时间和验收结果。' }
          ].map((item) => (
            <div key={item.label} className="vp-alert-flow-item">
              <Tag color="blue">{item.label}</Tag>
              <div className="vp-alert-flow-value">{item.value}</div>
              <div>{item.detail}</div>
            </div>
          ))}
        </div>
      </Card>

      <Card bordered title="触发规则" loading={loading} style={{ marginTop: 16 }}>
        <Table<QualityAlertRule>
          pagination={false}
          dataSource={rules}
          rowKey="issueType"
          columns={[
            { title: '规则', width: 180, render: (_: unknown, row: QualityAlertRule) => ruleTitle(row) },
            { title: '级别', width: 90, render: (_: unknown, row: QualityAlertRule) => <Tag color={ruleColor(row)}>{row.level}</Tag> },
            { title: '责任团队', width: 130, dataIndex: 'owner' },
            { title: '当前命中', width: 110, render: (_: unknown, row: QualityAlertRule) => Number(row.count ?? 0).toLocaleString() },
            { title: '触发条件', dataIndex: 'trigger' },
            { title: '通知动作', dataIndex: 'notify' },
            { title: 'SLA', width: 120, dataIndex: 'sla' }
          ]}
        />
      </Card>

      <Card
        bordered
        loading={loading}
        title={<Space><span>当前待通知告警</span><Button size="small" aria-label="复制待通知汇总" disabled={priorityIssues.length === 0} icon={<IconCopy />} onClick={() => copyText(priorityIssueDigest(plan, release), '待通知告警')}>复制待通知汇总</Button></Space>}
        style={{ marginTop: 16 }}
      >
        <Table<QualityPriorityIssue>
          pagination={false}
          dataSource={priorityIssues}
          rowKey={(row?: QualityPriorityIssue) => `${row?.priority ?? ''}-${row?.protocol ?? ''}-${row?.issueType ?? ''}-${row?.vehicleLabel ?? ''}-${row?.lastSeen ?? ''}`}
          columns={[
            { title: '优先级', width: 90, render: (_: unknown, row: QualityPriorityIssue) => <Tag color={row.priority === 'P0' ? 'red' : 'orange'}>{row.priority}</Tag> },
            { title: '车辆', width: 210, dataIndex: 'vehicleLabel' },
            { title: '问题', width: 130, render: (_: unknown, row: QualityPriorityIssue) => qualityIssueLabel(row.issueType) },
            { title: 'SLA', width: 120, dataIndex: 'sla' },
            { title: '建议动作', width: 160, dataIndex: 'actionLabel' },
            { title: '最后时间', width: 170, dataIndex: 'lastSeen' },
            {
              title: '说明',
              render: (_: unknown, row: QualityPriorityIssue) => (
                <Typography.Text ellipsis={{ showTooltip: true }}>{row.detail || row.actionDetail || '-'}</Typography.Text>
              )
            },
            {
              title: '证据',
              width: 360,
              render: (_: unknown, row: QualityPriorityIssue) => (
                <Space spacing={4} wrap>
                  <Button size="small" disabled={!row.vehicleHash} onClick={() => navigateHash(row.vehicleHash)}>车辆服务</Button>
                  <Button size="small" disabled={!row.realtimeHash} onClick={() => navigateHash(row.realtimeHash)}>实时</Button>
                  <Button size="small" disabled={!row.historyHash} onClick={() => navigateHash(row.historyHash)}>轨迹</Button>
                  <Button size="small" disabled={!row.rawHash} onClick={() => navigateHash(row.rawHash)}>RAW</Button>
                  <Button size="small" aria-label="复制单条告警通知" icon={<IconCopy />} onClick={() => copyText(row.notificationText, '告警通知')}>复制通知</Button>
                </Space>
              )
            }
          ]}
        />
      </Card>

      <Card bordered title="通知策略" loading={loading} style={{ marginTop: 16 }}>
        <div className="vp-notification-policy-list">
          {policies.map((policy: QualityNotificationPolicy) => (
            <div key={policy.name} className="vp-notification-policy">
              <div>
                <Space>
                  <Tag color={policy.name.startsWith('P0') ? 'red' : policy.name.startsWith('P1') ? 'orange' : 'grey'}>{policy.name}</Tag>
                  <strong>{policy.target}</strong>
                </Space>
                <div className="vp-alert-policy-detail">{policy.condition}</div>
                <div className="vp-alert-policy-detail">验收：{policy.acceptanceCriteria || '-'}</div>
              </div>
              <Space wrap>
                <Tag color="red">{formatEscalationMinutes(policy.escalationMinutes)}</Tag>
                <Tag color="blue">{policy.channel}</Tag>
              </Space>
            </div>
          ))}
        </div>
      </Card>
    </div>
  );
}
