'use client';

import React, { useEffect, useMemo, useRef, useState } from 'react';
import { Carousel } from 'antd';
import type { CarouselRef } from 'antd/es/carousel';
import { Play, Pause, FeatherIcon, MessageCircleMore, Download, ArrowDownWideNarrow, RotateCcw, Navigation, X } from 'lucide-react';
import { TaskObject } from '@/api/DTO/movieEdit';
import { ScriptRenderer } from '@/components/script-renderer/ScriptRenderer';
import ScriptLoading from './script-loading';
import { GlassIconButton } from '@/components/ui/glass-icon-button';
import { downloadVideo, downloadAllVideos, getFirstFrame } from '@/utils/tools';
import { post } from '@/api/request';
import { Drawer } from 'antd';
import { useSearchParams } from 'next/navigation';
import error_image from '@/public/assets/error.webp';
import { showDownloadOptionsModal } from './download-options-modal';
import RenderLoading from './RenderLoading';
import { useBrowserType } from '@/hooks/useBrowserType';

interface H5MediaViewerProps {
    /** 任务对象，包含各阶段数据 */
    taskObject: TaskObject;
    /** 剧本数据（仅剧本阶段使用） */
    scriptData: any;
    /** 当前索引（视频/分镜阶段用于定位） */
    currentSketchIndex: number;
    /** 选中视图：final 或 video，用于覆盖阶段渲染 */
    selectedView?: 'final' | 'video' | null;
    /** 渲染模式（仅剧本阶段透传） */
    mode: string;
    /** 以下为剧本阶段透传必需项（与桌面版保持一致） */
    setIsPauseWorkFlow: (isPause: boolean) => void;
    setAnyAttribute: any;
    isPauseWorkFlow: boolean;
    applyScript: any;
    /** Carousel 切换时回传新的索引 */
    setCurrentSketchIndex: (index: number) => void;
    /** 打开智能对话 */
    onOpenChat?: () => void;
    /** 设置聊天预览视频 */
    setVideoPreview?: (url: string, id: string) => void;
    /** 智能对话是否打开（H5可忽略布局调整，仅占位） */
    isSmartChatBoxOpen?: boolean;
    /** 失败重试生成视频 */
    onRetryVideo?: (video_id: string) => void;
    /** 切换选择视图（final 或 video） */
    onSelectView?: (view: 'final' | 'video') => void;
    /** 启用视频编辑功能 */
    enableVideoEdit?: boolean;
    /** 视频编辑描述提交回调 */
    onVideoEditDescriptionSubmit?: (editPoint: any, description: string) => void;
    /** 项目ID */
    projectId?: string;
    /** 视频比例 */
    aspectRatio?: string;
}

/**
 * 面向 H5 的媒体预览组件。
 * - 除剧本阶段外，统一使用 antd Carousel 展示 图片/视频。
 * - 视频仅保留中间的大号播放/暂停按钮。
 */
