import { setIn } from 'lodash-redux-immutability';

import { setOneUntimedCondition } from '@/app/(root)/create/v2/actions/currentModeSetters';
import {
  ConditionTypes,
  CreateFormState,
  CreateModes,
} from '@/app/(root)/create/v2/types';
import { Clip } from '@/state/clipStore';
import { PersonaMetadata } from '@/state/personaStore';

const applyPersona =
  (
    clipOrPersona:
      | Clip
      | (PersonaMetadata & { clip?: { image_url?: string | null } }),
    rootClip?: Clip,
    options?: { overwriteStyles?: boolean }
  ) =>
  (state: CreateFormState) => {
    // Case 1: clip with persona data (existing usage like ClipMenuItems)
    if (!rootClip && 'persona' in clipOrPersona) {
      const clip = clipOrPersona as Clip;
      state = setOneUntimedCondition(ConditionTypes.PERSONA, [
        {
          personaId: clip.persona?.id || '',
          rootClipId: clip.persona?.root_clip_id || clip.id,
          clipId: clip.id,
          startSeconds: 0,
          endSeconds: clip.metadata?.duration || undefined,
          personaName: clip.persona?.name || undefined,
          personaImageUrl:
            clip.persona?.image_s3_id || clip.image_url || undefined,
        },
      ])(state);
      state = setIn(state, ['global', 'mode'], CreateModes.CUSTOM);
      return state;
    }

    // Case 2: persona metadata + root clip (CreateFormContext usage)
    if (rootClip && 'id' in clipOrPersona) {
      const persona = clipOrPersona as PersonaMetadata & {
        clip?: { image_url?: string | null };
      };
      const personaName =
        persona.name && persona.name.trim() !== ''
          ? persona.name.trim()
          : 'Untitled Persona';
      const personaStyles = rootClip.metadata?.tags || '';
      const personaNegativeTags = rootClip.metadata?.negative_tags || '';

      state = setOneUntimedCondition(ConditionTypes.PERSONA, [
        {
          personaId: persona.id ?? '',
          rootClipId: persona.root_clip_id || undefined,
          clipId: persona.root_clip_id || undefined,
          startSeconds: 0,
          endSeconds: rootClip.metadata?.duration ?? undefined,
          personaName,
          personaImageUrl:
            persona.image_s3_id || persona.clip?.image_url || undefined,
        },
      ])(state);

      state = setIn(state, ['global', 'mode'], CreateModes.CUSTOM);

      // Set styles if empty OR overwrite if explicitly requested
      const currentStyles = state[CreateModes.CUSTOM].styles || '';
      const currentExcludeStyles =
        state[CreateModes.CUSTOM].excludeStyles || '';
      const shouldOverwriteStyles =
        options?.overwriteStyles === true || currentStyles.trim() === '';
      const shouldOverwriteExcludeStyles =
        options?.overwriteStyles === true || currentExcludeStyles.trim() === '';

      if (shouldOverwriteStyles) {
        state = setIn(state, [CreateModes.CUSTOM, 'styles'], personaStyles);
      }
      if (shouldOverwriteExcludeStyles) {
        state = setIn(
          state,
          [CreateModes.CUSTOM, 'excludeStyles'],
          personaNegativeTags
        );
      }
      // Do not overwrite lyrics
      return state;
    }

    return state;
  };

// Type for persona data from API
export interface PersonaData {
  id: string;
  root_clip_id?: string | null;
  clip?: {
    id?: string;
  } | null;
  name: string;
  image_s3_id?: string | null;
}

// Helper to apply persona from persona data (e.g., from vox-prototype)
export const applyPersonaFromData =
  (personaData: PersonaData) => (state: CreateFormState) => {
    const rootClipId = personaData.root_clip_id || personaData.clip?.id || '';
    if (!rootClipId) {
      console.warn(
        'applyPersonaFromData: missing root clip id for persona',
        personaData
      );
      return state;
    }

    state = setOneUntimedCondition(ConditionTypes.PERSONA, [
      {
        personaId: personaData.id,
        rootClipId,
        clipId: rootClipId,
        startSeconds: 0,
        endSeconds: undefined,
        personaName: personaData.name || undefined,
        personaImageUrl: personaData.image_s3_id || undefined,
      },
    ])(state);

    state = setIn(state, ['global', 'mode'], CreateModes.CUSTOM);

    return state;
  };

export default applyPersona;
