import { useEffect, useMemo, useState, type FormEvent } from 'react';
import { Popover as AntPopover } from 'antd';
import { CheckCircle2, Gauge, History, RotateCcw, SlidersHorizontal } from 'lucide-react';
import type { IntegrationPlatform, ModelRateLimitStatus, PlatformDynamicPriorityUpdateRequest, PlatformPolicyEvent, PriorityDemotionRecord } from '@easyai-ai-gateway/contracts';
import { Badge, Button, Card, CardContent, CardHeader, CardTitle, EmptyState, FormDialog, Input, Label, Table, TableCell, TableHead, TableRow } from '../../components/ui';

export function RealtimeLoadPanel(props: {
  modelRateLimits: ModelRateLimitStatus[];
  modelRateLimitsUpdatedAt: number | null;
  platforms: IntegrationPlatform[];
  onSavePlatformDynamicPriority: (platformId: string, input: PlatformDynamicPriorityUpdateRequest) => Promise<void>;
  onRestoreRuntimeModel: (platformModelId: string) => Promise<void>;
}) {
  const [now, setNow] = useState(() => Date.now());
  const [priorityDialog, setPriorityDialog] = useState<PriorityDialogState | null>(null);
  const [priorityError, setPriorityError] = useState('');
  const [prioritySaving, setPrioritySaving] = useState(false);
  const [restoreSavingId, setRestoreSavingId] = useState<string | null>(null);
  const platformMap = useMemo(() => new Map(props.platforms.map((item) => [item.id, item])), [props.platforms]);

  useEffect(() => {
    const timer = window.setInterval(() => setNow(Date.now()), 1000);
    return () => window.clearInterval(timer);
  }, []);

  function openPriorityDialog(status: ModelRateLimitStatus, platform: IntegrationPlatform | undefined) {
    setPriorityError('');
    setPriorityDialog({
      platform,
      status,
      value: formatPriority(platformEffectivePriority(status, platform)),
    });
  }

  function closePriorityDialog() {
    if (prioritySaving) return;
    setPriorityDialog(null);
    setPriorityError('');
  }

  async function submitPriorityForm(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!priorityDialog) return;
    const dynamicPriority = parsePriorityInput(priorityDialog.value);
    if (dynamicPriority === null) {
      setPriorityError('请输入大于等于 0 的整数。');
      return;
    }
    await savePriority(priorityDialog.status.platformId, { dynamicPriority });
  }

  async function resetPriority() {
    if (!priorityDialog) return;
    await savePriority(priorityDialog.status.platformId, { reset: true });
  }

  async function savePriority(platformId: string, input: PlatformDynamicPriorityUpdateRequest) {
    setPrioritySaving(true);
    setPriorityError('');
    try {
      await props.onSavePlatformDynamicPriority(platformId, input);
      setPriorityDialog(null);
    } catch (err) {
      setPriorityError(err instanceof Error ? err.message : '更新平台动态优先级失败');
    } finally {
      setPrioritySaving(false);
    }
  }

  async function restoreRuntimeModel(platformModelId: string) {
    setRestoreSavingId(platformModelId);
    try {
      await props.onRestoreRuntimeModel(platformModelId);
    } catch {
      // App-level state owns the error message.
    } finally {
      setRestoreSavingId(null);
    }
  }

  return (
    <section className="pageStack">
      <Card>
        <CardHeader>
          <div>
            <CardTitle>实时负载</CardTitle>
            <p className="mutedText">按平台模型查看实时 RPM、TPM、并发、排队、冷却和综合满载率。</p>
          </div>
        </CardHeader>
        <CardContent>
          <RateLimitStatusTable
            now={now}
            platformMap={platformMap}
            statuses={props.modelRateLimits}
            updatedAt={props.modelRateLimitsUpdatedAt}
            onAdjustPriority={openPriorityDialog}
            onRestoreRuntimeModel={restoreRuntimeModel}
            restoreSavingId={restoreSavingId}
          />
        </CardContent>
      </Card>
      <PlatformPriorityDialog
        dialog={priorityDialog}
        error={priorityError}
        saving={prioritySaving}
        onClose={closePriorityDialog}
        onReset={resetPriority}
        onSubmit={submitPriorityForm}
        onValueChange={(value) => setPriorityDialog((current) => current ? { ...current, value } : current)}
      />
    </section>
  );
}

