import { NextRequest, NextResponse } from 'next/server';
import { MetaAIClient } from '@/lib/providers/meta-client';

/**
 * POST /api/meta/video
 * 
 * Generate a video from a text prompt using Meta AI's Kadabra engine.
 * Uses MetaAIClient for session initialization (which works for images).
 */

const META_AI_BASE = "https://www.meta.ai";
const GRAPHQL_ENDPOINT = `${META_AI_BASE}/api/graphql/`;

// Video generation doc IDs from metaai-api
const VIDEO_INITIATE_DOC_ID = "25290947477183545";  // useKadabraSendMessageMutation
const VIDEO_POLL_DOC_ID = "25290569913909283";      // KadabraPromptRootQuery

export async function POST(req: NextRequest) {
    try {
        const { prompt, cookies: clientCookies, aspectRatio = 'portrait' } = await req.json();

        if (!prompt) {
            return NextResponse.json({ error: "Prompt is required" }, { status: 400 });
        }

        if (!clientCookies) {
            return NextResponse.json(
                { error: "Meta AI cookies not found. Please configure settings." },
                { status: 401 }
            );
        }

        console.log(`[Meta Video API] Generating video for: "${prompt.substring(0, 50)}..." (${aspectRatio})`);

        // Use MetaAIClient for session initialization (proven to work)
        const client = new MetaAIClient({ cookies: clientCookies });
        const session = await client.getSession();
        const cookieString = client.getCookies();

        console.log("[Meta Video] Using MetaAIClient session:", {
            hasLsd: !!session.lsd,
            hasDtsg: !!session.fb_dtsg,
            hasAccessToken: !!session.accessToken
        });

        // Generate unique IDs for this request
        const externalConversationId = crypto.randomUUID();
        const offlineThreadingId = Date.now().toString() + Math.random().toString().substring(2, 8);

        // Initiate video generation with aspect ratio
        await initiateVideoGeneration(prompt, externalConversationId, offlineThreadingId, session, cookieString, aspectRatio);

        // Poll for video completion
        const videos = await pollForVideoResult(externalConversationId, session, cookieString);

        if (videos.length === 0) {
            throw new Error("No videos generated");
        }

        return NextResponse.json({
            success: true,
            videos: videos.map(v => ({ url: v.url, prompt: prompt })),
            conversation_id: externalConversationId
        });

    } catch (error: unknown) {
        const err = error as Error;
        console.error("[Meta Video API] Error:", err.message);

        const msg = err.message || "";
        const isAuthError = msg.includes("401") || msg.includes("403") ||
            msg.includes("auth") || msg.includes("cookies") || msg.includes("expired") || msg.includes("Login");

        return NextResponse.json(
            { error: err.message || "Video generation failed" },
            { status: isAuthError ? 401 : 500 }
        );
    }
}

interface MetaSession {
    lsd?: string;
    fb_dtsg?: string;
    accessToken?: string;
}

/**
 * Normalize cookies from JSON array to string format
 */
function normalizeCookies(cookies: string): string {
    if (!cookies) return '';

    try {
        const trimmed = cookies.trim();
        if (trimmed.startsWith('[')) {
            const parsed = JSON.parse(trimmed);
            if (Array.isArray(parsed)) {
                return parsed.map((c: any) => `${c.name}=${c.value}`).join('; ');
            }
        }
    } catch (e) {
        // Not JSON, assume it's already a string format
    }

    return cookies;
}

/**
 * Initialize session - get access token and LSD from meta.ai page
 */
