import { FC, useState, useCallback, useRef } from "react";
import {
    Box, Button, VStack, HStack, Text, Input, Alert, AlertIcon,
    Progress, Select, Badge, Icon, useColorModeValue
} from "@chakra-ui/react";
import { FiUpload, FiDownload, FiFile } from "react-icons/fi";
import { languageList, LangCode } from "lingva-scraper";
import dynamic from "next/dynamic";
import type { ColumnSelection, SheetColumnInfo } from "./ColumnSelector";

const ColumnSelector = dynamic(() => import("./ColumnSelector"), { ssr: false });

const SUPPORTED_TYPES = [".pdf", ".docx", ".xlsx", ".xls", ".csv"];
const TABULAR_TYPES = [".xlsx", ".xls", ".csv"];

type Stage = "idle" | "columns" | "translating" | "done" | "error";

const DocumentTranslator: FC = () => {
    const [file, setFile] = useState<File | null>(null);
    const [target, setTarget] = useState<string>("en");
    const [stage, setStage] = useState<Stage>("idle");
    const [progress, setProgress] = useState(0);
    const [errorMsg, setErrorMsg] = useState("");
    const [sheetColumns, setSheetColumns] = useState<SheetColumnInfo[]>([]);
    const [columnSelections, setColumnSelections] = useState<ColumnSelection[]>([]);
    const [downloadUrl, setDownloadUrl] = useState<string | null>(null);
    const [downloadName, setDownloadName] = useState("");
    const fileInputRef = useRef<HTMLInputElement>(null);
    const borderColor = useColorModeValue("gray.200", "gray.600");
    const dropBg = useColorModeValue("gray.50", "gray.700");

    const isTabular = file
        ? TABULAR_TYPES.some(e => file.name.toLowerCase().endsWith(e))
        : false;

    const handleFile = useCallback(async (f: File) => {
        setFile(f);
        setStage("idle");
        setErrorMsg("");
        setDownloadUrl(null);
        setSheetColumns([]);

        const ext = "." + f.name.split(".").pop()?.toLowerCase();
        if (!SUPPORTED_TYPES.includes(ext)) {
            setErrorMsg(`Unsupported file type. Supported: ${SUPPORTED_TYPES.join(", ")}`);
            setStage("error");
            return;
        }

        if (TABULAR_TYPES.includes(ext)) {
            // Fetch column info
            const fd = new FormData();
            fd.append("file", f);
            fd.append("action", "getColumns");
            try {
                const res = await fetch("/api/translate/document", { method: "POST", body: fd });
                if (res.ok) {
                    const data = await res.json();
                    setSheetColumns(data.columns ?? []);
                    setStage("columns");
                } else {
                    const e = await res.json();
                    setErrorMsg(e.error ?? "Failed to read columns");
                    setStage("error");
                }
            } catch {
                setErrorMsg("Network error reading file columns");
                setStage("error");
            }
        }
    }, []);

    const onDrop = useCallback((e: React.DragEvent) => {
        e.preventDefault();
        const f = e.dataTransfer.files[0];
        if (f) handleFile(f);
    }, [handleFile]);

    const translate = useCallback(async () => {
        if (!file) return;
        setStage("translating");
        setProgress(10);
        setErrorMsg("");

        const fd = new FormData();
        fd.append("file", file);
        fd.append("targetLanguage", target);
        fd.append("action", "translate");
        if (columnSelections.length > 0) {
            fd.append("columnSelections", JSON.stringify(columnSelections));
        }

        try {
            setProgress(30);
            const res = await fetch("/api/translate/document", { method: "POST", body: fd });
            setProgress(90);

            if (!res.ok) {
                const e = await res.json().catch(() => ({ error: "Translation failed" }));
                setErrorMsg(e.error ?? "Translation failed");
                setStage("error");
                return;
            }

            const blob = await res.blob();
            const ext = "." + file.name.split(".").pop()!;
            const outName = file.name.replace(ext, `_${target}${ext}`);
            const url = URL.createObjectURL(blob);
            setDownloadUrl(url);
            setDownloadName(outName);
            setProgress(100);
            setStage("done");
        } catch (err) {
            setErrorMsg("Network error during translation");
            setStage("error");
        }
    }, [file, target, columnSelections]);

    const reset = () => {
        setFile(null);
        setStage("idle");
        setErrorMsg("");
        setDownloadUrl(null);
        setSheetColumns([]);
        if (fileInputRef.current) fileInputRef.current.value = "";
    };

    const targetLangs = Object.entries(languageList.target) as [LangCode<"target">, string][];

    return (
        <VStack w="full" spacing={4} px={[8, null, 24, 40]}>
            {/* Drop Zone */}
            <Box
                w="full"
                border="2px dashed"
                borderColor={file ? "lingva.400" : borderColor}
                borderRadius="xl"
                p={8}
                bg={dropBg}
                textAlign="center"
                cursor="pointer"
                onDrop={onDrop}
                onDragOver={(e: React.DragEvent) => e.preventDefault()}
                onClick={() => fileInputRef.current?.click()}
                _hover={{ borderColor: "lingva.400" }}
                transition="border-color 0.2s"
            >
                <Input
                    ref={fileInputRef}
                    type="file"
                    display="none"
                    accept=".pdf,.docx,.xlsx,.xls,.csv"
                    onChange={(e: React.ChangeEvent<HTMLInputElement>) => { const f = e.target.files?.[0]; if (f) handleFile(f); }}
                />
                {file ? (
                    <VStack spacing={1}>
                        <Icon as={FiFile} boxSize={8} color="lingva.400" />
                        <Text fontWeight="semibold">{file.name}</Text>
                        <Text fontSize="sm" color="gray.500">
                            {(file.size / 1024 / 1024).toFixed(2)} MB
                        </Text>
                    </VStack>
                ) : (
                    <VStack spacing={2}>
                        <Icon as={FiUpload} boxSize={10} color="gray.400" />
                        <Text fontWeight="semibold">Drop file here or click to upload</Text>
                        <Text fontSize="sm" color="gray.500">
                            Supported: PDF, Word (.docx), Excel (.xlsx, .xls), CSV
                        </Text>
                    </VStack>
                )}
            </Box>

            {/* Target language + controls */}
            {file && stage !== "error" && (
                <HStack w="full" spacing={3}>
                    <Box flex={1}>
                        <Select
                            value={target}
                            onChange={(e: React.ChangeEvent<HTMLSelectElement>) => setTarget(e.target.value)}
                            size="md"
                            aria-label="Target language"
                        >
                            {targetLangs.map(([code, name]) => (
                                <option key={code} value={code}>{name}</option>
                            ))}
                        </Select>
                    </Box>
                    <Button
                        colorScheme="lingva"
                        leftIcon={<Icon as={FiFile} />}
                        onClick={translate}
                        isLoading={stage === "translating"}
                        loadingText="Translating…"
                        isDisabled={stage === "translating" || (isTabular && stage !== "columns" && stage !== "idle")}
                    >
                        Translate
                    </Button>
                    <Button variant="ghost" size="sm" onClick={reset}>Reset</Button>
                </HStack>
            )}

            {/* Column selector for Excel/CSV */}
            {stage === "columns" && sheetColumns.length > 0 && (
                <ColumnSelector
                    sheetColumns={sheetColumns}
                    onChange={setColumnSelections}
                />
            )}

            {/* Progress */}
            {stage === "translating" && (
                <Box w="full">
                    <Progress value={progress} colorScheme="lingva" borderRadius="full" hasStripe isAnimated />
                    <Text fontSize="sm" textAlign="center" mt={1} color="gray.500">
                        Translating… this may take a moment for large documents.
                    </Text>
                </Box>
            )}

            {/* Download */}
            {stage === "done" && downloadUrl && (
                <Alert status="success" borderRadius="md">
                    <AlertIcon />
                    <HStack justify="space-between" w="full">
                        <Text fontSize="sm">Translation complete!</Text>
                        <Button
                            as="a"
                            href={downloadUrl}
                            download={downloadName}
                            size="sm"
                            colorScheme="lingva"
                            leftIcon={<Icon as={FiDownload} />}
                        >
                            Download
                        </Button>
                    </HStack>
                </Alert>
            )}

            {/* Error */}
            {stage === "error" && errorMsg && (
                <Alert status="error" borderRadius="md">
                    <AlertIcon />
                    <VStack align="start" spacing={1}>
                        <Text fontSize="sm">{errorMsg}</Text>
                        <Button size="xs" variant="link" colorScheme="red" onClick={reset}>Try again</Button>
                    </VStack>
                </Alert>
            )}

            <Text fontSize="xs" color="gray.400" textAlign="center">
                Document translation requires Replicate AI to be enabled in the admin settings.
                <br />
                PDF formatting is best-effort; Excel and Word formatting is fully preserved.
            </Text>
        </VStack>
    );
};

export default DocumentTranslator;