type PriorityDialogState = {
  platform: IntegrationPlatform | undefined;
  status: ModelRateLimitStatus;
  value: string;
};

function RateLimitStatusTable(props: {
  statuses: ModelRateLimitStatus[];
  platformMap: Map<string, IntegrationPlatform>;
  now: number;
  updatedAt: number | null;
  onAdjustPriority: (status: ModelRateLimitStatus, platform: IntegrationPlatform | undefined) => void;
  onRestoreRuntimeModel: (platformModelId: string) => Promise<void>;
  restoreSavingId: string | null;
}) {
  if (!props.statuses.length) {
    return <EmptyState title="暂无实时负载" description="模型产生请求后会在这里显示实时 RPM、TPM 和并发窗口。" />;
  }
  return (
    <section className="platformLimitView">
      <div className="platformLimitHeader">
        <span><Gauge size={15} />按综合满载率从高到低排序</span>
        <small>每 3 秒刷新一次；TPM 显示已结算 + 预占；最新更新时间 {formatTimeOfDay(props.updatedAt)}。</small>
      </div>
      <div className="platformLimitTableViewport">
        <Table className="platformDataTable platformLimitTable">
          <TableRow className="shTableHeader">
            <TableHead>模型</TableHead>
            <TableHead>平台</TableHead>
            <TableHead className="platformLimitStatusHead">状态</TableHead>
            <TableHead className="platformLimitNumberHead">平台优先级</TableHead>
            <TableHead className="platformLimitNumberHead">满载率</TableHead>
            <TableHead className="platformLimitMetricHead platformLimitNumberHead" title="正在执行 / 并发上限 / 排队任务">
              <span>并发</span>
              <small>正在执行 / 并发 / 排队</small>
            </TableHead>
            <TableHead className="platformLimitNumberHead">TPM</TableHead>
            <TableHead className="platformLimitNumberHead">RPM</TableHead>
          </TableRow>
          {props.statuses.map((status) => {
            const platform = props.platformMap.get(status.platformId);
            return (
              <TableRow key={status.platformModelId}>
                <TableCell>
                  <span className="platformTableName">
                    <strong>{status.displayName || status.modelAlias || status.modelName}</strong>
                    <small>{status.providerModelName || status.modelName}</small>
                  </span>
                </TableCell>
                <TableCell>
                  <span className="platformTableName">
                    <strong>{platform ? platformDisplayName(platform) : status.platformName}</strong>
                    <small>{status.provider}</small>
                  </span>
                </TableCell>
                <TableCell className="platformLimitStatusCell">
                  {modelRuntimeStatusCell(
                    status,
                    platform,
                    props.now,
                    props.onRestoreRuntimeModel,
                    props.restoreSavingId === status.platformModelId,
                  )}
                </TableCell>
                <TableCell className="platformLimitNumberCell">{platformPriorityCell(status, platform, props.onAdjustPriority)}</TableCell>
                <TableCell className="platformLimitNumberCell">
                  <span className="rateLoadCell" data-overloaded={status.loadRatio > 0.8 ? 'true' : undefined}>
                    <strong>{formatPercent(status.loadRatio)}</strong>
                    <span className="rateLoadTrack"><i style={{ width: `${Math.min(status.loadRatio * 100, 100)}%` }} /></span>
                  </span>
                </TableCell>
                <TableCell className="platformLimitNumberCell">{concurrencyMetricCell(status)}</TableCell>
                <TableCell className="platformLimitNumberCell">{metricCell(status.tpm, true)}</TableCell>
                <TableCell className="platformLimitNumberCell">{metricCell(status.rpm)}</TableCell>
              </TableRow>
            );
          })}
        </Table>
      </div>
    </section>
  );
}

function platformDisplayName(platform: IntegrationPlatform) {
  return platform.internalName?.trim() || platform.name;
}