export function H5MediaViewer({
    taskObject,
    scriptData,
    currentSketchIndex,
    selectedView,
    mode,
    setIsPauseWorkFlow,
    setAnyAttribute,
    isPauseWorkFlow,
    applyScript,
    setCurrentSketchIndex,
    onOpenChat,
    setVideoPreview,
    isSmartChatBoxOpen,
    onRetryVideo,
    onSelectView,
    enableVideoEdit,
    onVideoEditDescriptionSubmit,
    projectId,
    aspectRatio
}: H5MediaViewerProps) {
    const carouselRef = useRef<CarouselRef>(null);
    const videoRefs = useRef<Array<HTMLVideoElement | null>>([]);
    const rootRef = useRef<HTMLDivElement | null>(null);
    const [activeIndex, setActiveIndex] = useState<number>(0);
    const [isPlaying, setIsPlaying] = useState<boolean>(false);
    const [isCatalogOpen, setIsCatalogOpen] = useState<boolean>(false);
    const browserType = useBrowserType();
    const searchParams = useSearchParams();
    const episodeId = searchParams.get('episodeId') || '';
    /** 解析形如 "16:9" 的比例字符串 */
    const parseAspect = (input?: string): { w: number; h: number } => {
        const parts = (typeof input === 'string' ? input.split(':') : []);
        const w = Number(parts[0]);
        const h = Number(parts[1]);
        return {
            w: Number.isFinite(w) && w > 0 ? w : 16,
            h: Number.isFinite(h) && h > 0 ? h : 9
        };
    };

    /** 根据浏览器类型获取最大高度值 */
    const maxHeight = useMemo(() => {
        switch (browserType) {
            case 'Edge':
                return 'calc(100vh - 10.5rem)';
            case 'Chrome':
                return 'calc(100vh - 17rem)';
            default:
                return 'calc(100vh - 15rem)';
        }
    }, [browserType]);

    /** 视频轮播容器高度：按 aspectRatio 计算（基于视口宽度） */
    const videoWrapperHeight = useMemo(() => {
        const { w, h } = parseAspect(aspectRatio);
        return `min(calc(100vw * ${h} / ${w}), ${maxHeight})`;
    }, [aspectRatio, maxHeight]);

    /** 图片轮播容器高度：默认 16:9 */
    const imageWrapperHeight = useMemo(() => {
        const { w, h } = parseAspect(aspectRatio);
        return `min(calc(100vw * ${h} / ${w}), ${maxHeight})`;
    }, [aspectRatio, maxHeight]);

    // 计算当前阶段类型
    const stage = (selectedView === 'final' && taskObject.final?.url)
        ? 'final_video'
        : (!['init', 'script', 'character', 'scene'].includes(taskObject.currentStage) ? 'video' : taskObject.currentStage);

    // 生成各阶段对应的 slides 数据
    const videoUrls = useMemo(() => {
        if (stage === 'final_video') {
            return taskObject.final?.url ? [taskObject.final.url] : [];
        }
        if (stage === 'video') {
            // 注意：不再过滤，保持与原始数组长度一致，避免索引错位
            const list = (taskObject.videos?.data ?? []) as Array<any>;
            return list.map(v => (Array.isArray(v?.urls) && v.urls.length > 0 ? v.urls[0] : '')) as string[];
        }
        return [];
    }, [stage, taskObject.final?.url, taskObject.videos?.data]);

    const imageItems = useMemo(() => {
        if (stage === 'scene' || stage === 'character') {
            const roles = (taskObject.roles?.data ?? []) as Array<any>;
            const scenes = (taskObject.scenes?.data ?? []) as Array<any>;
            console.log('h5-media-viewer:stage', stage);
            console.log('h5-media-viewer:roles', roles);
            console.log('h5-media-viewer:scenes', scenes);
            return [...roles, ...scenes].map(item => ({
                url: item?.url as string | undefined,
                status: item?.status as number | undefined,
                type: item?.type as string | undefined,
            }));
        }
        return [] as Array<{ url?: string; status?: number; type?: string }>;
    }, [stage, taskObject.roles?.data, taskObject.scenes?.data]);

    // 占位，避免未使用警告
    useEffect(() => {
        void isSmartChatBoxOpen;
    }, [isSmartChatBoxOpen]);

    // 同步外部索引到 Carousel
    useEffect(() => {
        if (stage === 'video' || stage === 'scene' || stage === 'character') {
            const target = Math.max(0, currentSketchIndex);
            carouselRef.current?.goTo(target, false);
            setActiveIndex(target);
            setIsPlaying(false);
            // 切换时暂停全部视频
            videoRefs.current.forEach(v => v?.pause());
        }
    }, [currentSketchIndex, stage]);

    // 阶段变更时重置状态
    useEffect(() => {
        setActiveIndex(0);
        setIsPlaying(false);
        videoRefs.current.forEach(v => v?.pause());
    }, [stage]);

    const handleAfterChange = (index: number) => {
        setActiveIndex(index);
        setIsPlaying(false);
        videoRefs.current.forEach(v => v?.pause());
        // 同步到父级索引
        if (stage === 'video' || stage === 'scene' || stage === 'character') {
            setCurrentSketchIndex(index);
        }
    };

    const togglePlay = () => {
        if (stage !== 'final_video' && stage !== 'video') return;
        const currentVideo = videoRefs.current[activeIndex] ?? null;
        if (!currentVideo) return;
        if (currentVideo.paused) {
            currentVideo.play().then(() => setIsPlaying(true)).catch(() => setIsPlaying(false));
        } else {
            currentVideo.pause();
            setIsPlaying(false);
        }
    };

    // 渲染视频 slide
    const renderVideoSlides = () => (
        <div data-alt="carousel-wrapper" className="relative w-full aspect-auto min-h-[200px] overflow-hidden rounded-lg" style={{
            height: videoWrapperHeight,
        }}>
            <Carousel
                ref={carouselRef}
                key={`h5-carousel-video-${stage}-${videoUrls.length}`}
                arrows
                dots={false}
                infinite={false}
                afterChange={handleAfterChange}
                className="absolute inset-0"
                slidesToShow={1}
                adaptiveHeight
            >
                {videoUrls.map((url, idx) => {
                    const hasUrl = typeof url === 'string' && url.length > 0;
                    const raw = (taskObject.videos?.data ?? [])[idx] as any;
                    const status = raw?.video_status;
                    const videoId = raw?.video_id as string | undefined;
                    return (
                        <div key={`h5-video-${idx}`} data-alt="video-slide" className="relative w-full h-full flex justify-center">
                            {hasUrl ? (
                                <>
                                    <video
                                        ref={(el) => (videoRefs.current[idx] = el)}
                                        className="w-full h-full object-contain [transform:translateZ(0)] [backface-visibility:hidden] [will-change:transform] bg-black cursor-pointer"
                                        src={url}
                                        preload="metadata"
                                        playsInline
                                        loop
                                        poster={getFirstFrame(url)}
                                        crossOrigin="anonymous"
                                        onClick={(e) => {
                                            e.stopPropagation();
                                            if (activeIndex === idx) togglePlay();
                                        }}
                                        onLoadedMetadata={() => {}}
                                        onPlay={() => {
                                            if (activeIndex === idx) setIsPlaying(true);
                                        }}
                                        onPause={() => {
                                            if (activeIndex === idx) setIsPlaying(false);
                                        }}
                                        onCanPlay={() => {}}
                                        onError={() => {}}
                                    />
                                    {/* 顶部功能按钮改为全局固定渲染，移出 slide */}
                                    {activeIndex === idx && !isPlaying && (
                                        <button
                                            type="button"
                                            onClick={togglePlay}
                                            data-alt="play-toggle"
                                            className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-16 h-16 rounded-full bg-black/60 text-white flex items-center justify-center active:scale-95"
                                            aria-label={'Play'}
                                        >
                                            <Play className="w-8 h-8" />
                                        </button>
                                    )}
                                </>
                            ) : (
                                <div className="w-full aspect-auto min-h-[200px] flex items-center justify-center bg-black/10 relative" data-alt="video-status" style={{
                                    height: videoWrapperHeight,
                                }}>
                                    {(status === 0 || status === 2) && (
                                        <RenderLoading
                                            recordSize="120px"
                                            loadingText={status === 0 ? 'Generating video...' : 'Generate failed'}
                                            isFailed={status === 2}
                                        />
                                    )}
                                    {/* {status === 2 && (
                                      <div className="flex flex-col items-center justify-center gap-1">
                                        <img src={error_image.src} alt="error" className="w-12 h-12" />
                                        <span className="text-[#fa485f] text-base">Generate failed</span>
                                      </div>
                                    )} */}
                                </div>
                            )}
                        </div>
                    );
                })}
            </Carousel>
        </div>
    );

    // 渲染图片 slide
    const renderImageSlides = () => (
        <div data-alt="carousel-wrapper" className="relative w-full aspect-auto min-h-[200px] overflow-hidden rounded-lg" style={{
            height: imageWrapperHeight,
        }}>
            <Carousel
                ref={carouselRef}
                key={`h5-carousel-image-${stage}-${imageItems.length}`}
                arrows
                dots={false}
                infinite={false}
                afterChange={handleAfterChange}
                className="absolute inset-0"
                slidesToShow={1}
                adaptiveHeight
            >
                {imageItems.map((item, idx) => {
                    const status = item?.status;
                    const url = item?.url;
                    const showImage = status === 1 && typeof url === 'string' && url.length > 0;
                    return (
                        <div key={`h5-image-${idx}`} data-alt="image-slide" className="relative w-full h-full flex justify-center">
                            {showImage ? (
                                <img src={url} alt="scene" className="w-full h-full object-contain" />
                            ) : (
                                <div className="w-full aspect-auto min-h-[200px] flex items-center justify-center bg-black/10 relative" data-alt="image-status" style={{
                                    height: imageWrapperHeight,
                                }}>
                                    {(status === 0 || status === 2) && (
                                        <RenderLoading
                                            recordSize="120px"
                                            loadingText={status === 0 ? (item.type === 'role' ? 'Generating role...' : 'Generating scene...') : 'Generate failed'}
                                            isFailed={status === 2}
                                        />
                                    )}
                                    {/* {status === 2 && (
                                        <div className="flex flex-col items-center justify-center gap-1">
                                            <img src={error_image.src} alt="error" className="w-12 h-12" />
                                            <span className="text-[#fa485f] text-base">Generate failed</span>
                                        </div>
                                    )} */}
                                </div>
                            )}
                        </div>
                    );
                })}
            </Carousel>
        </div>
    );

    // 剧本阶段：不使用 Carousel，沿用 ScriptRenderer
    if (stage === 'script') {
        const navItems = Array.isArray(scriptData) ? (scriptData as Array<any>).map(v => ({ id: v?.id, title: v?.title })) : [];
        const scrollToSection = (id?: string) => {
            if (!id) return;
            const el = document.getElementById(`section-${id}`);
            if (el) {
                el.scrollIntoView({ behavior: 'smooth', block: 'start' });
            }
        };
        return (
            <div data-alt="script-content" className="w-full overflow-auto"
            style={{
                height: 'calc(100vh - 10rem)'
            }}>
                {scriptData ? (
                    <>
                        <ScriptRenderer
                            data={scriptData}
                            setIsPauseWorkFlow={setIsPauseWorkFlow}
                            setAnyAttribute={setAnyAttribute}
                            isPauseWorkFlow={isPauseWorkFlow}
                            applyScript={applyScript}
                            mode={mode}
                            from="h5"
                        />
                        <button
                            type="button"
                            data-alt="open-catalog-button"
                            className="fixed bottom-[5rem] right-4 z-[60] w-12 h-12 rounded-full bg-gradient-to-br from-blue-500 to-blue-600 text-white shadow-lg flex items-center justify-center active:scale-95"
                            aria-label="open-catalog"
                            onClick={() => setIsCatalogOpen(true)}
                        >
                            <Navigation className="w-6 h-6" />
                        </button>

                        <Drawer
                            open={isCatalogOpen}
                            onClose={() => setIsCatalogOpen(false)}
                            placement="right"
                            width={'auto'}
                            mask
                            maskClosable={true}
                            maskStyle={{ backgroundColor: 'rgba(0,0,0,0)' }}
                            className="[&_.ant-drawer-content-wrapper]:w-auto [&_.ant-drawer-content-wrapper]:max-w-[80vw] backdrop-blur-lg bg-black/30 border border-white/20 shadow-xl"
                            rootClassName="outline-none"
                            data-alt="catalog-drawer"
                            closable={false}
                            style={{
                            backgroundColor: 'transparent',
                            borderBottomLeftRadius: 10,
                            borderTopLeftRadius: 10,
                            overflow: 'hidden',
                            }}
                            styles={{
                            body: {
                                backgroundColor: 'transparent',
                                padding: 0,
                            },
                            }}
                        >
                            <div className="mt-1" data-alt="catalog-list">
                                <div className="px-3 py-2 text-blue-500 text-xl font-bold">navigation</div>
                                {navItems.map(item => (
                                    <div
                                        key={item.id}
                                        role="button"
                                        tabIndex={0}
                                        onClick={() => {
                                            scrollToSection(item.id);
                                            setIsCatalogOpen(false);
                                        }}
                                        onKeyDown={(e) => {
                                            if (e.key === 'Enter') {
                                                scrollToSection(item.id);
                                                setIsCatalogOpen(false);
                                            }
                                        }}
                                        className="px-3 py-2 text-white/90 text-sm cursor-pointer transition-colors"
                                        data-alt="catalog-item"
                                    >
                                        {item.title}
                                    </div>
                                ))}
                            </div>
                        </Drawer>
                    </>
                    
                ) : (
                    <ScriptLoading isCompleted={!!scriptData} />
                )}

                
            </div>
        );
    }

    // 其他阶段：使用 Carousel
    return (
        <div ref={rootRef} data-alt="h5-media-viewer" className={`relative`} 
        style={{
            width: 'calc(100vw - 2rem)'
        }}>
            {stage === 'final_video' && videoUrls.length > 0 && renderVideoSlides()}
            {stage === 'video' && videoUrls.length > 0 && renderVideoSlides()}
            {(stage === 'scene' || stage === 'character') && imageItems.length > 0 && renderImageSlides()}
            {/* 全局固定操作区 */}
            {(stage === 'video' || stage === 'final_video') && (
              <div data-alt="global-video-actions" className="absolute top-0 right-4 z-[60] flex flex-col items-center gap-2">
                {stage === 'video' && (
                  <>
                    <GlassIconButton
                      data-alt="edit-with-chat-button"
                      className="w-8 h-8 bg-custom-purple backdrop-blur-xl rounded-full flex items-center justify-center transition-all"
                      icon={FeatherIcon}
                      size="sm"
                      aria-label="edit-with-chat"
                      onClick={() => {
                        const current = (taskObject.videos?.data ?? [])[activeIndex] as any;
                        if (current && Array.isArray(current.urls) && current.urls.length > 0 && setVideoPreview) {
                          setVideoPreview(current.urls[0], current.video_id);
                          onOpenChat && onOpenChat();
                        }
                      }}
                    />
                    <GlassIconButton
                      data-alt="download-button"
                      className="w-8 h-8 bg-gradient-to-br from-purple-500/80 to-purple-600/80 backdrop-blur-xl rounded-full flex items-center justify-center hover:from-purple-400/80 hover:to-purple-500/80 transition-all"
                      icon={Download}
                      size="sm"
                      aria-label="download"
                      onClick={() => {
                        const current = (taskObject.videos?.data ?? [])[activeIndex] as any;
                        const status = current?.video_status;
                        const hasUrl = current && Array.isArray(current.urls) && current.urls.length > 0;
                        const hasFinalVideo = taskObject.final?.url;
                        const baseVideoCount = (taskObject.videos?.data ?? []).length;
                        const totalVideos = hasFinalVideo ? baseVideoCount + 1 : baseVideoCount;
                        const isCurrentVideoFailed = status === 2;

                        showDownloadOptionsModal({
                          currentVideoIndex: hasFinalVideo ? activeIndex + 1 : activeIndex,
                          totalVideos,
                          isCurrentVideoFailed,
                          projectId: episodeId,
                          videoId: current?.video_id,
                          onDownloadCurrent: async (withWatermark: boolean) => {
                            if (!current?.video_id) return;
                            const json: any = await post('/movie/download_video', {
                              project_id: episodeId,
                              video_id: current.video_id,
                              watermark: withWatermark
                            });
                            const url = json?.data?.download_url as string | undefined;
                            if (url) await downloadVideo(url);
                          },
                          onDownloadAll: ()=>{}
                        });
                      }}
                    />
                    {(() => {
                      const status = (taskObject.videos?.data ?? [])[activeIndex]?.video_status;
                      return status === 2 ? (
                        <GlassIconButton
                          data-alt="retry-button"
                          className="w-8 h-8 bg-gradient-to-br from-purple-500/80 to-purple-600/80 backdrop-blur-xl border border-purple-400/30 rounded-full flex items-center justify-center hover:from-purple-400/80 hover:to-purple-500/80 transition-all"
                          icon={RotateCcw}
                          size="sm"
                          aria-label="retry"
                          onClick={() => {
                            const vid = (taskObject.videos?.data ?? [])[activeIndex]?.video_id;
                            if (vid && onRetryVideo) onRetryVideo(vid);
                          }}
                        />
                      ) : null;
                    })()}
                  </>
                )}
                {stage === 'final_video' && (
                  <GlassIconButton
                    data-alt="download-button"
                    className="w-8 h-8 bg-gradient-to-br from-purple-500/80 to-purple-600/80 backdrop-blur-xl rounded-full flex items-center justify-center hover:from-purple-400/80 hover:to-purple-500/80 transition-all"
                    icon={Download}
                    size="sm"
                    aria-label="download"
                    onClick={() => {
                      const totalVideos = (taskObject.videos?.data ?? []).length + 1;
                      const finalUrl = videoUrls[0];

                      showDownloadOptionsModal({
                        currentVideoIndex: 0,
                        totalVideos,
                        isCurrentVideoFailed: false,
                        isFinalStage: true,
                        projectId: episodeId,
                        onDownloadCurrent: async (withWatermark: boolean) => {
                          const json: any = await post('/movie/download_video', {
                            project_id: episodeId,
                            watermark: withWatermark
                          });
                          const url = json?.data?.download_url as string | undefined;
                          if (url) await downloadVideo(url);
                        },
                        onDownloadAll: ()=>{}
                      });
                    }}
                  />
                )}
              </div>
            )}
            <style jsx global>{`
              [data-alt='carousel-wrapper'] .slick-slide { width: 100%;display: flex !important;justify-content: center; }
              .slick-slider { height: 100% !important; }
              .slick-current > div { width: 100% !important; }
              .ant-carousel { height: 100% !important; }
              .slick-list { width: 100%;height: 100% !important;max-height: 100%; }
              .slick-track { display: flex !important; align-items: center;height: 100% !important; }
              [data-alt='carousel-wrapper'] .slick-arrow { z-index: 70 !important; }
              [data-alt='carousel-wrapper'] .slick-prev { left: 8px; }
              [data-alt='carousel-wrapper'] .slick-next { right: 8px; }
            `}</style>
        </div>
    );
}

export default H5MediaViewer;


