import { apiRequest, type QueryParams } from "@/shared/api/request";

type Raw = Record<string, unknown>;

export interface AgencyOpeningRewardDto {
    rankNo: number;
    tierNo: number;
    thresholdCoinSpent: number;
    rewardCoinAmount: number;
}

export interface AgencyOpeningCycleDto {
    cycleId: string;
    activityCode: string;
    title: string;
    status: string;
    startMs: number;
    endMs: number;
    minHostCount: number;
    maxAgencyAgeDays: number;
    rewards: AgencyOpeningRewardDto[];
    settledAtMs: number;
    createdAtMs: number;
    updatedAtMs: number;
}

export interface AgencyOpeningCyclePayload {
    cycle_id?: string;
    title: string;
    status: string;
    start_ms: number;
    end_ms: number;
    min_host_count: number;
    max_agency_age_days: number;
    rewards: Array<{ rank_no: number; tier_no?: number; threshold_coin_spent: number; reward_coin_amount: number }>;
}

export interface AgencyOpeningApplicationDto {
    applicationId: string;
    cycleId: string;
    agencyId: string;
    agencyOwnerUserId: string;
    agencyName: string;
    hostCount: number;
    agencyCreatedAtMs: number;
    status: string;
    scoreCoinAmount: number;
    rewardRankNo: number;
    rewardThresholdCoinSpent: number;
    rewardCoinAmount: number;
    walletCommandId: string;
    walletTransactionId: string;
    failureReason: string;
    appliedAtMs: number;
    approvedAtMs: number;
    scoreStartMs: number;
    scoreEndMs: number;
    reviewedByAdminId: number;
    grantedAtMs: number;
    updatedAtMs: number;
}

export function listAgencyOpeningCycles(query: QueryParams = {}) {
    return apiRequest<{ items?: Raw[]; total?: number; page?: number; page_size?: number }>(
        "/v1/admin/activity/agency-opening/cycles",
        { method: "GET", query },
    ).then((page) => ({ ...page, items: (page.items || []).map(normalizeCycle) }));
}

export function createAgencyOpeningCycle(payload: AgencyOpeningCyclePayload) {
    return apiRequest<Raw, AgencyOpeningCyclePayload>("/v1/admin/activity/agency-opening/cycles", {
        body: payload,
        method: "POST",
    }).then(normalizeCycle);
}

export function updateAgencyOpeningCycle(cycleId: string, payload: AgencyOpeningCyclePayload) {
    return apiRequest<Raw, AgencyOpeningCyclePayload>(
        `/v1/admin/activity/agency-opening/cycles/${encodeURIComponent(cycleId)}`,
        {
            body: payload,
            method: "PUT",
        },
    ).then(normalizeCycle);
}

export function setAgencyOpeningCycleStatus(cycleId: string, status: string) {
    return apiRequest<Raw, { status: string }>(
        `/v1/admin/activity/agency-opening/cycles/${encodeURIComponent(cycleId)}/status`,
        { body: { status }, method: "PATCH" },
    ).then(normalizeCycle);
}

export function listAgencyOpeningApplications(query: QueryParams = {}) {
    return apiRequest<{ items?: Raw[]; total?: number; page?: number; page_size?: number }>(
        "/v1/admin/activity/agency-opening/applications",
        { method: "GET", query },
    ).then((page) => ({ ...page, items: (page.items || []).map(normalizeApplication) }));
}

export function approveAgencyOpeningApplication(applicationId: string) {
    return apiRequest<Raw, undefined>(
        `/v1/admin/activity/agency-opening/applications/${encodeURIComponent(applicationId)}/approve`,
        { method: "POST" },
    ).then(normalizeApplication);
}

function normalizeCycle(item: Raw): AgencyOpeningCycleDto {
    return {
        cycleId: stringValue(item.cycleId ?? item.cycle_id),
        activityCode: stringValue(item.activityCode ?? item.activity_code),
        title: stringValue(item.title),
        status: stringValue(item.status),
        startMs: numberValue(item.startMs ?? item.start_ms),
        endMs: numberValue(item.endMs ?? item.end_ms),
        minHostCount: numberValue(item.minHostCount ?? item.min_host_count),
        maxAgencyAgeDays: numberValue(item.maxAgencyAgeDays ?? item.max_agency_age_days),
        rewards: Array.isArray(item.rewards) ? item.rewards.map((reward) => normalizeReward(reward as Raw)) : [],
        settledAtMs: numberValue(item.settledAtMs ?? item.settled_at_ms),
        createdAtMs: numberValue(item.createdAtMs ?? item.created_at_ms),
        updatedAtMs: numberValue(item.updatedAtMs ?? item.updated_at_ms),
    };
}

function normalizeReward(item: Raw): AgencyOpeningRewardDto {
    return {
        rankNo: numberValue(item.rankNo ?? item.rank_no),
        tierNo: numberValue(item.tierNo ?? item.tier_no ?? item.rankNo ?? item.rank_no),
        thresholdCoinSpent: numberValue(item.thresholdCoinSpent ?? item.threshold_coin_spent),
        rewardCoinAmount: numberValue(item.rewardCoinAmount ?? item.reward_coin_amount),
    };
}

function normalizeApplication(item: Raw): AgencyOpeningApplicationDto {
    return {
        applicationId: stringValue(item.applicationId ?? item.application_id),
        cycleId: stringValue(item.cycleId ?? item.cycle_id),
        agencyId: stringValue(item.agencyId ?? item.agency_id),
        agencyOwnerUserId: stringValue(item.agencyOwnerUserId ?? item.agency_owner_user_id),
        agencyName: stringValue(item.agencyName ?? item.agency_name),
        hostCount: numberValue(item.hostCount ?? item.host_count),
        agencyCreatedAtMs: numberValue(item.agencyCreatedAtMs ?? item.agency_created_at_ms),
        status: stringValue(item.status),
        scoreCoinAmount: numberValue(item.scoreCoinAmount ?? item.score_coin_amount),
        rewardRankNo: numberValue(item.rewardRankNo ?? item.reward_rank_no),
        rewardThresholdCoinSpent: numberValue(item.rewardThresholdCoinSpent ?? item.reward_threshold_coin_spent),
        rewardCoinAmount: numberValue(item.rewardCoinAmount ?? item.reward_coin_amount),
        walletCommandId: stringValue(item.walletCommandId ?? item.wallet_command_id),
        walletTransactionId: stringValue(item.walletTransactionId ?? item.wallet_transaction_id),
        failureReason: stringValue(item.failureReason ?? item.failure_reason),
        appliedAtMs: numberValue(item.appliedAtMs ?? item.applied_at_ms),
        approvedAtMs: numberValue(item.approvedAtMs ?? item.approved_at_ms),
        scoreStartMs: numberValue(item.scoreStartMs ?? item.score_start_ms),
        scoreEndMs: numberValue(item.scoreEndMs ?? item.score_end_ms),
        reviewedByAdminId: numberValue(item.reviewedByAdminId ?? item.reviewed_by_admin_id),
        grantedAtMs: numberValue(item.grantedAtMs ?? item.granted_at_ms),
        updatedAtMs: numberValue(item.updatedAtMs ?? item.updated_at_ms),
    };
}

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

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