// Project lifecycle actions: load, new, rename, delete.
// All project state is persisted via the server-mirror (auto: server if logged in, otherwise local IndexedDB).

import { uid } from './types';
import type { EditorActions, Getter, Setter, TextOverlay } from './types';
import type {
  Clip,
  ExportSettings,
  SilenceSegment,
  SubtitleCue,
  SubtitleStyle,
  Track,
} from '@/types';
import * as mirror from '@/lib/storage/server-mirror';
import { useAuth } from '@/store/auth';

function ctxFromAuth() {
  const s = useAuth.getState();
  return { mode: s.storageMode, isLoggedIn: !!s.user };
}

function clone<T>(v: T): T {
  return JSON.parse(JSON.stringify(v));
}

export function createProjectActions(
  set: Setter,
  get: Getter,
): Pick<
  EditorActions,
  | 'setProjectName'
  | 'loadProjectById'
  | 'newProject'
  | 'deleteCurrentProject'
> {
  return {
    setProjectName: (name) => {
      set({ projectName: name });
    },

    newProject: async (name) => {
      const id = uid();
      const now = Date.now();
      const ctx = ctxFromAuth();
      await mirror.saveProject(
        id,
        name,
        now,
        {
          tracks: get().tracks,
          clips: [],
          subtitles: [],
          textOverlays: [],
          silenceSegments: [],
          selection: {},
          assetsMeta: [],
        },
        ctx,
      );
      await mirror.setCurrentProjectId(id);
      set({
        projectId: id,
        projectName: name,
        projectCreatedAt: now,
        assets: [],
        clips: [],
        subtitles: [],
        textOverlays: [],
        silenceSegments: [],
        selection: {},
        currentTime: 0,
        playing: false,
        history: [],
        historyIndex: -1,
      });
    },

    loadProjectById: async (id) => {
      const ctx = ctxFromAuth();
      const stored = await mirror.loadProject(id, ctx);
      if (!stored) throw new Error(`ไม่พบโปรเจกต์ ${id}`);
      await mirror.setCurrentProjectId(id);
      set({
        projectId: stored.id,
        projectName: stored.name,
        projectCreatedAt: stored.createdAt,
        tracks: (stored.tracks as Track[]) ?? get().tracks,
        clips: (stored.clips as Clip[]) ?? [],
        subtitles: (stored.subtitles as SubtitleCue[]) ?? [],
        textOverlays: (stored.textOverlays as TextOverlay[]) ?? [],
        silenceSegments: (stored.silenceSegments as SilenceSegment[]) ?? [],
        selection: (stored.selection as { clipId?: string; trackId?: string; textOverlayId?: string }) ?? {},
        currentTime: 0,
        playing: false,
        history: [],
        historyIndex: -1,
        ...(stored.subtitleStyle
          ? { subtitleStyle: stored.subtitleStyle as SubtitleStyle }
          : {}),
        ...(stored.exportSettings
          ? { exportSettings: stored.exportSettings as ExportSettings }
          : {}),
      });
    },

    deleteCurrentProject: async () => {
      const id = get().projectId;
      if (!id) return;
      const ctx = ctxFromAuth();
      await mirror.deleteProject(id, ctx);
      const newId = uid();
      const now = Date.now();
      await mirror.saveProject(
        newId,
        'โปรเจกต์ใหม่',
        now,
        {
          tracks: get().tracks,
          clips: [],
          subtitles: [],
          textOverlays: [],
          silenceSegments: [],
          selection: {},
          assetsMeta: [],
        },
        ctx,
      );
      await mirror.setCurrentProjectId(newId);
      set({
        projectId: newId,
        projectName: 'โปรเจกต์ใหม่',
        projectCreatedAt: now,
        assets: [],
        clips: [],
        subtitles: [],
        textOverlays: [],
        silenceSegments: [],
        selection: {},
        currentTime: 0,
        playing: false,
        history: [],
        historyIndex: -1,
      });
      void clone;
    },
  };
}