function platformPriorityCell(
  status: ModelRateLimitStatus,
  platform: IntegrationPlatform | undefined,
  onAdjustPriority: (status: ModelRateLimitStatus, platform: IntegrationPlatform | undefined) => void,
) {
  const records = status.recentPriorityDemotions ?? [];
  const content = <PriorityDemotionPopover records={records} />;
  return (
    <span className="platformPriorityCell">
      <AntPopover
        align={{ offset: [0, 8] }}
        content={content}
        overlayClassName="priorityDemotionAntPopover"
        placement="bottomLeft"
        trigger={['hover', 'focus']}
      >
        <button className="priorityDemotionTrigger" type="button" aria-label={priorityDemotionAriaLabel(status, platform)}>
          <span className="rateMetricCell">
            <strong>{formatPriority(platformEffectivePriority(status, platform))}</strong>
            <small>{platformPrioritySubtitle(status, platform, records.length)}</small>
          </span>
        </button>
      </AntPopover>
      <Button className="priorityAdjustButton" type="button" variant="outline" size="xs" onClick={() => onAdjustPriority(status, platform)}>
        <SlidersHorizontal size={13} />
        调整
      </Button>
    </span>
  );
}

function PlatformPriorityDialog(props: {
  dialog: PriorityDialogState | null;
  error: string;
  saving: boolean;
  onClose: () => void;
  onReset: () => void;
  onSubmit: (event: FormEvent<HTMLFormElement>) => void;
  onValueChange: (value: string) => void;
}) {
  const dialog = props.dialog;
  const platform = dialog?.platform;
  const status = dialog?.status;
  return (
    <FormDialog
      bodyClassName="platformPriorityDialogBody"
      className="platformPriorityDialog"
      closeLabel="关闭"
      eyebrow="Runtime Priority"
      footer={(
        <>
          <Button type="button" variant="outline" disabled={props.saving} onClick={props.onClose}>
            取消
          </Button>
          <Button type="button" variant="secondary" disabled={props.saving || !dialog} onClick={props.onReset}>
            <RotateCcw size={15} />
            重置为静态优先级
          </Button>
          <Button type="submit" disabled={props.saving || !dialog}>
            <CheckCircle2 size={15} />
            保存动态优先级
          </Button>
        </>
      )}
      open={Boolean(dialog)}
      title="调整平台动态优先级"
      onClose={props.onClose}
      onSubmit={props.onSubmit}
    >
      <div className="platformPriorityDialogSummary">
        <span>
          <strong>{platform ? platformDisplayName(platform) : status?.platformName}</strong>
          <small>{status?.provider}</small>
        </span>
        <span>
          <strong>{formatPriority(platformEffectivePriority(status, platform))}</strong>
          <small>当前生效</small>
        </span>
      </div>
      <div className="platformPriorityDialogMetrics">
        <span>静态 {formatPriority(platformStaticPriority(status, platform))}</span>
        <span>动态 {formatPriority(platformDynamicPriority(status, platform))}</span>
      </div>
      <Label>
        动态优先级
        <Input
          value={dialog?.value ?? ''}
          inputMode="numeric"
          min={0}
          placeholder="例如 1511"
          onChange={(event) => props.onValueChange(event.target.value)}
        />
      </Label>
      {props.error && <p className="formMessage error">{props.error}</p>}
    </FormDialog>
  );
}

function PriorityDemotionPopover(props: { records: PriorityDemotionRecord[] }) {
  if (!props.records.length) {
    return (
      <span className="priorityDemotionPopover" role="tooltip">
        <span className="priorityDemotionEmpty">暂无优先级降级记录</span>
      </span>
    );
  }
  return (
    <span className="priorityDemotionPopover" role="tooltip">
      <span className="priorityDemotionHeader">
        <History size={14} />
        <strong>最近 10 条优先级降级</strong>
      </span>
      {props.records.map((record) => (
        <span key={record.id} className="priorityDemotionItem">
          <span className="priorityDemotionItemHeader">
            <strong>{priorityDemotionReasonText(record)}</strong>
            {priorityIsSet(record.dynamicPriority) ? <Badge variant="secondary">队尾 {formatPriority(record.dynamicPriority)}</Badge> : null}
          </span>
          <small>{priorityDemotionMetaText(record)}</small>
          {record.errorMessage && <span className="priorityDemotionError">{record.errorMessage}</span>}
        </span>
      ))}
    </span>
  );
}

