import {getStandeeSet, type AvatarDefinition} from "../../standee-sets";
import type {VQStillEvent, VQWaitEvent} from "../../lib/VQRemotionLib";

export type VoicevoxVoice = Readonly<{
  speakerName: string;
  styleName: string;
}>;

export type CharacterDefinition = Readonly<{
  displayName: string;
  voicevox: VoicevoxVoice;
  avatar: AvatarDefinition;
}>;

export const characters = {
  sayo: {
    displayName: "小夜",
    voicevox: {
      speakerName: "小夜/SAYO",
      styleName: "ノーマル",
    },
    avatar: {
      ...getStandeeSet("sayo_ohnegus_ai"),
      accentColor: "#6b5f83",
      speakingAnimationType: "rhubarbLipSync",
      idleAnimationType: "none",
    },
  },
} as const satisfies Record<string, CharacterDefinition>;

export type CharacterId = keyof typeof characters;

export type SpeechOptions = Readonly<{
  subtitle?: string;
  voicevox?: Partial<VoicevoxVoice>;
  durationSeconds?: number;
}>;

export type SpeechEvent = Readonly<{
  type: "say";
  id: string;
  character: CharacterId;
  text: string;
  subtitle?: string;
  voicevox?: Partial<VoicevoxVoice>;
  durationSeconds?: number;
}>;

export type StillEvent = VQStillEvent;
export type WaitEvent = VQWaitEvent;

export type TimelineEvent = SpeechEvent | StillEvent | WaitEvent;

export const say = (
  id: string,
  character: CharacterId,
  text: string,
  options: SpeechOptions = {}
): SpeechEvent => ({
  type: "say",
  id,
  character,
  text,
  ...options,
});

export const still = (
  id: string,
  imagePath: string,
  options: Omit<StillEvent, "type" | "id" | "imagePath"> = {}
): StillEvent => ({
  type: "still",
  id,
  imagePath,
  ...options,
});

export const wait = (id: string, durationSeconds: number): WaitEvent => ({
  type: "wait",
  id,
  durationSeconds,
});

export const timeline = [
  say("pizza-oven-project-01-sayo-001", "sayo", "こんにちは。小夜です。"),
  say("pizza-oven-project-01-sayo-002", "sayo", "ピザって美味しいじゃないですか。"),
  say("pizza-oven-project-01-sayo-003", "sayo", "だから、作る事にしたんですよね。"),
  still(
    "pizza-oven-project-01-oven-still-001",
    "image/still/blender-oven-still01.png",
    {
      durationSeconds: 1.5,
      fit: "cover",
    }
  ),
  say("pizza-oven-project-01-sayo-004", "sayo", "ピザ窯を。"),
  wait("pizza-oven-project-01-wait-001", 1),
  say("pizza-oven-project-01-sayo-005", "sayo", "まずはblender上で、耐熱レンガの寸法を元に積み方を設計することにしました。"),
] satisfies TimelineEvent[];

export const isSpeechEvent = (
  event: TimelineEvent
): event is SpeechEvent => event.type === "say";

export const script = timeline.filter(isSpeechEvent);
