"use client";

import {useCallback, useEffect, useState} from "react";
import {
    AlertCircle,
    Apple,
    CheckCircle2,
    Cookie,
    Download,
    Heart,
    Languages,
    Loader2,
    Settings,
    Sun,
    Upload,
    UtensilsCrossed,
    X,
} from "lucide-react";
import Link from 'next/link'
import {Button} from "@/components/ui/button";
import {
    AlignmentType,
    Document,
    Packer,
    PageOrientation,
    Paragraph,
    Table,
    TableCell,
    TableLayoutType,
    TableRow,
    TextRun,
    WidthType
} from "docx";

// 餐食类型
enum MealTypeCode {
    BREAKFAST = "breakfast",
    FRUIT = "fruit",
    LUNCH = "lunch",
    SNACK = "snack",
    SPECIAL = "special",
}

// 语言名称项
interface LangName {
    zh: string;
    en?: string;
}

// 单个菜品
interface Dish {
    id?: string;
    name: LangName;
    translated?: boolean; // 是否已翻译
}

// 单日食谱
interface DailyMeal {
    dayCode: number;
    mealCode: MealTypeCode;
    dishList: Dish[];
}

// 一周食谱
interface WeeklyMenu {
    menuId?: string;
    weekNumber?: string;
    title: LangName;
    days: { code: number; name: LangName }[];
    mealCategories: { code: MealTypeCode; name: LangName; sort: number }[];
    meals: DailyMeal[];
}

// 餐食类型配置
const MEAL_TYPES = [
    {code: MealTypeCode.BREAKFAST, label: "早餐", icon: Sun},
    {code: MealTypeCode.FRUIT, label: "水果餐", icon: Apple},
    {code: MealTypeCode.LUNCH, label: "中餐", icon: UtensilsCrossed},
    {code: MealTypeCode.SNACK, label: "午点", icon: Cookie},
    {code: MealTypeCode.SPECIAL, label: "体弱儿餐", icon: Heart},
];

type UploadState = "idle" | "uploading" | "parsing" | "done" | "error";
type TranslateState = "idle" | "translating" | "done";

/**
 * 头部组件
 * */
function HarderCompose() {
    return (
        <div className="mx-auto max-w-6xl px-4 py-6">
            <div className="flex items-center justify-between">
                <div className="flex items-center gap-3">
                    <div
                        className="flex h-10 w-10 items-center justify-center rounded-xl bg-primary text-primary-foreground">
                        <UtensilsCrossed className="h-5 w-5"/>
                    </div>
                    <div>
                        <h1 className="text-xl font-semibold">食谱翻译工具</h1>
                        <p className="text-sm text-muted-foreground">Word 文档解析 · 智能翻译</p>
                    </div>
                </div>
                <Link href="/settings">
                    <Button variant="ghost" size="sm">
                        <Settings className="h-4 w-4"/>
                    </Button>
                </Link>
            </div>
        </div>
    );
}