async function initSession(cookies: string, retryCount: number = 0): Promise<MetaSession> {
    console.log("[Meta Video] Initializing session...");
    console.log("[Meta Video] Cookie string length:", cookies.length);

    // Add small delay to avoid rate limiting (especially after image generation)
    if (retryCount > 0) {
        await new Promise(resolve => setTimeout(resolve, 1000 * retryCount));
    }

    const response = await fetch(META_AI_BASE, {
        headers: {
            "Cookie": cookies,
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
            "Accept-Language": "en-US,en;q=0.5",
        }
    });

    const html = await response.text();
    console.log("[Meta Video] HTML Preview:", html.substring(0, 200));

    // Detect Facebook error page and retry
    if (html.includes('<title>Error</title>') || html.includes('id="facebook"')) {
        console.warn("[Meta Video] Received Facebook error page, retrying...");
        if (retryCount < 3) {
            return initSession(cookies, retryCount + 1);
        }
        throw new Error("Meta AI: Server temporarily unavailable. Please try again in a moment.");
    }

    const session: MetaSession = {};

    // Extract LSD token - multiple patterns for different Meta AI versions
    const lsdMatch = html.match(/"LSD",\[\],\{"token":"([^"]+)"/) ||
        html.match(/"lsd":"([^"]+)"/) ||
        html.match(/name="lsd" value="([^"]+)"/) ||
        html.match(/"token":"([^"]+)".*?"name":"lsd"/);
    if (lsdMatch) {
        session.lsd = lsdMatch[1];
    }

    // Extract access token
    const tokenMatch = html.match(/"accessToken":"([^"]+)"/) ||
        html.match(/accessToken['"]\s*:\s*['"]([^'"]+)['"]/);
    if (tokenMatch) {
        session.accessToken = tokenMatch[1];
    }

    // Extract DTSG token - try multiple patterns
    const dtsgMatch = html.match(/DTSGInitData",\[\],\{"token":"([^"]+)"/) ||
        html.match(/"DTSGInitialData".*?"token":"([^"]+)"/) ||
        html.match(/fb_dtsg['"]\s*:\s*\{[^}]*['"]token['"]\s*:\s*['"]([^'"]+)['"]/);
    if (dtsgMatch) {
        session.fb_dtsg = dtsgMatch[1];
    }

    // Also try to extract from cookies if not found in HTML
    if (!session.lsd) {
        const lsdCookie = cookies.match(/lsd=([^;]+)/);
        if (lsdCookie) session.lsd = lsdCookie[1];
    }
    if (!session.fb_dtsg) {
        const dtsgCookie = cookies.match(/fb_dtsg=([^;]+)/);
        if (dtsgCookie) session.fb_dtsg = dtsgCookie[1];
    }

    if (html.includes('login_form') || html.includes('login_page')) {
        throw new Error("Meta AI: Cookies expired. Please update in Settings.");
    }

    console.log("[Meta Video] Session tokens extracted:", {
        hasLsd: !!session.lsd,
        hasDtsg: !!session.fb_dtsg,
        hasAccessToken: !!session.accessToken
    });

    return session;
}

/**
 * Initiate video generation using Kadabra mutation
 */
async function initiateVideoGeneration(
    prompt: string,
    conversationId: string,
    threadingId: string,
    session: MetaSession,
    cookies: string,
    aspectRatio: string = 'portrait'
): Promise<void> {
    console.log("[Meta Video] Initiating video generation...");

    // Map aspect ratio to orientation
    const orientationMap: Record<string, string> = {
        'portrait': 'VERTICAL',
        'landscape': 'HORIZONTAL',
        'square': 'SQUARE'
    };
    const orientation = orientationMap[aspectRatio] || 'VERTICAL';

    const variables = {
        message: {
            prompt_text: prompt,
            external_conversation_id: conversationId,
            offline_threading_id: threadingId,
            imagineClientOptions: { orientation: orientation },
            selectedAgentType: "PLANNER"
        },
        __relay_internal__pv__AbraArtifactsEnabledrelayprovider: true
    };

    const body = new URLSearchParams({
        fb_api_caller_class: "RelayModern",
        fb_api_req_friendly_name: "useKadabraSendMessageMutation",
        variables: JSON.stringify(variables),
        doc_id: VIDEO_INITIATE_DOC_ID,
        ...(session.lsd && { lsd: session.lsd }),
        ...(session.fb_dtsg && { fb_dtsg: session.fb_dtsg })
    });

    const response = await fetch(GRAPHQL_ENDPOINT, {
        method: "POST",
        headers: {
            "Content-Type": "application/x-www-form-urlencoded",
            "Cookie": cookies,
            "Origin": META_AI_BASE,
            "Referer": `${META_AI_BASE}/`,
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
            ...(session.accessToken && { "Authorization": `OAuth ${session.accessToken}` })
        },
        body: body.toString()
    });

    if (!response.ok) {
        const errorText = await response.text();
        console.error("[Meta Video] Initiation failed:", response.status, errorText);
        throw new Error(`Meta AI Error: ${response.status}`);
    }

    const data = await response.json();
    console.log("[Meta Video] Initiation response:", JSON.stringify(data).substring(0, 200));

    // Check for errors
    if (data.errors) {
        throw new Error(data.errors[0]?.message || "Video initiation failed");
    }
}

/**
 * Poll for video result using KadabraPromptRootQuery
 */
async function pollForVideoResult(
    conversationId: string,
    session: MetaSession,
    cookies: string
): Promise<{ url: string }[]> {
    const maxAttempts = 60; // 2 minutes max
    const pollInterval = 2000;

    for (let attempt = 0; attempt < maxAttempts; attempt++) {
        console.log(`[Meta Video] Polling attempt ${attempt + 1}/${maxAttempts}...`);

        await new Promise(resolve => setTimeout(resolve, pollInterval));

        const variables = {
            external_conversation_id: conversationId
        };

        const body = new URLSearchParams({
            fb_api_caller_class: "RelayModern",
            fb_api_req_friendly_name: "KadabraPromptRootQuery",
            variables: JSON.stringify(variables),
            doc_id: VIDEO_POLL_DOC_ID,
            ...(session.lsd && { lsd: session.lsd }),
            ...(session.fb_dtsg && { fb_dtsg: session.fb_dtsg })
        });

        try {
            const response = await fetch(GRAPHQL_ENDPOINT, {
                method: "POST",
                headers: {
                    "Content-Type": "application/x-www-form-urlencoded",
                    "Cookie": cookies,
                    "Origin": META_AI_BASE,
                    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
                    ...(session.accessToken && { "Authorization": `OAuth ${session.accessToken}` })
                },
                body: body.toString()
            });

            const data = await response.json();

            // Extract video URLs from response
            const videos = extractVideosFromResponse(data);

            if (videos.length > 0) {
                console.log(`[Meta Video] Got ${videos.length} video(s)!`);
                return videos;
            }

            // Check for error status
            const status = data?.data?.kadabra_prompt?.status;
            if (status === "FAILED" || status === "ERROR") {
                throw new Error("Meta AI video generation failed");
            }
        } catch (e: any) {
            console.error("[Meta Video] Poll error:", e.message);
            if (attempt === maxAttempts - 1) throw e;
        }
    }

    throw new Error("Meta AI: Video generation timed out");
}

/**
 * Extract video URLs from GraphQL response
 */
function extractVideosFromResponse(response: any): { url: string }[] {
    const videos: { url: string }[] = [];

    try {
        // Navigate through possible response structures
        const prompt = response?.data?.kadabra_prompt;
        const messages = prompt?.messages?.edges || [];

        for (const edge of messages) {
            const node = edge?.node;
            const attachments = node?.attachments || [];

            for (const attachment of attachments) {
                // Check for video media
                const media = attachment?.media;
                if (media?.video_uri) {
                    videos.push({ url: media.video_uri });
                }
                if (media?.playable_url) {
                    videos.push({ url: media.playable_url });
                }
                if (media?.browser_native_sd_url) {
                    videos.push({ url: media.browser_native_sd_url });
                }
            }

            // Check imagine_card for video results
            const imagineCard = node?.imagine_card;
            if (imagineCard?.session?.media_sets) {
                for (const mediaSet of imagineCard.session.media_sets) {
                    for (const media of mediaSet?.imagine_media || []) {
                        if (media?.video_uri) {
                            videos.push({ url: media.video_uri });
                        }
                    }
                }
            }
        }
    } catch (e) {
        console.error("[Meta Video] Error extracting videos:", e);
    }

    return videos;
}
