import { useState } from 'react';
import type { AdminRecord } from '../types';
import { ReferenceList } from './ReferenceList';
import { rewriteTosUrl } from '../lib/api';
import { showToast } from './Toast';

const STATUS_MAP: Record<string, { label: string; color: string; bg: string }> = {
  completed: { label: '已完成', color: 'var(--color-success)', bg: 'var(--color-success-bg)' },
  failed: { label: '失败', color: 'var(--color-danger)', bg: 'var(--color-danger-bg)' },
  processing: { label: '生成中', color: 'var(--color-info)', bg: 'var(--color-info-bg)' },
  queued: { label: '排队中', color: 'var(--color-info)', bg: 'var(--color-info-bg)' },
};

const MODE_MAP: Record<string, string> = { universal: '全能参考', keyframe: '首尾帧' };

interface Props {
  record: AdminRecord;
  onClose: () => void;
  showTeam?: boolean;
  showCost?: boolean;
}

export function RecordDetailModal({ record: r, onClose, showTeam, showCost }: Props) {
  const st = STATUS_MAP[r.status] || STATUS_MAP.processing;
  const [debugOpen, setDebugOpen] = useState(false);
  // 仅当转换后的 prompt 与原文不同(即 prompt 里有 @ 被转为「图片N」)才单独显示一栏
  const hasConvertedPrompt = !!(r.api_prompt && r.api_prompt !== r.prompt);
  const handleCopyTaskId = () => {
    if (!r.ark_task_id) return;
    navigator.clipboard.writeText(r.ark_task_id).then(() => showToast('已复制'));
  };

  const elapsed = (() => {
    if (!r.completed_at) return '-';
    const ms = new Date(r.completed_at).getTime() - new Date(r.created_at).getTime();
    if (ms < 0) return '-';
    const sec = Math.round(ms / 1000);
    if (sec < 60) return `${sec}秒`;
    const min = Math.floor(sec / 60);
    const s = sec % 60;
    return `${min}分${s > 0 ? s + '秒' : ''}`;
  })();

  const refs = r.reference_urls || [];

  return (
    <>
      <div style={overlay} onClick={onClose}>
        <div style={modal} onClick={(e) => e.stopPropagation()}>
          {/* Header */}
          <div style={header}>
            <span style={{ fontSize: 16, fontWeight: 600, color: 'var(--color-text-light)' }}>任务详情</span>
            <button style={closeBtn} onClick={onClose}>✕</button>
          </div>

          {/* Body — 左:视频+参考素材 / 右:信息+提示词 */}
          <div style={body}>
            {/* ── 左侧:视频 + 参考素材 ── */}
            <div style={mediaPanel}>
              <MediaArea record={r} />
              {refs.length > 0 && (
                <>
                  <div style={sectionTitle}>参考素材({refs.length})</div>
                  <div style={refScrollBox}>
                    <ReferenceList references={refs} />
                  </div>
                </>
              )}
            </div>

            {/* ── 右侧:信息 + 提示词 ── */}
            <div style={infoPanel}>
              {/* Status */}
              <div style={{ marginBottom: 16 }}>
                <span style={{ ...statusBadge, color: st.color, background: st.bg }}>{st.label}</span>
              </div>

              {/* Error */}
              {r.status === 'failed' && r.error_message && (
                <div style={errorBox}>
                  <div style={{ fontWeight: 500, marginBottom: 4 }}>失败原因</div>
                  <div>{r.error_message}</div>
                  {r.raw_error && r.raw_error !== r.error_message && (
                    <div style={{ marginTop: 8, fontSize: 11, color: 'var(--color-text-tertiary)', fontFamily: 'monospace', wordBreak: 'break-all' }}>
                      原始错误:{r.raw_error}
                    </div>
                  )}
                </div>
              )}

              {/* Info Grid */}
              <div style={{ ...sectionTitle, marginTop: 0 }}>基本信息</div>
              <div style={infoGrid}>
                {r.ark_task_id && <InfoItem label="任务ID" value={r.ark_task_id} />}
                {r.username && <InfoItem label="用户" value={r.username} />}
                {showTeam && r.team_name && <InfoItem label="团队" value={r.team_name} />}
                <InfoItem label="提交时间" value={new Date(r.created_at).toLocaleString('zh-CN')} />
                <InfoItem label="耗时" value={elapsed} />
                <InfoItem label="模型" value={r.model === 'seedance_2.0_fast' ? 'AirDrama Fast' : 'AirDrama'} />
                <InfoItem label="模式" value={MODE_MAP[r.mode] || r.mode} />
                <InfoItem label="比例" value={r.aspect_ratio || '-'} />
                <InfoItem label="分辨率" value={r.resolution ? r.resolution.toUpperCase() : '-'} />
                <InfoItem label="时长" value={r.duration != null ? `${r.duration}秒` : '-'} />
                <InfoItem label="Tokens" value={(r.tokens_consumed || 0).toLocaleString()} />
                {showCost && <InfoItem label="费用" value={`¥${(r.cost_amount || 0).toFixed(2)}`} />}
                {r.seed != null && r.seed !== -1 && <InfoItem label="种子值" value={String(r.seed)} />}
              </div>

              {/* Prompt */}
              <div style={sectionTitle}>提示词</div>
              <div style={promptBox}>{r.prompt || '(无提示词)'}</div>

              {/* 调试信息(开发/客服参考)— 默认收起 */}
              <div style={debugSection}>
                <button
                  style={debugToggle}
                  onClick={() => setDebugOpen(!debugOpen)}
                  type="button"
                >
                  <span style={{ display: 'inline-block', width: 12, color: 'var(--color-text-tertiary)' }}>
                    {debugOpen ? '▾' : '▸'}
                  </span>
                  调试信息(开发/客服参考)
                </button>
                {debugOpen && (
                  <div style={debugContent}>
                    {hasConvertedPrompt && (
                      <>
                        <div style={debugLabel}>实际发给火山(@素材名被自动转换为「图片N/视频N/音频N」):</div>
                        <div style={debugCodeBox}>{r.api_prompt}</div>
                      </>
                    )}
                    {r.ark_task_id && (
                      <div style={debugRow}>
                        <span style={debugLabel}>火山 Task ID:</span>
                        <span style={debugMono}>{r.ark_task_id}</span>
                        <button style={debugCopyBtn} onClick={handleCopyTaskId} type="button">复制</button>
                      </div>
                    )}
                    {r.status === 'failed' && r.raw_error && (
                      <>
                        <div style={debugLabel}>原始错误:</div>
                        <div style={debugCodeBox}>{r.raw_error}</div>
                      </>
                    )}
                    {!hasConvertedPrompt && !r.ark_task_id && (r.status !== 'failed' || !r.raw_error) && (
                      <div style={debugLabel}>(暂无调试信息)</div>
                    )}
                  </div>
                )}
              </div>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}

/**
 * 左侧媒体区 — 根据任务状态决定显示什么:
 * - completed + result_url → 视频播放器(controls,不自动播放)
 * - completed - result_url → "视频已生成"占位
 * - failed → RGB 故障字 "生成失败" + 错误原因摘要 + 斜纹底纹
 * - processing / queued → 旋转 spinner + 文字
 */
function MediaArea({ record: r }: { record: AdminRecord }) {
  return (
    <div style={mediaFrame}>
      {r.status === 'completed' && r.result_url ? (
        <video
          src={rewriteTosUrl(r.result_url)}
          poster={r.thumbnail_url ? rewriteTosUrl(r.thumbnail_url) : undefined}
          style={mediaVideo}
          controls
          preload="metadata"
        />
      ) : r.status === 'completed' ? (
        <div style={mediaPlaceholder}>
          <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
            <polygon points="23 7 16 12 23 17 23 7"/>
            <rect x="1" y="5" width="15" height="14" rx="2"/>
          </svg>
          <span>视频已生成</span>
        </div>
      ) : r.status === 'failed' ? (
        <FailureGlitch errorMessage={r.error_message} />
      ) : (
        <div style={mediaPlaceholder}>
          <svg className="spinner" width="44" height="44" viewBox="0 0 50 50" style={spinnerStyle}>
            <circle cx="25" cy="25" r="20" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeDasharray="80 40" />
          </svg>
          <span>{r.status === 'queued' ? '排队中' : '生成中'}</span>
          {/* 内联 keyframes — 没有 module.css */}
          <style>{`@keyframes shoot-spin { to { transform: rotate(360deg); } }`}</style>
        </div>
      )}
    </div>
  );
}

/**
 * RGB 故障字失败态 — "生成失败"主标题用 cyan/magenta text-shadow 偏移
 * 模拟坏掉的 CRT 信号丢失;副标题等宽字体显示错误摘要。
 */
function FailureGlitch({ errorMessage }: { errorMessage?: string }) {
  const msg = (errorMessage || 'Generation failed').slice(0, 80);
  return (
    <div style={failBg}>
      <div style={failStripe} aria-hidden="true" />
      <div style={glitchTitle}>生成失败</div>
      <div style={glitchSub}>{msg}</div>
      <div style={{ ...failStripe, top: 'auto', bottom: 0 }} aria-hidden="true" />
    </div>
  );
}

function InfoItem({ label, value }: { label: string; value: string }) {
  return (
    <div style={{ minWidth: 0 }}>
      <div style={{ fontSize: 11, color: 'var(--color-text-tertiary)', marginBottom: 2 }}>{label}</div>
      <div style={{ fontSize: 13, color: 'var(--color-text-light)', wordBreak: 'break-all' }}>{value}</div>
    </div>
  );
}

// ─────────────────────────────────────
// Styles
// ─────────────────────────────────────

const overlay: React.CSSProperties = {
  position: 'fixed', inset: 0, background: 'var(--color-modal-overlay)', display: 'flex',
  alignItems: 'center', justifyContent: 'center', zIndex: 10000,
};

const modal: React.CSSProperties = {
  background: 'var(--color-bg-modal-glass)',
  backdropFilter: 'blur(24px) saturate(180%)',
  WebkitBackdropFilter: 'blur(24px) saturate(180%)',
  border: '1px solid var(--color-border-modal-soft)',
  borderRadius: 12,
  width: 1080,
  maxWidth: '95vw',
  maxHeight: '85vh',
  display: 'flex',
  flexDirection: 'column',
  boxShadow: 'var(--shadow-glass-light)',
};

const header: React.CSSProperties = {
  display: 'flex', justifyContent: 'space-between', alignItems: 'center',
  padding: '16px 24px', borderBottom: '1px solid var(--color-border-modal-soft)',
  flexShrink: 0,
};

const closeBtn: React.CSSProperties = {
  background: 'none', border: 'none', color: 'var(--color-text-tertiary)', fontSize: 16, cursor: 'pointer',
  padding: '4px 8px', borderRadius: 4,
};

const body: React.CSSProperties = {
  flex: 1,
  display: 'flex',
  gap: 24,
  padding: 24,
  overflow: 'hidden', /* infoPanel 内部滚动 */
  minHeight: 0,
};

/* 左侧媒体区 — 固定 480 宽,视频 + 参考素材纵向排列 */
const mediaPanel: React.CSSProperties = {
  width: 480,
  flexShrink: 0,
  display: 'flex',
  flexDirection: 'column',
  alignItems: 'stretch',
  minHeight: 0,    /* 给内部 flex 让出收缩空间 */
};

/* 参考素材区:max-height + 内部滚动,避免视频高度被推下去
   Seedance 最多 9 张 → 80px thumb × 5/行 = 1-2 行,250px 给足兜底 */
const refScrollBox: React.CSSProperties = {
  maxHeight: 250,
  overflowY: 'auto',
  marginTop: 8,
  paddingRight: 4,
};

const mediaFrame: React.CSSProperties = {
  width: '100%',
  aspectRatio: '16 / 9',
  maxHeight: 360,
  background: 'var(--color-bg-video)',
  borderRadius: 12,
  overflow: 'hidden',
  position: 'relative',
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
  border: '1px solid var(--color-border-modal-soft)',
};

const mediaVideo: React.CSSProperties = {
  width: '100%',
  height: '100%',
  objectFit: 'contain',
  display: 'block',
};

const mediaPlaceholder: React.CSSProperties = {
  display: 'flex',
  flexDirection: 'column',
  alignItems: 'center',
  justifyContent: 'center',
  gap: 12,
  color: 'var(--color-text-on-glass-soft)',
  fontSize: 13,
};

const spinnerStyle: React.CSSProperties = {
  color: 'var(--color-primary)',
  animation: 'shoot-spin 1s linear infinite',
};

/* ── 失败态:RGB 故障字 + 斜纹底 ── */
const failBg: React.CSSProperties = {
  position: 'absolute',
  inset: 0,
  display: 'flex',
  flexDirection: 'column',
  alignItems: 'center',
  justifyContent: 'center',
  gap: 18,
  /* 半透明红斜纹 — 仿 CRT 信号丢失 */
  background: `
    repeating-linear-gradient(135deg,
      var(--color-danger-bg-soft) 0,
      var(--color-danger-bg-soft) 14px,
      transparent 14px,
      transparent 22px),
    var(--color-bg-elevated)
  `,
};

const failStripe: React.CSSProperties = {
  position: 'absolute',
  top: 0, left: 0, right: 0,
  height: 6,
  background: `repeating-linear-gradient(90deg,
    var(--color-danger) 0,
    var(--color-danger) 6px,
    var(--color-info) 6px,
    var(--color-info) 8px,
    transparent 8px,
    transparent 14px)`,
  opacity: 0.6,
};

const glitchTitle: React.CSSProperties = {
  fontSize: 44,
  fontWeight: 700,
  letterSpacing: '0.12em',
  color: 'var(--color-danger)',
  fontFamily: "'Space Grotesk', 'JetBrains Mono', ui-monospace, monospace",
  /* RGB 偏移:左 cyan 右 magenta */
  textShadow: `
    -2px 0 var(--color-info),
    2px 0 #ff00aa,
    0 0 30px var(--color-danger-bg)
  `,
  textAlign: 'center',
  userSelect: 'none',
};

const glitchSub: React.CSSProperties = {
  fontSize: 12,
  color: 'var(--color-danger)',
  opacity: 0.85,
  fontFamily: "'JetBrains Mono', ui-monospace, monospace",
  maxWidth: '85%',
  textAlign: 'center',
  wordBreak: 'break-word',
  lineHeight: 1.6,
};

/* 右侧信息区 — 现有内容整体搬过来 */
const infoPanel: React.CSSProperties = {
  flex: 1,
  minWidth: 0,
  overflowY: 'auto',
  paddingRight: 4, /* 给滚动条让位 */
};

const statusBadge: React.CSSProperties = {
  padding: '4px 12px', borderRadius: 6, fontSize: 13, fontWeight: 500,
};

const errorBox: React.CSSProperties = {
  background: 'var(--color-danger-bg-soft)', border: '1px solid var(--color-danger-border)',
  borderRadius: 8, padding: 12, marginBottom: 16, fontSize: 13, color: 'var(--color-danger)',
};

const sectionTitle: React.CSSProperties = {
  fontSize: 12, color: 'var(--color-text-tertiary)', fontWeight: 500, marginBottom: 8, marginTop: 16,
  textTransform: 'uppercase', letterSpacing: 1,
};

const infoGrid: React.CSSProperties = {
  display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '12px 16px',
};

const promptBox: React.CSSProperties = {
  background: 'var(--color-bg-elevated)', borderRadius: 8, padding: 12, fontSize: 13,
  color: 'var(--color-text-monochrome)', lineHeight: 1.6, whiteSpace: 'pre-wrap', wordBreak: 'break-all',
  maxHeight: 150, overflowY: 'auto',
};

/* ── 调试信息折叠区(开发/客服参考)── */
const debugSection: React.CSSProperties = {
  marginTop: 20,
  paddingTop: 12,
  borderTop: '1px dashed var(--color-border-modal-soft)',
};
const debugToggle: React.CSSProperties = {
  display: 'flex', alignItems: 'center', gap: 4,
  background: 'none', border: 'none', cursor: 'pointer',
  color: 'var(--color-text-tertiary)', fontSize: 11, padding: 0,
  fontFamily: 'inherit',
};
const debugContent: React.CSSProperties = {
  marginTop: 10, display: 'flex', flexDirection: 'column', gap: 8,
};
const debugLabel: React.CSSProperties = {
  fontSize: 11, color: 'var(--color-text-tertiary)',
};
const debugCodeBox: React.CSSProperties = {
  background: 'var(--color-bg-elevated)', borderRadius: 6, padding: 10,
  fontSize: 12, lineHeight: 1.5,
  fontFamily: "'JetBrains Mono', ui-monospace, Menlo, Consolas, monospace",
  color: 'var(--color-text-monochrome)',
  whiteSpace: 'pre-wrap', wordBreak: 'break-all',
  maxHeight: 200, overflowY: 'auto',
  border: '1px solid var(--color-border-modal-soft)',
};
const debugRow: React.CSSProperties = {
  display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap',
};
const debugMono: React.CSSProperties = {
  fontFamily: "'JetBrains Mono', ui-monospace, Menlo, Consolas, monospace",
  fontSize: 12, color: 'var(--color-text-on-glass-soft)',
  wordBreak: 'break-all',
};
const debugCopyBtn: React.CSSProperties = {
  background: 'var(--color-bg-elevated)',
  border: '1px solid var(--color-border-modal-soft)',
  borderRadius: 4, padding: '2px 8px',
  fontSize: 11, color: 'var(--color-text-on-glass-soft)',
  cursor: 'pointer',
};
