import { useMemo, useState } from "react";
import { parseForm } from "@/shared/forms/validation";
import { usePaginatedQuery } from "@/shared/hooks/usePaginatedQuery.js";
import { useToast } from "@/shared/ui/ToastProvider.jsx";
import {
    createTaskDefinition,
    listTaskDefinitions,
    setTaskDefinitionStatus,
    updateTaskDefinition,
} from "@/features/daily-tasks/api";
import { useDailyTaskAbilities } from "@/features/daily-tasks/permissions.js";
import { dailyTaskFormSchema } from "@/features/daily-tasks/schema";
import { buildAppJumpParam } from "@/shared/app-jump/appJumpConfig.js";

const pageSize = 50;
const emptyData = { items: [], page: 1, pageSize, total: 0 };
const emptyForm = (task = {}) => {
    const actionType = task.actionType || "none";
    const appJumpParam = taskAppJumpParam(actionType, task.actionParam, task.actionPayloadJson);

    return {
        appJumpParam,
        actionParam: task.actionParam || "",
        actionType: actionType === "none" ? "none" : appJumpTypeFromParam(appJumpParam),
        category: task.category || "",
        description: task.description || "",
        effectiveFrom: msToDatetimeLocal(task.effectiveFromMs),
        effectiveTo: msToDatetimeLocal(task.effectiveToMs),
        iconUrl: task.iconUrl || "",
        metricType: task.metricType || "",
        rewardCoinAmount: task.rewardCoinAmount === 0 || task.rewardCoinAmount ? String(task.rewardCoinAmount) : "",
        sortOrder: task.sortOrder === 0 || task.sortOrder ? String(task.sortOrder) : "0",
        status: task.status || "draft",
        targetUnit: task.targetUnit || "count",
        targetValue: task.targetValue === 0 || task.targetValue ? String(task.targetValue) : "",
        taskType: task.taskType || "daily",
        title: task.title || "",
    };
};

export function useDailyTasksPage() {
    const abilities = useDailyTaskAbilities();
    const { showToast } = useToast();
    const [query, setQuery] = useState("");
    const [status, setStatus] = useState("");
    const [taskType, setTaskType] = useState("");
    const [page, setPage] = useState(1);
    const [activeAction, setActiveAction] = useState("");
    const [selectedTask, setSelectedTask] = useState(null);
    const [form, setForm] = useState(emptyForm);
    const [loadingAction, setLoadingAction] = useState("");
    const filters = useMemo(
        () => ({
            keyword: query,
            status,
            task_type: taskType,
        }),
        [query, status, taskType],
    );
    const {
        data = emptyData,
        error,
        loading,
        reload,
    } = usePaginatedQuery({
        errorMessage: "加载每日任务失败",
        fetcher: listTaskDefinitions,
        filters,
        page,
        pageSize,
        queryKey: ["daily-tasks", filters, page],
    });

    const changeQuery = resetSetter(setQuery, setPage);
    const changeStatus = resetSetter(setStatus, setPage);
    const changeTaskType = resetSetter(setTaskType, setPage);

    const resetFilters = () => {
        setQuery("");
        setStatus("");
        setTaskType("");
        setPage(1);
    };

    const openCreate = () => {
        setSelectedTask(null);
        setForm(emptyForm());
        setActiveAction("create");
    };

    const openEdit = (task) => {
        if (!task?.taskId) {
            return;
        }
        setSelectedTask(task);
        setForm(emptyForm(task));
        setActiveAction("edit");
    };

    const closeAction = () => {
        setActiveAction("");
        setSelectedTask(null);
    };

    const changeFormActionType = (actionType) => {
        const nextAppJumpParam = actionType === "app" ? buildAppJumpParam({ target: "wallet" }) : "";
        setForm((current) => ({
            ...current,
            actionParam: "",
            actionType: actionType === "app" ? "wallet" : "none",
            appJumpParam: nextAppJumpParam,
        }));
    };

    const submitTask = async (event) => {
        event.preventDefault();
        const editing = activeAction === "edit";
        if (editing && !selectedTask?.taskId) {
            return;
        }
        await runAction(editing ? "edit" : "create", editing ? "任务已更新" : "任务已创建", async () => {
            const payload = buildTaskPayload(parseForm(dailyTaskFormSchema, form));
            if (editing) {
                await updateTaskDefinition(selectedTask.taskId, payload);
            } else {
                await createTaskDefinition(payload);
            }
            closeAction();
            setForm(emptyForm());
            await reload();
        });
    };

    const toggleTask = async (task, nextEnabled = task.status !== "active") => {
        if (!abilities.canStatus || !task?.taskId || task.status === "archived") {
            return;
        }
        const nextStatus = nextEnabled ? "active" : "paused";
        if (task.status === nextStatus) {
            return;
        }
        await runAction(`status-${task.taskId}`, nextEnabled ? "任务已启用" : "任务已暂停", async () => {
            await setTaskDefinitionStatus(task.taskId, nextStatus);
            await reload();
        });
    };

    const runAction = async (action, successMessage, submitter) => {
        setLoadingAction(action);
        try {
            await submitter();
            showToast(successMessage, "success");
        } catch (err) {
            showToast(err.message || "操作失败", "error");
        } finally {
            setLoadingAction("");
        }
    };

    return {
        abilities,
        activeAction,
        appJumpTypeFromParam,
        changeFormActionType,
        changeQuery,
        changeStatus,
        changeTaskType,
        closeAction,
        data,
        error,
        form,
        loading,
        loadingAction,
        openCreate,
        openEdit,
        page,
        query,
        reload,
        resetFilters,
        selectedTask,
        setForm,
        setPage,
        status,
        submitTask,
        taskType,
        toggleTask,
    };
}

