import { useEffect, useCallback, useMemo } from 'react';
import { useInputBarStore } from '../store/inputBar';
import { useGenerationStore } from '../store/generation';
import { useAuthStore } from '../store/auth';
import { Dropdown } from './Dropdown';
import { showToast } from './Toast';
import { parseAssetMentions } from '../lib/assetMentions';
import type { CreationMode, AspectRatio, Duration, Resolution, GenerationType, ModelOption } from '../types';
import styles from './Toolbar.module.css';

const VideoIcon = () => (
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
    <polygon points="23 7 16 12 23 17 23 7" />
    <rect x="1" y="5" width="15" height="14" rx="2" ry="2" />
  </svg>
);

const ImageIcon = () => (
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
    <rect x="3" y="3" width="18" height="18" rx="2" />
    <circle cx="8.5" cy="8.5" r="1.5" />
    <polyline points="21 15 16 10 5 21" />
  </svg>
);

const DiamondIcon = () => (
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
    <path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5" />
  </svg>
);

const LightningIcon = () => (
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
    <path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z" />
  </svg>
);

const StarIcon = () => (
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
    <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
  </svg>
);

const SwapIcon = () => (
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round">
    <path d="M7 12h10M17 12l-3-3M17 12l-3 3M7 12l3-3M7 12l3 3" />
  </svg>
);

const MonitorIcon = () => (
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
    <rect x="2" y="3" width="20" height="14" rx="2" />
    <line x1="8" y1="21" x2="16" y2="21" />
    <line x1="12" y1="17" x2="12" y2="21" />
  </svg>
);

const ClockIcon = () => (
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
    <circle cx="12" cy="12" r="10" />
    <polyline points="12 6 12 12 16 14" />
  </svg>
);

const ChevronDown = () => (
  <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
    <polyline points="6 9 12 15 18 9" />
  </svg>
);

const generationTypeItems = [
  { label: '视频生成', value: 'video' as GenerationType, icon: <VideoIcon /> },
];

// NOTE: modelItems 在组件内部按 resolution 动态构建（1080P 下 Fast 置灰）

const modeItems = [
  { label: '全能参考', value: 'universal' as CreationMode, icon: <StarIcon /> },
  { label: '首尾帧', value: 'keyframe' as CreationMode, icon: <SwapIcon /> },
];

const ratioItems = [
  { label: '21:9', value: '21:9' as AspectRatio },
  { label: '16:9', value: '16:9' as AspectRatio },
  { label: '4:3', value: '4:3' as AspectRatio },
  { label: '1:1', value: '1:1' as AspectRatio },
  { label: '3:4', value: '3:4' as AspectRatio },
  { label: '9:16', value: '9:16' as AspectRatio },
];

const keyframeRatioItems = [
  ...ratioItems,
];

const durationItems = Array.from({ length: 12 }, (_, i) => {
  const v = i + 4;
  return { label: `${v}s`, value: String(v) };
});

// 对照 billing.py::RESOLUTION_MAP — 前端预估与后端计费保持一致
const RESOLUTION_PIXELS: Record<Resolution, Record<string, [number, number]>> = {
  '480p': {
    '16:9': [864, 496], '9:16': [496, 864], '4:3': [752, 560],
    '1:1': [640, 640], '3:4': [560, 752], '21:9': [992, 432],
  },
  '720p': {
    '16:9': [1280, 720], '9:16': [720, 1280], '4:3': [1112, 834],
    '1:1': [960, 960], '3:4': [834, 1112], '21:9': [1470, 630],
  },
  '1080p': {
    '16:9': [1920, 1080], '9:16': [1080, 1920], '4:3': [1664, 1248],
    '1:1': [1440, 1440], '3:4': [1248, 1664], '21:9': [2206, 946],
  },
};

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

