import { create } from 'zustand';
import type { CreationMode, ModelOption, AspectRatio, Duration, GenerationType, UploadedFile } from '../types';
import { showToast } from '../components/Toast';

let fileCounter = 0;

// API limits per Seedance 2.0 official doc
const MAX_IMAGES = 9;
const MAX_VIDEOS = 3;
const MAX_AUDIO = 3;

interface InputBarState {
  // Generation type
  generationType: GenerationType;
  setGenerationType: (type: GenerationType) => void;

  // Mode
  mode: CreationMode;
  setMode: (mode: CreationMode) => void;

  // Model
  model: ModelOption;
  setModel: (model: ModelOption) => void;

  // Aspect ratio
  aspectRatio: AspectRatio;
  setAspectRatio: (ratio: AspectRatio) => void;
  prevAspectRatio: AspectRatio;

  // Duration
  duration: Duration;
  setDuration: (duration: Duration) => void;
  prevDuration: Duration;

  // Prompt
  prompt: string;
  setPrompt: (prompt: string) => void;

  // Editor HTML (rich content with mention tags)
  editorHtml: string;
  setEditorHtml: (html: string) => void;

  // Universal references
  references: UploadedFile[];
  prevReferences: UploadedFile[];
  addReferences: (files: File[]) => void;
  removeReference: (id: string) => void;
  clearReferences: () => void;

  // Keyframe
  firstFrame: UploadedFile | null;
  lastFrame: UploadedFile | null;
  setFirstFrame: (file: File | null) => void;
  setLastFrame: (file: File | null) => void;

  // Computed
  canSubmit: () => boolean;

  // Search mode (联网搜索)
  searchMode: 'smart' | 'off';
  setSearchMode: (mode: 'smart' | 'off') => void;

  // Asset mentions (for reEdit/regenerate to pass asset data to PromptInput rebuild)
  assetMentions: { groupId: string; label: string; thumbUrl: string }[];

  // @ trigger (for toolbar button to insert @ in contentEditable)
  insertAtTrigger: number;
  triggerInsertAt: () => void;

  // Actions
  switchMode: (mode: CreationMode) => void;
  submit: () => void;
  reset: () => void;
}

