import { useState, useEffect, useCallback } from "react";
import api from "@/shared/api/axios";
import { ApiResponse, unwrap } from "@/shared/api/types";
import { toast } from "sonner";

export type ExtractionStep = "config" | "processing" | "result";
export type InputTab = "file" | "url";

const VALID_FILE_TYPES = [".mp4", ".mov", ".avi", ".mp3", ".wav", ".m4a"];

interface UseScriptExtractionOptions {
    isOpen: boolean;
}

export const useScriptExtraction = ({ isOpen }: UseScriptExtractionOptions) => {
    const [isLoading, setIsLoading] = useState(false);
    const [script, setScript] = useState("");
    const [error, setError] = useState<string | null>(null);
    const [step, setStep] = useState<ExtractionStep>("config");
    const [dragActive, setDragActive] = useState(false);
    const [selectedFile, setSelectedFile] = useState<File | null>(null);
    const [activeTab, setActiveTab] = useState<InputTab>("url");
    const [inputUrl, setInputUrl] = useState("");

    // Reset state when modal opens
    useEffect(() => {
        if (isOpen) {
            setStep("config");
            setScript("");
            setError(null);
            setIsLoading(false);
            setSelectedFile(null);
            setInputUrl("");
            setActiveTab("url");
        }
    }, [isOpen]);

    const handleDrag = useCallback((e: React.DragEvent) => {
        e.preventDefault();
        e.stopPropagation();
        if (e.type === "dragenter" || e.type === "dragover") {
            setDragActive(true);
        } else if (e.type === "dragleave") {
            setDragActive(false);
        }
    }, []);

    const handleFile = useCallback((file: File) => {
        const ext = file.name.toLowerCase().slice(file.name.lastIndexOf("."));
        if (!VALID_FILE_TYPES.includes(ext)) {
            setError(`不支持的文件格式 ${ext}，请上传视频或音频文件`);
            return;
        }
        setSelectedFile(file);
        setError(null);
    }, []);

    const handleDrop = useCallback(
        (e: React.DragEvent) => {
            e.preventDefault();
            e.stopPropagation();
            setDragActive(false);
            if (e.dataTransfer.files?.[0]) {
                handleFile(e.dataTransfer.files[0]);
            }
        },
        [handleFile]
    );

    const handleFileChange = useCallback(
        (e: React.ChangeEvent<HTMLInputElement>) => {
            if (e.target.files?.[0]) {
                handleFile(e.target.files[0]);
            }
        },
        [handleFile]
    );

    const handleExtract = useCallback(async () => {
        if (activeTab === "file" && !selectedFile) {
            setError("请先上传文件");
            return;
        }
        if (activeTab === "url" && !inputUrl.trim()) {
            setError("请先输入视频链接");
            return;
        }

        setIsLoading(true);
        setStep("processing");
        setError(null);

        try {
            const formData = new FormData();
            if (activeTab === "file" && selectedFile) {
                formData.append("file", selectedFile);
            } else if (activeTab === "url") {
                formData.append("url", inputUrl.trim());
            }
            formData.append("rewrite", "false");

            const { data: res } = await api.post<
                ApiResponse<{ original_script: string }>
            >("/api/tools/extract-script", formData, {
                headers: { "Content-Type": "multipart/form-data" },
                timeout: 180000, // 3 minutes timeout
            });

            const payload = unwrap(res);
            setScript(payload.original_script);
            setStep("result");
        } catch (err: unknown) {
            console.error(err);
            const axiosErr = err as {
                response?: { data?: { message?: string } };
                message?: string;
            };
            const msg =
                axiosErr.response?.data?.message || axiosErr.message || "请求失败";
            setError(msg);
            setStep("config");
        } finally {
            setIsLoading(false);
        }
    }, [activeTab, selectedFile, inputUrl]);

    const copyToClipboard = useCallback((text: string) => {
        if (navigator.clipboard && window.isSecureContext) {
            navigator.clipboard
                .writeText(text)
                .then(() => {
                    toast.success("已复制到剪贴板");
                })
                .catch(() => {
                    fallbackCopyTextToClipboard(text);
                });
        } else {
            fallbackCopyTextToClipboard(text);
        }
    }, []);

    const fallbackCopyTextToClipboard = (text: string) => {
        const textArea = document.createElement("textarea");
        textArea.value = text;
        textArea.style.top = "0";
        textArea.style.left = "0";
        textArea.style.position = "fixed";
        textArea.style.opacity = "0";

        document.body.appendChild(textArea);
        textArea.focus();
        textArea.select();

        try {
            const successful = document.execCommand("copy");
            if (successful) {
                toast.success("已复制到剪贴板");
            } else {
                toast.error("复制失败，请手动复制");
            }
        } catch {
            toast.error("复制失败，请手动复制");
        }

        document.body.removeChild(textArea);
    };

    const resetToConfig = useCallback(() => {
        setStep("config");
    }, []);

    const clearSelectedFile = useCallback(() => {
        setSelectedFile(null);
    }, []);

    const clearInputUrl = useCallback(() => {
        setInputUrl("");
    }, []);

    return {
        // State
        isLoading,
        script,
        error,
        step,
        dragActive,
        selectedFile,
        activeTab,
        inputUrl,
        // Setters
        setActiveTab,
        setInputUrl,
        // Handlers
        handleDrag,
        handleDrop,
        handleFileChange,
        handleExtract,
        copyToClipboard,
        resetToConfig,
        clearSelectedFile,
        clearInputUrl,
    };
};
