'use client';

import { useState, useRef, useEffect } from 'react';
import { useSearchParams, useRouter } from 'next/navigation';
import { toast } from 'react-hot-toast';
import { FileVideo, Image as ImageIcon, Download, Scissors, ChevronRight, Wand2, RefreshCw, Sparkles, Settings2 } from 'lucide-react';
import FileUpload from '@/components/FileUpload';
import { assetsApi, modulesApi, jobsApi } from '@/lib/api';
import { useStore } from '@/lib/store';

const scaleOptions = [
    { value: 2, label: '2x' },
    { value: 4, label: '4x' },
    { value: 6, label: '6x' },
];

const modelOptions = [
    { value: 'Standard V2', label: 'Standard V2' },
    { value: 'High Fidelity V2', label: 'High Fidelity V2' },
    { value: 'Low Resolution V2', label: 'Low Resolution V2' },
    { value: 'CGI', label: 'CGI' },
    { value: 'Text Refine', label: 'Text Refine' },
    { value: 'Enhance Generative', label: 'Enhance Generative' },
    { value: 'Auto', label: 'Auto' },
];

interface ExtractedFrame {
    id: string;
    asset_metadata?: {
        timestamp: number;
    };
    upscaleStatus?: 'idle' | 'processing' | 'completed' | 'error';
    upscaleJobId?: string;
    upscaleResultId?: string;
    upscaleError?: string;
}