function PlatformDisabledReasonPopover(props: { record?: PlatformPolicyEvent }) {
  const record = props.record;
  if (!record) {
    return (
      <span className="priorityDemotionPopover" role="tooltip">
        <span className="priorityDemotionEmpty">暂无禁用原因记录</span>
      </span>
    );
  }
  return (
    <span className="priorityDemotionPopover" role="tooltip">
      <span className="priorityDemotionHeader">
        <History size={14} />
        <strong>禁用原因</strong>
      </span>
      <span className="priorityDemotionItem">
        <span className="priorityDemotionItemHeader">
          <strong>{platformPolicyEventReasonText(record)}</strong>
        </span>
        <small>{platformPolicyEventMetaText(record)}</small>
        {record.errorMessage && <span className="priorityDemotionError">{record.errorMessage}</span>}
      </span>
    </span>
  );
}

function platformPrioritySubtitle(status: ModelRateLimitStatus, platform: IntegrationPlatform | undefined, demotionCount: number) {
  const staticPriority = platformStaticPriority(status, platform);
  const dynamicPriority = platformDynamicPriority(status, platform);
  const base = priorityIsSet(dynamicPriority) ? `静态 ${formatPriority(staticPriority)} · 动态 ${formatPriority(dynamicPriority)}` : `静态 ${formatPriority(staticPriority)}`;
  return demotionCount ? `${base} · 降级 ${demotionCount}` : base;
}

function priorityDemotionAriaLabel(status: ModelRateLimitStatus, platform: IntegrationPlatform | undefined) {
  const count = status.recentPriorityDemotions?.length ?? 0;
  return `平台优先级 ${formatPriority(platformEffectivePriority(status, platform))}，最近 ${count} 条优先级降级记录`;
}

function priorityDemotionReasonText(record: PriorityDemotionRecord) {
  const category = record.category ? `错误分类 ${record.category}` : '';
  const code = record.errorCode ? `错误 ${record.errorCode}` : '';
  const statusCode = record.statusCode ? `状态码 ${record.statusCode}` : '';
  return [priorityDemotionReasonLabel(record.reason), statusCode, code, category].filter(Boolean).join(' · ');
}

function priorityDemotionMetaText(record: PriorityDemotionRecord) {
  const policy = priorityDemotionPolicyText(record);
  const values = [
    formatDateTime(record.createdAt),
    shortId(record.taskId) ? `任务 ${shortId(record.taskId)}` : '',
    policy,
  ].filter(Boolean);
  return values.join(' · ') || '-';
}

function priorityDemotionPolicyText(record: PriorityDemotionRecord) {
  const policyPath = [record.policySource || record.policy, record.policyRule].filter(Boolean).join('.');
  if (!policyPath) return '';
  return record.matchedValue ? `策略 ${policyPath}=${record.matchedValue}` : `策略 ${policyPath}`;
}

function priorityDemotionReasonLabel(reason: string | undefined) {
  const labels: Record<string, string> = {
    priority_demote_policy: '命中优先级降级规则',
    failover_allow_policy: '命中跨平台切换规则',
    auto_disable_policy: '命中自动禁用规则',
    client_retryable: '客户端错误可重试',
    hard_stop_policy: '命中硬拒绝规则',
    runner_policy_disabled: '全局调度策略停用',
  };
  return reason ? labels[reason] ?? reason : '优先级降级';
}

function platformPolicyEventReasonText(record: PlatformPolicyEvent) {
  const category = record.category ? `错误分类 ${record.category}` : '';
  const code = record.errorCode ? `错误 ${record.errorCode}` : '';
  const statusCode = record.statusCode ? `状态码 ${record.statusCode}` : '';
  return [platformPolicyEventReasonLabel(record), statusCode, code, category].filter(Boolean).join(' · ');
}

function platformPolicyEventMetaText(record: PlatformPolicyEvent) {
  const policyPath = [record.policySource || record.policy, record.policyRule].filter(Boolean).join('.');
  const policy = policyPath ? (record.matchedValue ? `策略 ${policyPath}=${record.matchedValue}` : `策略 ${policyPath}`) : '';
  return [
    formatDateTime(record.createdAt),
    shortId(record.taskId) ? `任务 ${shortId(record.taskId)}` : '',
    policy,
  ].filter(Boolean).join(' · ') || '-';
}

