import type { StudioState } from '../types/studio';
import { CHANNEL_OPTIONS } from '../types/studio';

const CREATOMATE_API_KEY = import.meta.env.VITE_CREATOMATE_API_KEY ?? '';
const API_BASE = 'https://api.creatomate.com/v1';

export interface VideoResult {
  videoUrl: string;
  prompt: string;
}

interface CreatomateRender {
  id: string;
  status: 'planned' | 'waiting' | 'transcribing' | 'rendering' | 'succeeded' | 'failed';
  url?: string;
  error_message?: string;
}

const ASPECT_DIMENSIONS: Record<string, { width: number; height: number }> = {
  '9:16': { width: 1080, height: 1920 },
  '16:9': { width: 1920, height: 1080 },
  '1:1': { width: 1080, height: 1080 },
  '4:5': { width: 1080, height: 1350 },
};

const PILLAR_TITLES: Record<string, { ko: string; en: string }> = {
  safety: { ko: '안전한 수술 시스템', en: 'Safe Surgery System' },
  expertise: { ko: '전문 의료진', en: 'Expert Medical Team' },
  results: { ko: '자연스러운 결과', en: 'Natural Results' },
  care: { ko: '환자 중심 케어', en: 'Patient-Centered Care' },
};

/**
 * Build a Creatomate source object programmatically.
 * This creates a simple branded slideshow video without needing
 * a pre-built template — ideal for initial integration.
 */
function buildSource(state: StudioState) {
  const channel = CHANNEL_OPTIONS.find(c => c.channel === state.channel);
  const format = channel?.formats.find(f => f.key === state.format);
  const dims = ASPECT_DIMENSIONS[format?.aspectRatio ?? '16:9'];
  const pillar = state.pillarId ? PILLAR_TITLES[state.pillarId] : null;

  return {
    output_format: 'mp4',
    width: dims.width,
    height: dims.height,
    duration: 10,
    elements: [
      // Background gradient
      {
        type: 'shape',
        shape: 'rectangle',
        width: '100%',
        height: '100%',
        fill_color: 'linear-gradient(180deg, #0A1128 0%, #1A2B5E 50%, #4F1DA1 100%)',
      },
      // Title text
      {
        type: 'text',
        text: pillar?.ko || 'INFINITH Marketing',
        font_family: 'Noto Sans KR',
        font_weight: '700',
        font_size: dims.width > dims.height ? '72px' : '56px',
        fill_color: '#FFFFFF',
        x: '50%',
        y: '40%',
        x_anchor: '50%',
        y_anchor: '50%',
        width: '80%',
        text_align: 'center',
        animations: [
          { type: 'text-appear', duration: 1, split: 'word' },
        ],
      },
      // Subtitle
      {
        type: 'text',
        text: pillar?.en || 'Premium Medical Marketing',
        font_family: 'Noto Sans KR',
        font_weight: '400',
        font_size: dims.width > dims.height ? '36px' : '28px',
        fill_color: 'rgba(255,255,255,0.7)',
        x: '50%',
        y: '55%',
        x_anchor: '50%',
        y_anchor: '50%',
        width: '80%',
        text_align: 'center',
        animations: [
          { type: 'fade', fade_in: true, duration: 0.8, start: 0.5 },
        ],
      },
      // Brand accent line
      {
        type: 'shape',
        shape: 'rectangle',
        width: '120px',
        height: '4px',
        fill_color: '#6C5CE7',
        x: '50%',
        y: '48%',
        x_anchor: '50%',
        y_anchor: '50%',
        animations: [
          { type: 'wipe', duration: 0.6, start: 0.3 },
        ],
      },
      // Channel badge
      {
        type: 'text',
        text: `${channel?.label || ''} · ${format?.label || ''}`,
        font_family: 'Noto Sans KR',
        font_weight: '500',
        font_size: '20px',
        fill_color: 'rgba(255,255,255,0.5)',
        x: '50%',
        y: '90%',
        x_anchor: '50%',
        y_anchor: '50%',
        text_align: 'center',
      },
    ],
  };
}

async function pollRender(renderId: string, maxAttempts = 30): Promise<CreatomateRender> {
  for (let i = 0; i < maxAttempts; i++) {
    const res = await fetch(`${API_BASE}/renders/${renderId}`, {
      headers: { Authorization: `Bearer ${CREATOMATE_API_KEY}` },
    });

    if (!res.ok) {
      throw new Error(`렌더 상태 확인 실패 (${res.status})`);
    }

    const render: CreatomateRender = await res.json();

    if (render.status === 'succeeded' && render.url) {
      return render;
    }

    if (render.status === 'failed') {
      throw new Error(render.error_message || '영상 렌더링에 실패했습니다');
    }

    // Wait 2 seconds before next poll
    await new Promise(resolve => setTimeout(resolve, 2000));
  }

  throw new Error('영상 렌더링 시간이 초과되었습니다 — 다시 시도해주세요');
}

export async function generateVideo(state: StudioState): Promise<VideoResult> {
  if (!CREATOMATE_API_KEY) {
    throw new Error('Creatomate API 키가 설정되지 않았습니다');
  }

  const source = buildSource(state);
  const prompt = `${state.channel}/${state.format} — ${state.pillarId || 'general'}`;

  let renderResponse;
  try {
    renderResponse = await fetch(`${API_BASE}/renders`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${CREATOMATE_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ source }),
    });
  } catch (err) {
    throw new Error('Creatomate 서버에 연결할 수 없습니다');
  }

  if (!renderResponse.ok) {
    const status = renderResponse.status;
    if (status === 401) throw new Error('Creatomate API 인증 실패 — 관리자에게 문의하세요');
    if (status === 429) throw new Error('렌더 한도 초과 — 잠시 후 다시 시도해주세요');
    if (status === 400) {
      const body = await renderResponse.json().catch(() => ({}));
      throw new Error(`영상 설정 오류: ${body.message || '잘못된 요청'}`);
    }
    throw new Error(`영상 생성 요청 실패 (${status})`);
  }

  const renders: CreatomateRender[] = await renderResponse.json();
  const render = renders[0];

  if (!render?.id) {
    throw new Error('렌더 ID를 받지 못했습니다');
  }

  // If already succeeded (fast render)
  if (render.status === 'succeeded' && render.url) {
    return { videoUrl: render.url, prompt };
  }

  // Poll for completion
  const completed = await pollRender(render.id);
  return { videoUrl: completed.url!, prompt };
}