export const useInputBarStore = create<InputBarState>((set, get) => ({
  generationType: 'video',
  setGenerationType: (generationType) => set({ generationType }),

  mode: 'universal',
  setMode: (mode) => set({ mode }),

  model: 'seedance_2.0',
  setModel: (model) => set({ model }),

  aspectRatio: '21:9',
  setAspectRatio: (aspectRatio) => set({ aspectRatio, prevAspectRatio: aspectRatio }),
  prevAspectRatio: '21:9',

  duration: 15,
  setDuration: (duration) => {
    const state = get();
    if (state.mode === 'universal') {
      set({ duration, prevDuration: duration });
    } else {
      set({ duration });
    }
  },
  prevDuration: 15,

  prompt: '',
  setPrompt: (prompt) => set({ prompt }),

  editorHtml: '',
  setEditorHtml: (editorHtml) => set({ editorHtml }),

  references: [],
  prevReferences: [],
  addReferences: (files) => {
    const state = get();
    // Count existing references by type
    const counts = { image: 0, video: 0, audio: 0 };
    for (const ref of state.references) counts[ref.type]++;

    const newRefs: UploadedFile[] = [];
    for (const file of files) {
      const type: 'image' | 'video' | 'audio' = file.type.startsWith('video/')
        ? 'video'
        : file.type.startsWith('audio/')
          ? 'audio'
          : 'image';

      const max = type === 'image' ? MAX_IMAGES : type === 'video' ? MAX_VIDEOS : MAX_AUDIO;
      if (counts[type] >= max) {
        const label = type === 'image' ? `最多上传${MAX_IMAGES}张图片` : type === 'video' ? `最多上传${MAX_VIDEOS}个视频` : `最多上传${MAX_AUDIO}个音频`;
        showToast(label);
        continue;
      }

      fileCounter++;
      const labelPrefix = type === 'video' ? '视频' : type === 'audio' ? '音频' : '图片';
      newRefs.push({
        id: `ref_${fileCounter}`,
        file,
        type,
        previewUrl: type === 'audio' ? '' : URL.createObjectURL(file),
        label: `${labelPrefix}${fileCounter}`,
      });
      counts[type]++;
    }
    if (newRefs.length > 0) {
      set({ references: [...state.references, ...newRefs] });
    }
  },
  removeReference: (id) => {
    const state = get();
    const ref = state.references.find((r) => r.id === id);
    if (ref) URL.revokeObjectURL(ref.previewUrl);
    set({ references: state.references.filter((r) => r.id !== id) });
  },
  clearReferences: () => {
    const state = get();
    state.references.forEach((r) => URL.revokeObjectURL(r.previewUrl));
    set({ references: [] });
  },

  firstFrame: null,
  lastFrame: null,
  setFirstFrame: (file) => {
    const state = get();
    if (state.firstFrame) URL.revokeObjectURL(state.firstFrame.previewUrl);
    if (file) {
      fileCounter++;
      set({
        firstFrame: {
          id: `first_${fileCounter}`,
          file,
          type: 'image',
          previewUrl: URL.createObjectURL(file),
          label: '首帧',
        },
      });
    } else {
      set({ firstFrame: null });
    }
  },
  setLastFrame: (file) => {
    const state = get();
    if (state.lastFrame) URL.revokeObjectURL(state.lastFrame.previewUrl);
    if (file) {
      fileCounter++;
      set({
        lastFrame: {
          id: `last_${fileCounter}`,
          file,
          type: 'image',
          previewUrl: URL.createObjectURL(file),
          label: '尾帧',
        },
      });
    } else {
      set({ lastFrame: null });
    }
  },

  canSubmit: () => {
    const state = get();
    const hasText = state.prompt.trim().length > 0;
    const hasFiles =
      state.mode === 'universal'
        ? state.references.length > 0
        : state.firstFrame !== null || state.lastFrame !== null;
    if (!hasText && !hasFiles) return false;
    // Audio cannot be sent alone — must have image or video
    if (state.mode === 'universal' && state.references.length > 0) {
      const hasImageOrVideo = state.references.some((r) => r.type === 'image' || r.type === 'video');
      if (!hasImageOrVideo && !hasText) return false;
    }
    return true;
  },

  searchMode: 'off',
  setSearchMode: (searchMode) => set({ searchMode }),

  assetMentions: [],

  insertAtTrigger: 0,
  triggerInsertAt: () => set((s) => ({ insertAtTrigger: s.insertAtTrigger + 1 })),

  switchMode: (mode) => {
    const state = get();
    if (state.mode === mode) return;

    if (mode === 'keyframe') {
      set({
        mode,
        prevReferences: state.references,
        references: [],
        aspectRatio: '16:9',
        duration: 5,
      });
    } else {
      // Clear keyframe
      if (state.firstFrame) URL.revokeObjectURL(state.firstFrame.previewUrl);
      if (state.lastFrame) URL.revokeObjectURL(state.lastFrame.previewUrl);
      set({
        mode,
        firstFrame: null,
        lastFrame: null,
        references: state.prevReferences,
        prevReferences: [],
        aspectRatio: state.prevAspectRatio,
        duration: state.prevDuration,
      });
    }
  },

  submit: () => {
    // Just show a toast - no real API call
  },

  reset: () => {
    const state = get();
    state.references.forEach((r) => URL.revokeObjectURL(r.previewUrl));
    state.prevReferences.forEach((r) => URL.revokeObjectURL(r.previewUrl));
    if (state.firstFrame) URL.revokeObjectURL(state.firstFrame.previewUrl);
    if (state.lastFrame) URL.revokeObjectURL(state.lastFrame.previewUrl);
    set({
      mode: 'universal',
      model: 'seedance_2.0',
      aspectRatio: '21:9',
      prevAspectRatio: '21:9',
      duration: 15,
      prevDuration: 15,
      prompt: '',
      editorHtml: '',
      references: [],
      prevReferences: [],
      assetMentions: [],
      firstFrame: null,
      lastFrame: null,
      generationType: 'video',
    });
  },
}));