function platformPolicyEventReasonLabel(record: PlatformPolicyEvent) {
  if (record.reason) {
    return priorityDemotionReasonLabel(record.reason);
  }
  if (record.eventType === 'task.policy.auto_disabled') {
    return '命中自动禁用规则';
  }
  if (record.eventType === 'task.policy.failover_disabled') {
    return '跨平台切换时禁用';
  }
  return '平台已禁用';
}

function metricCell(metric: ModelRateLimitStatus['rpm'], includeReserved = false) {
  if (!metric.limited) return <span className="rateMetricCell"><strong>{formatLimit(metric.currentValue)} / 不限</strong><small>{includeReserved ? reservedMetricText(metric) : '未配置上限'}</small></span>;
  return (
    <span className="rateMetricCell">
      <strong>{formatLimit(metric.currentValue)} / {formatLimit(metric.limitValue)}</strong>
      <small>{includeReserved ? reservedMetricText(metric) : `窗口 ${formatPercent(metric.ratio)}`}</small>
    </span>
  );
}

function concurrencyMetricCell(status: ModelRateLimitStatus) {
  const queuedTasks = status.queuedTasks ?? 0;
  const limitText = status.concurrent.limited ? formatLimit(status.concurrent.limitValue) : '不限';
  return (
    <span className="rateMetricCell" title="正在执行 / 并发上限 / 排队任务">
      <strong>{formatLimit(status.concurrent.currentValue)} / {limitText} / {formatLimit(queuedTasks)}</strong>
    </span>
  );
}

function reservedMetricText(metric: ModelRateLimitStatus['rpm']) {
  return `已结算 ${formatLimit(metric.usedValue)} + 预占 ${formatLimit(metric.reservedValue)}`;
}