export default function FrameExtractorPage() {
    const router = useRouter();
    const searchParams = useSearchParams();
    const { addJob } = useStore();

    const [asset, setAsset] = useState<any>(null);
    const [loading, setLoading] = useState(false);
    const [extracting, setExtracting] = useState(false);
    const [currentTime, setCurrentTime] = useState(0);
    const [duration, setDuration] = useState(0);
    const videoRef = useRef<HTMLVideoElement>(null);
    const [extractedFrames, setExtractedFrames] = useState<ExtractedFrame[]>([]);

    // Upscale Settings
    const [scale, setScale] = useState(2);
    const [model, setModel] = useState('Auto');
    const [denoiseStrength, setDenoiseStrength] = useState(0.5);
    const [sharpen, setSharpen] = useState(0.5);

    // Load from URL if present
    useEffect(() => {
        const assetId = searchParams.get('assetId') || searchParams.get('assetIds')?.split(',')[0];
        if (assetId) {
            loadAsset(assetId);
        }
    }, [searchParams]);

    const loadAsset = async (id: string) => {
        setLoading(true);
        try {
            const res = await assetsApi.get(id);
            if (res.data.file_type === 'video') {
                setAsset(res.data);
            } else {
                toast.error('Asset is not a video');
            }
        } catch (err) {
            toast.error('Failed to load asset');
        } finally {
            setLoading(false);
        }
    };

    const handleFileUpload = async (file: File) => {
        setLoading(true);
        try {
            const res = await assetsApi.upload(file);
            setAsset(res.data);
            router.push(`/video/extract?assetId=${res.data.id}`);
        } catch (err: any) {
            if (err.response?.status === 409) {
                const existingAssetId = err.response.data.detail.asset_id;
                const shouldOverwrite = window.confirm(
                    `File "${file.name}" already exists. \nClick OK to Overwrite, Cancel to Use Existing.`
                );

                if (shouldOverwrite) {
                    try {
                        const overwriteRes = await assetsApi.upload(file, undefined, false, true); // overwrite=true
                        setAsset(overwriteRes.data);
                        router.push(`/video/extract?assetId=${overwriteRes.data.id}`);
                    } catch (retryErr) {
                        toast.error('Overwrite failed');
                    }
                } else {
                    // Use existing
                    router.push(`/video/extract?assetId=${existingAssetId}`);
                    loadAsset(existingAssetId);
                }
            } else {
                toast.error('Upload failed');
            }
        } finally {
            setLoading(false);
        }
    };

    const handleTimeUpdate = () => {
        if (videoRef.current) {
            setCurrentTime(videoRef.current.currentTime);
            setDuration(videoRef.current.duration || 0);
        }
    };

    const formatTime = (seconds: number) => {
        const mins = Math.floor(seconds / 60);
        const secs = Math.floor(seconds % 60);
        const ms = Math.floor((seconds % 1) * 100);
        return `${mins}:${secs.toString().padStart(2, '0')}.${ms.toString().padStart(2, '0')}`;
    };

    const extractFrame = async () => {
        if (!asset || !videoRef.current) return;

        setExtracting(true);
        try {
            const timestamp = videoRef.current.currentTime;

            const res = await modulesApi.extractFrame({
                asset_id: asset.id,
                timestamp: timestamp
            });

            const newFrame: ExtractedFrame = {
                ...res.data,
                upscaleStatus: 'idle'
            };

            setExtractedFrames(prev => [newFrame, ...prev]);
            toast.success('Frame extracted!');
        } catch (err) {
            console.error(err);
            toast.error('Extraction failed');
        } finally {
            setExtracting(false);
        }
    };

    const handleUpscale = async (frame: ExtractedFrame) => {
        if (frame.upscaleStatus === 'processing') return;

        // Update status to processing
        setExtractedFrames(prev => prev.map(f =>
            f.id === frame.id ? { ...f, upscaleStatus: 'processing' } : f
        ));

        try {
            const response = await modulesApi.upscaleImage({
                asset_id: frame.id,
                scale,
                model,
                denoise_strength: denoiseStrength,
                sharpen,
            });

            const job = response.data;

            addJob({
                id: job.id,
                module: 'image_upscaling',
                status: job.status,
                progress: job.progress,
                created_at: job.created_at,
            });

            setExtractedFrames(prev => prev.map(f =>
                f.id === frame.id ? { ...f, upscaleJobId: job.id } : f
            ));

            // Poll for completion
            pollJob(frame.id, job.id);
            toast.success('Upscaling started');

        } catch (err: any) {
            console.error(err);
            toast.error('Upscale failed: ' + (err.message || 'Unknown error'));
            setExtractedFrames(prev => prev.map(f =>
                f.id === frame.id ? { ...f, upscaleStatus: 'error', upscaleError: err.message } : f
            ));
        }
    };

    const pollJob = async (frameId: string, jobId: string) => {
        let currentJob: any;
        const interval = setInterval(async () => {
            try {
                const res = await jobsApi.get(jobId);
                currentJob = res.data;

                if (currentJob.status === 'completed' || currentJob.status === 'failed') {
                    clearInterval(interval);

                    if (currentJob.status === 'completed' && currentJob.output_asset_ids?.[0]) {
                        setExtractedFrames(prev => prev.map(f =>
                            f.id === frameId ? {
                                ...f,
                                upscaleStatus: 'completed',
                                upscaleResultId: currentJob.output_asset_ids[0]
                            } : f
                        ));
                        toast.success('Upscale complete!');
                    } else {
                        setExtractedFrames(prev => prev.map(f =>
                            f.id === frameId ? {
                                ...f,
                                upscaleStatus: 'error',
                                upscaleError: currentJob.error_message || 'Job failed'
                            } : f
                        ));
                    }
                }
            } catch (err) {
                console.error("Polling error", err);
                clearInterval(interval);
            }
        }, 2000);
    };

    const [previewAssetId, setPreviewAssetId] = useState<string | null>(null);

    return (
        <div className="max-w-[1600px] mx-auto space-y-8 h-[calc(100vh-8rem)] flex flex-col">
            {/* Header */}
            <div className="flex items-center gap-4 flex-shrink-0">
                <div className="w-12 h-12 bg-forge-yellow/10 rounded-lg flex items-center justify-center">
                    <Scissors className="w-6 h-6 text-forge-yellow" />
                </div>
                <div>
                    <h1 className="text-2xl font-bold text-white">Frame Extractor & Upscale</h1>
                    <p className="text-gray-500">Extract frames and upscale them instantly using Topaz AI</p>
                </div>
            </div>

            <div className="flex-1 grid grid-cols-1 lg:grid-cols-4 gap-8 min-h-0">
                {/* Left Column - Video Player (2 cols) */}
                <div className="lg:col-span-2 flex flex-col gap-4 min-h-0">
                    {!asset ? (
                        <div className="flex-1 bg-forge-dark rounded-xl border border-gray-800 p-8 flex flex-col items-center justify-center">
                            <div className="w-full max-w-md">
                                <FileUpload
                                    onUpload={handleFileUpload}
                                    accept={{ 'video/*': ['.mp4', '.mov', '.webm', '.mkv'] }}
                                    label="Upload video to extract frames"
                                />
                            </div>
                        </div>
                    ) : (
                        <div className="flex flex-col gap-4 h-full">
                            <div className="bg-black rounded-xl overflow-hidden relative flex-1 min-h-[400px] flex items-center justify-center border border-gray-800">
                                <video
                                    ref={videoRef}
                                    src={`/api/v1/assets/${asset.id}/download`}
                                    className="max-h-full max-w-full"
                                    controls
                                    onTimeUpdate={handleTimeUpdate}
                                    onLoadedMetadata={handleTimeUpdate}
                                />
                            </div>

                            {/* Controls Bar */}
                            <div className="bg-forge-dark p-4 rounded-xl border border-gray-800 flex items-center justify-between gap-4">
                                <div className="text-xl font-mono text-forge-yellow font-bold">
                                    {formatTime(currentTime)}
                                </div>

                                <div className="flex-1 text-center text-gray-400 text-sm">
                                    Paused at frame
                                </div>

                                <button
                                    onClick={extractFrame}
                                    disabled={extracting}
                                    className="btn-primary flex items-center gap-2 px-6 py-3 text-lg"
                                >
                                    {extracting ? (
                                        <span className="w-5 h-5 border-2 border-black border-t-transparent rounded-full animate-spin" />
                                    ) : (
                                        <ImageIcon className="w-5 h-5" />
                                    )}
                                    Extract Frame
                                </button>
                            </div>
                        </div>
                    )}
                </div>

                {/* Middle Column - Upscale Settings (1 col) */}
                <div className="lg:col-span-1 space-y-6 overflow-y-auto">
                    <div className="bg-forge-dark p-6 rounded-xl border border-gray-800 space-y-6">
                        <h3 className="text-lg font-semibold text-white flex items-center gap-2">
                            <Settings2 className="w-5 h-5 text-forge-yellow" />
                            Upscale Settings
                        </h3>

                        {/* Scale */}
                        <div>
                            <label className="block text-sm font-medium text-gray-300 mb-2">
                                Scale Factor
                            </label>
                            <div className="flex gap-2">
                                {scaleOptions.map((option) => (
                                    <button
                                        key={option.value}
                                        onClick={() => setScale(option.value)}
                                        className={`flex-1 py-2 rounded-lg font-medium transition-colors text-sm ${scale === option.value
                                            ? 'bg-forge-yellow text-black'
                                            : 'bg-black/40 border border-gray-700 text-gray-300 hover:border-gray-600'
                                            }`}
                                    >
                                        {option.label}
                                    </button>
                                ))}
                            </div>
                        </div>

                        {/* Model */}
                        <div>
                            <label className="block text-sm font-medium text-gray-300 mb-2">
                                Upscaling Model
                            </label>
                            <select
                                value={model}
                                onChange={(e: React.ChangeEvent<HTMLSelectElement>) => setModel(e.target.value)}
                                className="select-field w-full"
                            >
                                {modelOptions.map((option) => (
                                    <option key={option.value} value={option.value}>
                                        {option.label}
                                    </option>
                                ))}
                            </select>
                        </div>

                        {/* Denoise */}
                        <div>
                            <label className="block text-sm font-medium text-gray-300 mb-2">
                                Denoise Strength: {denoiseStrength.toFixed(1)}
                            </label>
                            <input
                                type="range"
                                min={0}
                                max={1}
                                step={0.1}
                                value={denoiseStrength}
                                onChange={(e: React.ChangeEvent<HTMLInputElement>) => setDenoiseStrength(parseFloat(e.target.value))}
                                className="w-full accent-forge-yellow"
                            />
                        </div>

                        {/* Sharpen */}
                        <div>
                            <label className="block text-sm font-medium text-gray-300 mb-2">
                                Sharpen: {sharpen.toFixed(1)}
                            </label>
                            <input
                                type="range"
                                min={0}
                                max={1}
                                step={0.1}
                                value={sharpen}
                                onChange={(e: React.ChangeEvent<HTMLInputElement>) => setSharpen(parseFloat(e.target.value))}
                                className="w-full accent-forge-yellow"
                            />
                        </div>
                    </div>

                    <div className="bg-forge-dark/50 p-4 rounded-xl border border-gray-800 text-sm text-gray-400">
                        <p>Configure settings above, then click "Upscale" on any extracted frame.</p>
                    </div>
                </div>

                {/* Right Column - Extracted Frames (1 col) */}
                <div className="bg-forge-dark rounded-xl border border-gray-800 flex flex-col min-h-0 overflow-hidden lg:col-span-1">
                    <div className="p-4 border-b border-gray-800">
                        <h3 className="font-semibold text-white flex items-center gap-2">
                            <ImageIcon className="w-4 h-4 text-forge-yellow" />
                            Extracted Frames ({extractedFrames.length})
                        </h3>
                    </div>

                    <div className="flex-1 overflow-y-auto p-4 space-y-4">
                        {extractedFrames.length === 0 ? (
                            <div className="text-center text-gray-500 py-8">
                                No frames extracted yet
                            </div>
                        ) : (
                            extractedFrames.map((frame, idx) => (
                                <div key={frame.id} className="bg-forge-gray/30 rounded-lg p-3 border border-gray-700 hover:border-forge-yellow transition-colors group animate-in slide-in-from-right-4 fade-in duration-300">
                                    <div className="aspect-video bg-black/50 rounded mb-2 overflow-hidden relative">
                                        <img src={`/api/v1/assets/${frame.id}/download`} alt="frame" className="w-full h-full object-contain" />
                                        <div className="absolute top-1 right-1 bg-black/60 text-white text-xs px-1.5 py-0.5 rounded">
                                            {formatTime(frame.asset_metadata?.timestamp || 0)}
                                        </div>

                                        {/* Status Overlays */}
                                        {frame.upscaleStatus === 'processing' && (
                                            <div className="absolute inset-0 bg-black/60 flex items-center justify-center flex-col gap-2">
                                                <RefreshCw className="w-6 h-6 text-forge-yellow animate-spin" />
                                                <span className="text-xs text-forge-yellow font-medium">Upscaling...</span>
                                            </div>
                                        )}
                                        {frame.upscaleStatus === 'completed' && (
                                            <div className="absolute bottom-1 right-1 flex items-center gap-1 bg-green-500/90 text-black text-xs px-1.5 py-0.5 rounded font-bold">
                                                <Sparkles className="w-3 h-3" /> Upscaled
                                            </div>
                                        )}
                                    </div>

                                    <div className="flex gap-2">
                                        {frame.upscaleStatus === 'completed' && frame.upscaleResultId ? (
                                            <div className="flex-1 flex gap-2">
                                                <button
                                                    onClick={() => setPreviewAssetId(frame.upscaleResultId!)}
                                                    className="flex-1 bg-forge-gray text-white hover:bg-gray-600 text-xs py-1.5 rounded flex items-center justify-center gap-1 transition-colors"
                                                    title="Preview Result"
                                                >
                                                    <ImageIcon className="w-3 h-3" /> Preview
                                                </button>
                                                <button
                                                    onClick={() => window.open(`/api/v1/assets/${frame.upscaleResultId}/download`, '_blank')}
                                                    className="flex-1 bg-green-500/10 text-green-500 hover:bg-green-500 hover:text-black text-xs py-1.5 rounded flex items-center justify-center gap-1 transition-colors"
                                                    title="Download Result"
                                                >
                                                    <Download className="w-3 h-3" /> Save
                                                </button>
                                            </div>
                                        ) : (
                                            <button
                                                onClick={() => handleUpscale(frame)}
                                                disabled={frame.upscaleStatus === 'processing'}
                                                className="flex-1 bg-forge-yellow/10 text-forge-yellow hover:bg-forge-yellow hover:text-black text-xs py-1.5 rounded flex items-center justify-center gap-1 transition-colors disabled:opacity-50"
                                            >
                                                <Wand2 className="w-3 h-3" /> Upscale
                                            </button>
                                        )}

                                        <button
                                            onClick={() => window.open(`/api/v1/assets/${frame.id}/download`, '_blank')}
                                            className="p-1.5 text-gray-400 hover:text-white bg-gray-700/50 hover:bg-gray-700 rounded transition-colors"
                                            title="Download Original"
                                        >
                                            <Download className="w-3 h-3" />
                                        </button>
                                    </div>

                                    {frame.upscaleStatus === 'error' && (
                                        <div className="mt-2 text-xs text-red-400 bg-red-400/10 px-2 py-1 rounded">
                                            Error: {frame.upscaleError}
                                        </div>
                                    )}
                                </div>
                            ))
                        )}
                    </div>
                </div>
            </div>

            {/* Preview Modal */}
            {previewAssetId && (
                <div
                    className="fixed inset-0 z-50 flex items-center justify-center bg-black/90 backdrop-blur-sm p-4"
                    onClick={() => setPreviewAssetId(null)}
                >
                    <div className="relative max-w-full max-h-full" onClick={e => e.stopPropagation()}>
                        <img
                            src={`/api/v1/assets/${previewAssetId}/download`}
                            className="max-w-full max-h-[90vh] rounded-lg shadow-2xl border border-gray-800"
                            alt="Preview"
                        />
                        <button
                            onClick={() => setPreviewAssetId(null)}
                            className="absolute -top-4 -right-4 bg-white text-black p-2 rounded-full hover:bg-gray-200 transition-colors"
                        >
                            <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" /></svg>
                        </button>
                    </div>
                </div>
            )}
        </div>
    );
}