export function Toolbar() {
  const generationType = useInputBarStore((s) => s.generationType);
  const setGenerationType = useInputBarStore((s) => s.setGenerationType);
  const model = useInputBarStore((s) => s.model);
  const setModel = useInputBarStore((s) => s.setModel);
  const mode = useInputBarStore((s) => s.mode);
  const switchMode = useInputBarStore((s) => s.switchMode);
  const aspectRatio = useInputBarStore((s) => s.aspectRatio);
  const setAspectRatio = useInputBarStore((s) => s.setAspectRatio);
  const duration = useInputBarStore((s) => s.duration);
  const setDuration = useInputBarStore((s) => s.setDuration);
  const resolution = useInputBarStore((s) => s.resolution);
  const setResolution = useInputBarStore((s) => s.setResolution);
  const isSubmittable = useInputBarStore((s) => s.canSubmit());
  const triggerInsertAt = useInputBarStore((s) => s.triggerInsertAt);

  const isKeyframe = mode === 'keyframe';
  const references = useInputBarStore((s) => s.references);
  const editorHtml = useInputBarStore((s) => s.editorHtml);
  const team = useAuthStore((s) => s.team);

  const addTask = useGenerationStore((s) => s.addTask);

  const estimatedTokens = useMemo(() => {
    // 官方公式：`(输入视频时长 + 输出视频时长) × 宽 × 高 × 24fps / 1024`
    // 前后端必须一致（和 backend/utils/billing.py::estimate_tokens 对齐）。
    // 输入视频时长 = 直接上传的视频 references.duration + 素材库 @ 视频的 duration
    // resolution / aspectRatio 都是严格类型枚举，不做 || 兜底 — bug 直接暴露。
    const [w, h] = RESOLUTION_PIXELS[resolution][aspectRatio];
    const refVideoDur = references
      .filter((r) => r.type === 'video' && typeof r.duration === 'number')
      .reduce((sum, r) => sum + (r.duration || 0), 0);
    const mentionVideoDur = parseAssetMentions(editorHtml).durations.video;
    const totalDuration = duration + refVideoDur + mentionVideoDur;
    return Math.round((w * h * 24 * totalDuration) / 1024);
  }, [aspectRatio, duration, resolution, references, editorHtml]);

  // 分辨率 Dropdown：Fast 模式下 1080P 置灰
  const resolutionItems = useMemo(() => [
    { label: '480P', value: '480p' as Resolution },
    { label: '720P', value: '720p' as Resolution },
    {
      label: model === 'seedance_2.0_fast' ? '1080P（Fast 不支持）' : '1080P',
      value: '1080p' as Resolution,
      disabled: model === 'seedance_2.0_fast',
    },
  ], [model]);

  // 模型 Dropdown：当前 1080P 时，Fast 置灰（1080P 仅 AirDrama 支持）
  const modelItems = useMemo(() => [
    { label: 'AirDrama', value: 'seedance_2.0', icon: <DiamondIcon /> },
    {
      label: resolution === '1080p' ? 'AirDrama Fast（不支持 1080P）' : 'AirDrama Fast',
      value: 'seedance_2.0_fast',
      icon: <LightningIcon />,
      disabled: resolution === '1080p',
    },
  ], [resolution]);

  const estimatedCost = useMemo(() => {
    const hasVideoRef = references.some((r) => r.type === 'video');
    let price = team?.token_price || 0;
    if (model === 'seedance_2.0_fast') {
      // Fast 不支持 1080p，单价不分分辨率
      price = hasVideoRef ? (team?.token_price_fast_video || 0) : (team?.token_price_fast || 0);
    } else if (resolution === '1080p') {
      price = hasVideoRef ? (team?.token_price_1080p_video || 0) : (team?.token_price_1080p || 0);
    } else {
      price = hasVideoRef ? (team?.token_price_video || 0) : (team?.token_price || 0);
    }
    return (estimatedTokens * price / 1000000).toFixed(2);
  }, [estimatedTokens, model, resolution, references, team]);

  const handleSend = useCallback(() => {
    if (!isSubmittable) {
      const s = useInputBarStore.getState();
      if (s.mode === 'universal' && s.references.some((r) => r.type === 'audio')
        && !s.references.some((r) => r.type === 'image' || r.type === 'video')) {
        showToast('音频不能作为唯一的参考素材，请同时添加图片或视频');
      }
      return;
    }
    addTask();
  }, [isSubmittable, addTask]);

  const handleInsertAt = useCallback(() => {
    triggerInsertAt();
  }, [triggerInsertAt]);

  // Keyboard shortcut: Ctrl/Cmd + Enter
  useEffect(() => {
    const handler = (e: KeyboardEvent) => {
      if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
        handleSend();
      }
    };
    document.addEventListener('keydown', handler);
    return () => document.removeEventListener('keydown', handler);
  }, [handleSend]);

  return (
    <div className={styles.toolbar}>
      {/* Generation type — fixed to video */}
      <button className={`${styles.btn} ${styles.primary}`}>
        <VideoIcon />
        <span className={styles.label}>视频生成</span>
      </button>

      {/* Model selector */}
      <Dropdown
        items={modelItems}
        value={model}
        onSelect={(v) => setModel(v as ModelOption)}
        minWidth={160}
        trigger={
          <button className={styles.btn}>
            {model === 'seedance_2.0_fast' ? <LightningIcon /> : <DiamondIcon />}
            <span className={styles.label}>{model === 'seedance_2.0_fast' ? 'AirDrama Fast' : 'AirDrama'}</span>
            <ChevronDown />
          </button>
        }
      />

      {/* Mode selector */}
      <Dropdown
        items={modeItems}
        value={mode}
        onSelect={(v) => switchMode(v as CreationMode)}
        minWidth={150}
        trigger={
          <button className={styles.btn}>
            {isKeyframe ? <SwapIcon /> : <StarIcon />}
            <span className={styles.label}>{modeLabels[mode]}</span>
            <ChevronDown />
          </button>
        }
      />

      {/* Aspect ratio */}
      <Dropdown
        items={isKeyframe ? keyframeRatioItems : ratioItems}
        value={aspectRatio}
        onSelect={(v) => setAspectRatio(v as AspectRatio)}
        minWidth={100}
        trigger={
          <button className={styles.btn}>
            <MonitorIcon />
            <span className={styles.label}>{aspectRatio}</span>
          </button>
        }
      />

      {/* Resolution */}
      <Dropdown
        items={resolutionItems}
        value={resolution}
        onSelect={(v) => setResolution(v as Resolution)}
        minWidth={100}
        trigger={
          <button className={styles.btn}>
            <span className={styles.label}>{resolution.toUpperCase()}</span>
          </button>
        }
      />

      {/* Duration */}
      <Dropdown
        items={durationItems}
        value={String(duration)}
        onSelect={(v) => setDuration(Number(v) as Duration)}
        minWidth={100}
        trigger={
          <button className={styles.btn}>
            <ClockIcon />
            <span className={styles.label}>{duration}s</span>
          </button>
        }
      />

      {/* @ button - universal mode only */}
      {!isKeyframe && (
        <button className={styles.btn} onClick={handleInsertAt}>
          <span style={{ fontSize: 15, fontWeight: 600 }}>@</span>
        </button>
      )}

      {/* Spacer — push right group to the end */}
      <div className={styles.spacer} />

      {/* 全部清空 + 预估消耗：仅有内容时显示 */}
      {isSubmittable && (
      <span
        onClick={() => useInputBarStore.getState().reset()}
        style={{ fontSize: 12, color: 'var(--color-text-secondary)', whiteSpace: 'nowrap', userSelect: 'none', cursor: 'pointer', transition: 'filter 0.15s', marginRight: 20, lineHeight: 1 }}
        onMouseEnter={(e) => { (e.currentTarget as HTMLElement).style.filter = 'brightness(1.4)'; }}
        onMouseLeave={(e) => { (e.currentTarget as HTMLElement).style.filter = ''; }}
      >
        &#x27F2; 全部清空
      </span>
      )}

      {/* Estimated cost */}
      {isSubmittable && (team?.token_price || 0) > 0 && (
        <span
          style={{ fontSize: 12, color: 'var(--color-text-secondary)', whiteSpace: 'nowrap', userSelect: 'none', marginRight: 16, lineHeight: 1 }}
          title={`预估公式: (宽 × 高 × 24fps × 时长) / 1024 = tokens, tokens × 单价 / 1000000 = 费用\n⚠️ 仅为预估值，实际费用以火山 API 返回的 token 数为准`}
        >
          预估消耗：{estimatedTokens.toLocaleString()} tokens / ¥{estimatedCost}
        </span>
      )}

      {/* Send button */}
      <button
        className={`${styles.sendBtn} ${isSubmittable ? styles.sendEnabled : styles.sendDisabled}`}
        onClick={handleSend}
      >
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="var(--color-on-primary)" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
          <line x1="12" y1="19" x2="12" y2="5" />
          <polyline points="5 12 12 5 19 12" />
        </svg>
      </button>

    </div>
  );
}