export function buildTaskPayload(form) {
    // 每日任务现在和 banner/弹窗共用公共 APP 跳转 JSON；action_type/action_param 继续回填短字段，保证旧 H5 或旧 App 只读短字段时仍能打开。
    const appJumpEnabled = form.actionType !== "none";
    const actionPayloadJSON = appJumpEnabled ? normalizedJSONObject(form.appJumpParam || defaultAppJumpParam()) : "{}";
    const actionType = appJumpEnabled ? appJumpTypeFromParam(actionPayloadJSON) : "none";

    return {
        action_param: appJumpEnabled ? actionParamFromAppJump(actionPayloadJSON, form.actionParam) : "",
        action_payload_json: actionPayloadJSON,
        action_type: actionType,
        // 人群、维度过滤、图标键已从表单移除：任务默认全量用户可见，不做事件维度限制，图标只使用上传 URL。
        audience_type: "all",
        category: hiddenTaskCategory(form),
        description: form.description.trim(),
        dimension_filter_json: "{}",
        effective_from_ms: datetimeLocalToMs(form.effectiveFrom),
        effective_to_ms: datetimeLocalToMs(form.effectiveTo),
        icon_key: "",
        icon_url: form.iconUrl.trim(),
        metric_type: form.metricType.trim(),
        reward_coin_amount: Number(form.rewardCoinAmount),
        sort_order: Number(form.sortOrder || 0),
        status: form.status,
        target_unit: form.targetUnit,
        target_value: Number(form.targetValue),
        task_type: form.taskType,
        title: form.title.trim(),
    };
}

export function defaultAppJumpParam() {
    return buildAppJumpParam({ target: "wallet" });
}

function taskAppJumpParam(actionType, actionParam, actionPayloadJSON) {
    const parsed = parseObjectJSON(actionPayloadJSON);
    if (Object.keys(parsed).length > 0 && String(parsed.type || "").trim()) {
        return JSON.stringify(parsed);
    }
    const scalarParam = String(actionParam || "").trim();

    switch (String(actionType || "").trim()) {
        case "wallet":
            return buildAppJumpParam({ target: "wallet" });
        case "room_random":
            return buildAppJumpParam({ target: "room_random" });
        case "room_random_game":
            return buildAppJumpParam({ gameId: scalarParam, target: "room_random_game" });
        case "gift_panel":
            return buildAppJumpParam({ target: "room_random_window", window: "gift_panel" });
        case "gift_panel_specific":
            return buildAppJumpParam({ giftId: scalarParam, target: "room_random_window", window: "gift_panel" });
        case "explore_game":
            return buildAppJumpParam({ gameCode: scalarParam, target: "explore_game" });
        case "room":
        case "room_window":
        case "room_random_window":
        case "room_game":
            return buildAppJumpParam({ target: actionType });
        default:
            return "";
    }
}

export function appJumpTypeFromParam(actionPayloadJSON) {
    const payload = parseObjectJSON(actionPayloadJSON);
    return String(payload.type || "").trim() || "wallet";
}

function actionParamFromAppJump(actionPayloadJSON, fallback = "") {
    const payload = parseObjectJSON(actionPayloadJSON);
    const target = String(payload.type || "").trim();

    if (target === "explore_game") {
        return String(payload.game_code || payload.gameCode || fallback || "").trim();
    }
    if (target === "room_game" || target === "room_random_game") {
        return String(payload.game_id || payload.gameId || fallback || "").trim();
    }
    if (target === "room" || target === "room_window") {
        return String(payload.room_id || payload.roomId || fallback || "").trim();
    }
    if (target === "room_window" || target === "room_random_window") {
        if (String(payload.window || "").trim() === "game_window") {
            return String(payload.game_id || payload.gameId || fallback || "").trim();
        }
        return String(payload.gift_id || payload.giftId || fallback || "").trim();
    }
    return String(fallback || "").trim();
}

function hiddenTaskCategory(form) {
    const value = String(form.category || form.metricType || form.title || "task").trim();
    return value.slice(0, 32) || "task";
}

function normalizedJSONObject(value) {
    const trimmed = String(value || "").trim();
    if (!trimmed) {
        return "{}";
    }
    try {
        const parsed = JSON.parse(trimmed);
        if (!parsed || Array.isArray(parsed) || typeof parsed !== "object") {
            return "{}";
        }
        return JSON.stringify(parsed);
    } catch {
        return trimmed;
    }
}

function parseObjectJSON(value) {
    const normalized = normalizedJSONObject(value);
    try {
        const parsed = JSON.parse(normalized);
        return parsed && !Array.isArray(parsed) && typeof parsed === "object" ? parsed : {};
    } catch {
        return {};
    }
}

function resetSetter(setter, setPage) {
    return (value) => {
        setter(value);
        setPage(1);
    };
}

function msToDatetimeLocal(value) {
    if (!value) {
        return "";
    }
    const date = new Date(Number(value));
    if (Number.isNaN(date.getTime())) {
        return "";
    }
    const local = new Date(date.getTime() - date.getTimezoneOffset() * 60000);
    return local.toISOString().slice(0, 16);
}

function datetimeLocalToMs(value) {
    const trimmed = String(value || "").trim();
    if (!trimmed) {
        return 0;
    }
    const parsed = new Date(trimmed).getTime();
    return Number.isFinite(parsed) ? parsed : 0;
}
