import { apiRequest } from "@/shared/api/request";
import { API_ENDPOINTS, API_OPERATIONS, apiEndpointPath } from "@/shared/api/generated/endpoints";
import type { ApiPage, EntityId, PageQuery } from "@/shared/api/types";

export interface TaskDefinitionDto {
    taskId: string;
    taskType: string;
    category: string;
    metricType: string;
    title: string;
    description?: string;
    audienceType: string;
    iconKey: string;
    iconUrl: string;
    actionType: string;
    actionParam: string;
    actionPayloadJson: string;
    dimensionFilterJson: string;
    targetValue: number;
    targetUnit: string;
    rewardCoinAmount: number;
    status: string;
    sortOrder?: number;
    version?: number;
    effectiveFromMs?: number;
    effectiveToMs?: number;
    createdByAdminId?: number;
    updatedByAdminId?: number;
    createdAtMs?: number;
    updatedAtMs?: number;
}

export interface TaskDefinitionPayload {
    task_type: string;
    category: string;
    metric_type: string;
    title: string;
    description: string;
    audience_type: string;
    icon_key: string;
    icon_url: string;
    action_type: string;
    action_param: string;
    action_payload_json: string;
    dimension_filter_json: string;
    target_value: number;
    target_unit: string;
    reward_coin_amount: number;
    status: string;
    sort_order: number;
    effective_from_ms: number;
    effective_to_ms: number;
}

export interface TaskStatusPayload {
    status: string;
}

export function listTaskDefinitions(query: PageQuery = {}): Promise<ApiPage<TaskDefinitionDto>> {
    const endpoint = API_ENDPOINTS.listTaskDefinitions;
    return apiRequest<ApiPage<RawTaskDefinitionDto>>(apiEndpointPath(API_OPERATIONS.listTaskDefinitions), {
        method: endpoint.method,
        query,
    }).then(normalizeTaskPage);
}

export function createTaskDefinition(payload: TaskDefinitionPayload): Promise<TaskDefinitionDto> {
    const endpoint = API_ENDPOINTS.createTaskDefinition;
    return apiRequest<RawTaskDefinitionDto, TaskDefinitionPayload>(
        apiEndpointPath(API_OPERATIONS.createTaskDefinition),
        {
            body: payload,
            method: endpoint.method,
        },
    ).then(normalizeTaskDefinition);
}

export function updateTaskDefinition(taskId: EntityId, payload: TaskDefinitionPayload): Promise<TaskDefinitionDto> {
    const endpoint = API_ENDPOINTS.updateTaskDefinition;
    return apiRequest<RawTaskDefinitionDto, TaskDefinitionPayload>(
        apiEndpointPath(API_OPERATIONS.updateTaskDefinition, { task_id: taskId }),
        {
            body: payload,
            method: endpoint.method,
        },
    ).then(normalizeTaskDefinition);
}

export function setTaskDefinitionStatus(taskId: EntityId, status: string): Promise<TaskDefinitionDto> {
    const endpoint = API_ENDPOINTS.setTaskDefinitionStatus;
    return apiRequest<RawTaskDefinitionDto, TaskStatusPayload>(
        apiEndpointPath(API_OPERATIONS.setTaskDefinitionStatus, { task_id: taskId }),
        {
            body: { status },
            method: endpoint.method,
        },
    ).then(normalizeTaskDefinition);
}

type RawTaskDefinitionDto = TaskDefinitionDto & Record<string, unknown>;

function normalizeTaskPage(page: ApiPage<RawTaskDefinitionDto>): ApiPage<TaskDefinitionDto> {
    return {
        ...page,
        items: (page.items || []).map(normalizeTaskDefinition),
    };
}

function normalizeTaskDefinition(task: RawTaskDefinitionDto): TaskDefinitionDto {
    return {
        taskId: stringValue(task.taskId ?? task.task_id),
        taskType: stringValue(task.taskType ?? task.task_type),
        category: stringValue(task.category),
        metricType: stringValue(task.metricType ?? task.metric_type),
        title: stringValue(task.title),
        description: stringValue(task.description),
        audienceType: stringValue(task.audienceType ?? task.audience_type),
        iconKey: stringValue(task.iconKey ?? task.icon_key),
        iconUrl: stringValue(task.iconUrl ?? task.icon_url),
        actionType: stringValue(task.actionType ?? task.action_type),
        actionParam: stringValue(task.actionParam ?? task.action_param),
        actionPayloadJson: stringValue(task.actionPayloadJson ?? task.action_payload_json),
        dimensionFilterJson: stringValue(task.dimensionFilterJson ?? task.dimension_filter_json),
        targetValue: numberValue(task.targetValue ?? task.target_value),
        targetUnit: stringValue(task.targetUnit ?? task.target_unit),
        rewardCoinAmount: numberValue(task.rewardCoinAmount ?? task.reward_coin_amount),
        status: stringValue(task.status),
        sortOrder: numberValue(task.sortOrder ?? task.sort_order),
        version: numberValue(task.version),
        effectiveFromMs: numberValue(task.effectiveFromMs ?? task.effective_from_ms),
        effectiveToMs: numberValue(task.effectiveToMs ?? task.effective_to_ms),
        createdByAdminId: numberValue(task.createdByAdminId ?? task.created_by_admin_id),
        updatedByAdminId: numberValue(task.updatedByAdminId ?? task.updated_by_admin_id),
        createdAtMs: numberValue(task.createdAtMs ?? task.created_at_ms),
        updatedAtMs: numberValue(task.updatedAtMs ?? task.updated_at_ms),
    };
}

function stringValue(value: unknown) {
    return typeof value === "string" ? value : value === undefined || value === null ? "" : String(value);
}

function numberValue(value: unknown) {
    const number = Number(value || 0);
    return Number.isFinite(number) ? number : 0;
}