export default function RecipeTranslationPage() {
    const [uploadState, setUploadState] = useState<UploadState>("idle");
    const [translateState, setTranslateState] = useState<TranslateState>("idle");
    const [selectedMealType, setSelectedMealType] = useState<MealTypeCode | "all">("all");
    const [data, setData] = useState<WeeklyMenu | null>(null);
    const [error, setError] = useState<string | null>(null);
    const [fileName, setFileName] = useState<string>("");
    const [exportConfig, setExportConfig] = useState<{
        untranslatedColor: string;
        secondPageHeader: boolean;
        orientation: "portrait" | "landscape";
    }>({
        untranslatedColor: "CC0000",
        secondPageHeader: false,
        orientation: "landscape",
    });

    // 加载导出配置
    useEffect(() => {
        fetch("/api/config")
            .then((res) => res.json())
            .then((result) => {
                if (result.success && result.data?.export) {
                    setExportConfig({
                        untranslatedColor: result.data.export.untranslatedColor || "CC0000",
                        secondPageHeader: result.data.export.secondPageHeader || false,
                        orientation: result.data.export.orientation || "landscape",
                    });
                }
            })
            .catch(console.error);
    }, []);

    // 收集所有未翻译的菜品名称
    const getAllDishNames = useCallback((menu: WeeklyMenu): string[] => {
        const names: string[] = [];
        for (const meal of menu.meals) {
            for (const dish of meal.dishList) {
                if (dish.name.zh && !dish.name.en) {
                    names.push(dish.name.zh);
                }
            }
        }
        return [...new Set(names)]; // 去重
    }, []);

    // 批量翻译
    const handleTranslateAll = useCallback(async () => {
        if (!data) return;

        const dishNames = getAllDishNames(data);
        if (dishNames.length === 0) {
            alert("所有菜品都已翻译！");
            return;
        }

        setTranslateState("translating");

        try {
            const response = await fetch("/api/translate", {
                method: "POST",
                headers: {"Content-Type": "application/json"},
                body: JSON.stringify({names: dishNames}),
            });

            const result = await response.json();

            if (!response.ok) {
                throw new Error(result.error || "翻译失败");
            }

            // 更新 data 中的翻译结果
            const translations = result.translations as Record<string, string | null>;

            setData((prevData) => {
                if (!prevData) return null;

                const newMeals = prevData.meals.map((meal) => ({
                    ...meal,
                    dishList: meal.dishList.map((dish) => {
                        const translation = dish.name.zh ? translations[dish.name.zh] : null;
                        if (translation) {
                            return {
                                ...dish,
                                name: {...dish.name, en: translation},
                                translated: true,
                            };
                        }
                        return {
                            ...dish,
                            translated: dish.translated || false,
                        };
                    }),
                }));

                return {...prevData, meals: newMeals};
            });

            setTranslateState("done");
        } catch (err) {
            console.error("Translation error:", err);
            alert("翻译失败，请重试");
            setTranslateState("idle");
        }
    }, [data, getAllDishNames]);

    // 导出 Word 文档
    const handleExport = useCallback(async () => {
        if (!data) return;

        try {
            // 1. 先调用 API 获取最新导出设置
            const configResponse = await fetch("/api/config");
            const configResult = await configResponse.json();
            const exportConfig = configResult.success ? configResult.data?.export : {
                untranslatedColor: "CC0000",
                orientation: "landscape",
                secondPageHeader: false,
            };
            const {untranslatedColor, orientation, secondPageHeader} = exportConfig;

            // 2. 收集所有需要翻译的内容（星期、餐食类型、菜品）
            const allNames: string[] = [];

            // 收集星期名称（使用实际数据中的星期）
            for (const day of data.days) {
                if (day.name.zh) {
                    allNames.push(day.name.zh);
                }
            }

            // 收集餐食类型名称
            for (const meal of MEAL_TYPES) {
                allNames.push(meal.label);
            }

            // 收集所有菜品名称（去重）
            const dishNamesSet = new Set<string>();
            for (const meal of data.meals) {
                for (const dish of meal.dishList) {
                    if (dish.name.zh) {
                        dishNamesSet.add(dish.name.zh);
                    }
                }
            }
            allNames.push(...dishNamesSet);

            // 2. 调用翻译 API
            const response = await fetch("/api/translate", {
                method: "POST",
                headers: {"Content-Type": "application/json"},
                body: JSON.stringify({names: [...new Set(allNames)]}),
            });

            const result = await response.json();

            if (!response.ok) {
                throw new Error(result.error || "翻译失败");
            }

            const translations = result.translations as Record<string, string | null>;

            // 3. 构建翻译映射函数
            const t = (zh: string): string => translations[zh] || "";

            // 4. 构建表格数据 - 生成所有数据行
            const dayRows: TableRow[] = [];
            for (const day of data.days) {
                const dayZh = day.name.zh || "";
                const dayEn = t(dayZh) || translations[dayZh] || "";
                const dayCells: TableCell[] = [
                    new TableCell({
                        children: [
                            new Paragraph({children: [new TextRun({text: dayZh})]}),
                            dayEn ? new Paragraph({
                                children: [new TextRun({
                                    text: dayEn,
                                    color: "666666",
                                    size: 18
                                })]
                            }) : null,
                        ].filter((p): p is Paragraph => p !== null) as unknown as Paragraph[],
                    }),
                ];

                for (const mealType of MEAL_TYPES) {
                    const mealData = data.meals.find(
                        (m) => m.dayCode === day.code && m.mealCode === mealType.code
                    );

                    const cellContent: Paragraph[] = [];

                    if (mealData?.dishList && mealData.dishList.length > 0) {
                        for (const dish of mealData.dishList) {
                            const zhText = dish.name.zh;
                            const enText = dish.name.en || t(zhText);

                            if (enText) {
                                cellContent.push(
                                    new Paragraph({
                                        children: [new TextRun({text: zhText})],
                                    })
                                );
                                cellContent.push(
                                    new Paragraph({
                                        children: [new TextRun({text: enText, color: "666666", size: 18})],
                                    })
                                );
                            } else {
                                cellContent.push(
                                    new Paragraph({
                                        children: [new TextRun({text: zhText, color: untranslatedColor})],
                                    })
                                );
                            }
                        }
                    } else {
                        cellContent.push(new Paragraph({children: [new TextRun({text: "—", color: "999999"})]}));
                    }

                    dayCells.push(
                        new TableCell({
                            children: cellContent,
                        })
                    );
                }

                dayRows.push(new TableRow({children: dayCells}));
            }

            // 5. 创建文档 - 根据设置选择页面方向和分页
            const isLandscape = orientation === "landscape";
            const pageWidth = isLandscape ? 11906 : 16838;
            const pageHeight = isLandscape ? 16838 : 11906;

            // 构建表头行
            const buildHeaderRow = (): TableRow => {
                const headerCells: TableCell[] = [];
                headerCells.push(
                    new TableCell({
                        children: [
                            new Paragraph({children: [new TextRun({text: "星期 / Week", bold: true})]}),
                        ].filter((p): p is Paragraph => p !== null) as unknown as Paragraph[],
                        width: {size: 12, type: WidthType.PERCENTAGE},
                    }),
                );
                for (const mealType of MEAL_TYPES) {
                    const zhText = mealType.label;
                    const enText = t(zhText);
                    headerCells.push(
                        new TableCell({
                            children: [
                                new Paragraph({children: [new TextRun({text: enText || zhText, bold: true})]}),
                                enText ? new Paragraph({
                                    children: [new TextRun({
                                        text: zhText,
                                        color: "666666",
                                        size: 18
                                    })]
                                }) : null,
                            ].filter((p): p is Paragraph => p !== null) as unknown as Paragraph[],
                            width: {size: 17.6, type: WidthType.PERCENTAGE},
                        })
                    );
                }
                return new TableRow({ children: headerCells, tableHeader: false });
            };

            // 构建 sections
            const sections: any[] = [];

            sections.push({
                properties: {
                    page: {
                        size: {
                            orientation: isLandscape ? PageOrientation.LANDSCAPE : PageOrientation.PORTRAIT,
                            width: pageWidth,
                            height: pageHeight,
                        },
                        margin: {
                            top: 700,
                            bottom: 700,
                            left: 900,
                            right: 900,
                        },
                    },
                },
                children: [
                    new Paragraph({
                        children: [
                            new TextRun({
                                text: `${fileName || data.title?.zh || "食谱翻译"}`,
                                bold: true,
                                size: 32,
                            }),
                        ],
                        alignment: AlignmentType.CENTER,
                    }),
                    new Paragraph({children: []}),
                    new Table({
                        rows: [buildHeaderRow(), ...dayRows],
                        width: {size: 100, type: WidthType.PERCENTAGE},
                        layout: TableLayoutType.FIXED
                    }),
                ],
            });

            const doc = new Document({
                sections,
            });

            // 6. 生成并下载
            const blob = await Packer.toBlob(doc);
            const url = URL.createObjectURL(blob);
            const link = document.createElement("a");
            link.href = url;
            link.download = `${fileName || data.title?.zh || "食谱翻译"}.docx`;
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            URL.revokeObjectURL(url);
        } catch (err) {
            console.error("Export error:", err);
            alert("导出失败，请重试");
        }
    }, [data, fileName]);

    const handleFileUpload = useCallback(
        async (file: File) => {
            if (!file.name.endsWith(".docx")) {
                setError("请上传 .docx 格式的文件");
                setUploadState("error");
                return;
            }

            setUploadState("uploading");
            setError(null);
            setTranslateState("idle");

            try {
                const formData = new FormData();
                formData.append("file", file);

                setUploadState("parsing");

                const response = await fetch("/api/recipe", {
                    method: "POST",
                    body: formData,
                });

                const result = await response.json();

                if (!response.ok) {
                    throw new Error(result.error || "解析失败");
                }

                setData(result.data);
                setFileName(file.name.replace(/\.docx$/i, ""));
                setUploadState("done");
            } catch (err) {
                setError(err instanceof Error ? err.message : "文件解析失败，请检查格式");
                setUploadState("error");
            }
        },
        []
    );

    const handleDrop = useCallback(
        (e: React.DragEvent) => {
            e.preventDefault();
            const file = e.dataTransfer.files[0];
            if (file) handleFileUpload(file);
        },
        [handleFileUpload]
    );

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

    const reset = () => {
        setUploadState("idle");
        setData(null);
        setError(null);
        setTranslateState("idle");
        setSelectedMealType("all");
        setFileName("");
    };

    // 统计翻译状态
    const untranslatedCount = data ? getAllDishNames(data).length : 0;

    return (
        <div className="min-h-screen bg-background">
            {/* Header */}
            <header className="border-b bg-card">
                <HarderCompose/>
            </header>

            <main className="mx-auto max-w-6xl px-4 py-8">
                {/* Upload Zone - 闲置状态 */}
                {uploadState === "idle" && (
                    <div
                        onDrop={handleDrop}
                        onDragOver={(e) => e.preventDefault()}
                        className="group relative flex flex-col items-center justify-center rounded-2xl border-2 border-dashed border-border bg-muted/50 p-12 transition-all hover:border-primary/50 hover:bg-muted"
                    >
                        <input
                            type="file"
                            accept=".docx"
                            onChange={handleFileInput}
                            className="absolute inset-0 cursor-pointer opacity-0"
                        />
                        <div
                            className="mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-primary/10 text-primary transition-transform group-hover:scale-110">
                            <Upload className="h-8 w-8"/>
                        </div>
                        <p className="mb-1 text-lg font-medium">点击上传或拖拽 Word 文档</p>
                        <p className="text-sm text-muted-foreground">支持 .docx 格式</p>
                    </div>
                )}

                {/* 上传中 */}
                {uploadState === "uploading" && (
                    <div className="flex flex-col items-center justify-center rounded-2xl border bg-card p-12">
                        <Loader2 className="mb-4 h-12 w-12 animate-spin text-primary"/>
                        <p className="text-lg font-medium">正在上传文件...</p>
                    </div>
                )}

                {/* 解析中 */}
                {uploadState === "parsing" && (
                    <div className="flex flex-col items-center justify-center rounded-2xl border bg-card p-12">
                        <Loader2 className="mb-4 h-12 w-12 animate-spin text-primary"/>
                        <p className="text-lg font-medium">正在解析文档内容...</p>
                        <p className="mt-1 text-sm text-muted-foreground">提取文字并识别食谱结构</p>
                    </div>
                )}

                {/* 错误状态 */}
                {uploadState === "error" && (
                    <div
                        className="flex flex-col items-center justify-center rounded-2xl border border-destructive/50 bg-destructive/5 p-12">
                        <div
                            className="mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-destructive/10 text-destructive">
                            <X className="h-8 w-8"/>
                        </div>
                        <p className="mb-1 text-lg font-medium text-destructive">{error}</p>
                        <Button variant="outline" onClick={reset} className="mt-4">
                            重新上传
                        </Button>
                    </div>
                )}

                {/* 完成 - 显示结果 */}
                {uploadState === "done" && data && (
                    <div className="space-y-6">
                        {/* 成功提示 + 重新上传 */}
                        <div className="flex items-center justify-between rounded-xl border bg-card p-4">
                            <div className="flex items-center gap-3">
                                <CheckCircle2 className="h-5 w-5 text-primary"/>
                                <span className="font-medium">文档解析完成</span>
                                <span className="text-sm text-muted-foreground">{data.title.zh}</span>
                                {untranslatedCount > 0 && translateState !== "translating" && (
                                    <span className="flex items-center gap-1 text-sm text-destructive">
                    <AlertCircle className="h-4 w-4"/>
                                        {untranslatedCount} 个菜品待翻译
                  </span>
                                )}
                                {translateState === "done" && untranslatedCount === 0 && (
                                    <span className="flex items-center gap-1 text-sm text-green-600">
                    <CheckCircle2 className="h-4 w-4"/>
                    全部翻译完成
                  </span>
                                )}
                            </div>
                            <Button variant="outline" size="sm" onClick={reset}>
                                重新上传
                            </Button>
                        </div>

                        {/* 餐食类型筛选 + 操作按钮 */}
                        <div className="flex flex-wrap items-center justify-between gap-4">
                            {/* 餐食类型筛选 */}
                            <div className="flex flex-wrap gap-2">
                                <Button
                                    variant={selectedMealType === "all" ? "default" : "outline"}
                                    size="sm"
                                    onClick={() => setSelectedMealType("all")}
                                >
                                    全部
                                </Button>
                                {MEAL_TYPES.map((meal) => {
                                    const Icon = meal.icon;
                                    return (
                                        <Button
                                            key={meal.code}
                                            variant={selectedMealType === meal.code ? "default" : "outline"}
                                            size="sm"
                                            onClick={() => setSelectedMealType(meal.code)}
                                            className="gap-1.5"
                                        >
                                            <Icon className="h-4 w-4"/>
                                            {meal.label}
                                        </Button>
                                    );
                                })}
                            </div>

                            {/* 操作按钮 */}
                            <div className="flex items-center gap-3">
                                <Button
                                    variant="outline"
                                    className="gap-2"
                                    onClick={handleExport}
                                    disabled={translateState === "translating"}
                                >
                                    <Download className="h-4 w-4"/>
                                    导出翻译结果
                                </Button>
                                <Button
                                    className="gap-2"
                                    onClick={handleTranslateAll}
                                    disabled={translateState === "translating" || untranslatedCount === 0}
                                >
                                    {translateState === "translating" ? (
                                        <>
                                            <Loader2 className="h-4 w-4 animate-spin"/>
                                            翻译中...
                                        </>
                                    ) : (
                                        <>
                                            <Languages className="h-4 w-4"/>
                                            一键翻译全部
                                            {untranslatedCount > 0 &&
                                                <span className="text-xs opacity-70">({untranslatedCount})</span>}
                                        </>
                                    )}
                                </Button>
                            </div>
                        </div>

                        {/* 食谱表格 */}
                        <div className="overflow-x-auto rounded-xl border bg-card">
                            <table className="w-full text-sm">
                                <thead>
                                <tr className="border-b bg-muted/50">
                                    <th className="min-w-[80px] px-4 py-3 text-left font-medium">星期</th>
                                    {selectedMealType === "all"
                                        ? MEAL_TYPES.map((meal) => {
                                            const Icon = meal.icon;
                                            return (
                                                <th key={meal.code} className="px-4 py-3 text-center font-medium">
                                                    <div className="flex items-center justify-center gap-1.5">
                                                        <Icon className="h-4 w-4"/>
                                                        {meal.label}
                                                    </div>
                                                </th>
                                            );
                                        })
                                        : MEAL_TYPES.find((m) => m.code === selectedMealType)?.icon && (
                                        <th className="px-4 py-3 text-center font-medium">
                                            {
                                                MEAL_TYPES.find((m) => m.code === selectedMealType)
                                                    ?.label
                                            }
                                        </th>
                                    )}
                                </tr>
                                </thead>
                                <tbody>
                                {data.days.map((day) => (
                                    <tr key={day.code} className="border-b last:border-0 hover:bg-muted/30">
                                        <td className="px-4 py-3 font-medium">{day.name.zh}</td>
                                        {selectedMealType === "all" ? (
                                            MEAL_TYPES.map((meal) => {
                                                const mealData = data.meals.find(
                                                    (m) => m.dayCode === day.code && m.mealCode === meal.code
                                                );
                                                return (
                                                    <td key={meal.code} className="px-4 py-3">
                                                        <div className="flex flex-col gap-1">
                                                            {mealData?.dishList.length ? (
                                                                mealData.dishList.map((dish) => (
                                                                    <div
                                                                        key={dish.id}
                                                                        className="flex flex-col gap-0.5 text-sm"
                                                                    >
<span style={{color: dish.name.en ? undefined : exportConfig.untranslatedColor}}>
                                         {dish.name.zh}
                                       </span>
                                                                        {dish.name.en && (
                                                                            <span
                                                                                className="text-xs text-muted-foreground">
                                          {dish.name.en}
                                        </span>
                                                                        )}
                                                                    </div>
                                                                ))
                                                            ) : (
                                                                <span className="text-muted-foreground">—</span>
                                                            )}
                                                        </div>
                                                    </td>
                                                );
                                            })
                                        ) : (
                                            <td className="px-4 py-3">
                                                {(() => {
                                                    const mealData = data.meals.find(
                                                        (m) =>
                                                            m.dayCode === day.code &&
                                                            m.mealCode === selectedMealType
                                                    );
                                                    return mealData?.dishList.length ? (
                                                        <div className="flex flex-col gap-1">
                                                            {mealData.dishList.map((dish) => (
                                                                <div
                                                                    key={dish.id}
                                                                    className="flex flex-col gap-0.5"
                                                                >
                                    <span style={{color: dish.name.en ? undefined : exportConfig.untranslatedColor}}>
                                      {dish.name.zh}
                                    </span>
                                                                    {dish.name.en && (
                                                                        <span className="text-xs text-muted-foreground">
                                        {dish.name.en}
                                      </span>
                                                                    )}
                                                                </div>
                                                            ))}
                                                        </div>
                                                    ) : (
                                                        <span className="text-muted-foreground">—</span>
                                                    );
                                                })()}
                                            </td>
                                        )}
                                    </tr>
                                ))}
                                </tbody>
                            </table>
                        </div>
                    </div>
                )}
            </main>
        </div>
    );
}