function formatTimeOfDay(timestamp: number | null) {
  if (!timestamp) return '暂无';
  const date = new Date(timestamp);
  const pad = (value: number) => String(value).padStart(2, '0');
  return `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
}

function formatDateTime(value: string | undefined) {
  if (!value) return '';
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value;
  const pad = (item: number) => String(item).padStart(2, '0');
  return `${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
}

function shortId(value: string | undefined) {
  if (!value) return '';
  return value.length > 8 ? value.slice(0, 8) : value;
}

function modelRuntimeStatusCell(
  status: ModelRateLimitStatus,
  platform: IntegrationPlatform | undefined,
  now: number,
  onRestore: (platformModelId: string) => Promise<void>,
  restoring: boolean,
) {
  const modelCooldownMs = cooldownRemainingMs(status.modelCooldownUntil, now);
  const platformCooldownMs = cooldownRemainingMs(status.platformCooldownUntil, now);
  const platformStatus = platform?.status || status.platformStatus || 'enabled';
  const restoreButton = runtimeRestoreButton(status, platformStatus, modelCooldownMs, platformCooldownMs, onRestore, restoring);
  if (modelCooldownMs > 0) {
    return (
      <span className="platformRuntimeStatusCell">
        <span className="platformTableName">
          <strong><Badge variant="warning">模型冷却中</Badge></strong>
          <small>剩余 {formatCooldownRemaining(modelCooldownMs)}</small>
        </span>
        {restoreButton}
      </span>
    );
  }
  if (platformStatus !== 'enabled') {
    const badge = <Badge variant="warning">已禁用</Badge>;
    return (
      <span className="platformRuntimeStatusCell">
        <AntPopover
          align={{ offset: [0, 8] }}
          content={<PlatformDisabledReasonPopover record={status.platformDisabledReason} />}
          overlayClassName="priorityDemotionAntPopover"
          placement="bottomLeft"
          trigger={['hover', 'focus']}
        >
          <span className="platformTableName" tabIndex={0}>
            <strong>{badge}</strong>
          </span>
        </AntPopover>
        {restoreButton}
      </span>
    );
  }
  if (!status.enabled) {
    return (
      <span className="platformRuntimeStatusCell">
        <span className="platformTableName">
          <strong><Badge variant="secondary">已停用</Badge></strong>
          <small>不参与路由</small>
        </span>
        {restoreButton}
      </span>
    );
  }
  if (platformCooldownMs > 0) {
    return (
      <span className="platformRuntimeStatusCell">
        <span className="platformTableName">
          <strong><Badge variant="warning">平台冷却中</Badge></strong>
          <small>剩余 {formatCooldownRemaining(platformCooldownMs)}</small>
        </span>
        {restoreButton}
      </span>
    );
  }
  return (
    <span className="platformRuntimeStatusCell">
      <span className="platformTableName">
        <strong><Badge variant="success">可用</Badge></strong>
        <small>参与路由</small>
      </span>
    </span>
  );
}

function runtimeRestoreButton(
  status: ModelRateLimitStatus,
  platformStatus: string,
  modelCooldownMs: number,
  platformCooldownMs: number,
  onRestore: (platformModelId: string) => Promise<void>,
  restoring: boolean,
) {
  const canRestore = modelCooldownMs > 0 || platformCooldownMs > 0 || platformStatus !== 'enabled' || !status.enabled;
  if (!canRestore) return null;
  return (
    <Button
      className="platformRestoreButton"
      type="button"
      variant="outline"
      size="xs"
      disabled={restoring}
      onClick={() => void onRestore(status.platformModelId)}
    >
      <RotateCcw size={13} />
      {restoring ? '恢复中' : '恢复'}
    </Button>
  );
}

function cooldownRemainingMs(cooldownUntil: string | undefined, now: number) {
  if (!cooldownUntil) return 0;
  const until = Date.parse(cooldownUntil);
  if (!Number.isFinite(until)) return 0;
  return Math.max(until - now, 0);
}

function formatCooldownRemaining(milliseconds: number) {
  const minutes = milliseconds / 60000;
  if (minutes >= 1) return `${trimNumber(Math.ceil(minutes * 10) / 10)} 分钟`;
  const seconds = Math.ceil(milliseconds / 1000);
  return `${Math.max(seconds, 1)} 秒`;
}

function formatPercent(value: number) {
  if (!Number.isFinite(value) || value <= 0) return '0%';
  return `${trimNumber(value * 100)}%`;
}

function formatLimit(value: number) {
  if (Math.abs(value) >= 10000) return `${trimNumber(value / 10000)}万`;
  if (Math.abs(value) >= 1000) return `${trimNumber(value / 1000)}k`;
  return trimNumber(value);
}

function platformEffectivePriority(status: ModelRateLimitStatus | undefined, platform: IntegrationPlatform | undefined) {
  return firstPriority(
    status?.platformEffectivePriority,
    platform?.effectivePriority,
    status?.platformDynamicPriority,
    platform?.dynamicPriority,
    status?.platformPriority,
    platform?.priority,
  );
}

function platformStaticPriority(status: ModelRateLimitStatus | undefined, platform: IntegrationPlatform | undefined) {
  return firstPriority(status?.platformPriority, platform?.priority);
}

function platformDynamicPriority(status: ModelRateLimitStatus | undefined, platform: IntegrationPlatform | undefined) {
  return firstPriority(
    status?.platformDynamicPriority,
    platform?.dynamicPriority,
    status?.platformEffectivePriority,
    platform?.effectivePriority,
    status?.platformPriority,
    platform?.priority,
  );
}

function firstPriority(...values: Array<number | undefined>) {
  return values.find(priorityIsSet);
}

function priorityIsSet(value: number | undefined): value is number {
  return typeof value === 'number' && Number.isFinite(value);
}

function formatPriority(value: number | undefined) {
  if (!Number.isFinite(value)) return '-';
  return String(Math.trunc(value ?? 0));
}

function parsePriorityInput(value: string) {
  const trimmed = value.trim();
  if (!/^\d+$/.test(trimmed)) return null;
  const parsed = Number(trimmed);
  if (!Number.isSafeInteger(parsed)) return null;
  return parsed;
}

function trimNumber(value: number) {
  return Number.isInteger(value) ? String(value) : value.toFixed(2).replace(/\.?0+$/, '');
}
