//
//  WalletAPI.swift
//  suixinkan
//
//  Created by Codex on 2026/6/22.
//

import Foundation
import Observation

/// 钱包模块服务协议，定义钱包、提现、银行卡和积分接口能力。
@MainActor
protocol WalletServing {
    /// 获取钱包汇总数据。
    func walletSummary(type: Int) async throws -> WalletSummaryResponse

    /// 获取钱包收益明细分页。
    func walletEarningDetail(startDate: String, endDate: String, page: Int, pageSize: Int) async throws -> WalletEarningDetailResponse

    /// 获取提现记录分页。
    func walletWithdrawList(page: Int, pageSize: Int) async throws -> WalletWithdrawListResponse

    /// 获取提现申请所需信息。
    func withdrawInfo() async throws -> WithdrawInfoResponse

    /// 发送提现短信验证码。
    func withdrawSendSms() async throws

    /// 提交提现申请。
    func withdrawApply(amount: String, smsCode: String) async throws

    /// 获取银行卡审核和资料信息。
    func bankCardInfo() async throws -> BankCardInfoResponse

    /// 获取银行列表。
    func bankList() async throws -> BankListResponse

    /// 获取省市区列表。
    func areas() async throws -> [AreaNode]

    /// 发送银行卡设置短信验证码。
    func bankCardVerifyCode() async throws

    /// 更新银行卡资料。
    func updateBankInfo(_ request: UpdateBankInfoRequest) async throws

    /// 获取积分概览。
    func pointOverview(staffId: Int) async throws -> PointOverviewResponse

    /// 提交积分兑换申请。
    func pointWithdrawApply(points: Int, remark: String) async throws

    /// 获取积分兑换记录。
    func pointWithdrawList(status: Int?, page: Int, pageSize: Int) async throws -> PointWithdrawListResponse
}

@MainActor
@Observable
/// 钱包 API，封装个人钱包、提现、银行卡和积分兑换网络请求。
final class WalletAPI {
    @ObservationIgnored private let client: APIClient

    /// 初始化钱包 API，并注入共享网络客户端。
    init(client: APIClient) {
        self.client = client
    }

    /// 获取钱包汇总数据。
    func walletSummary(type: Int = 0) async throws -> WalletSummaryResponse {
        try await client.send(
            APIRequest(
                method: .get,
                path: "/api/yf-handset-app/photog/wallet/summary",
                queryItems: [URLQueryItem(name: "type", value: String(type))]
            )
        )
    }

    /// 获取钱包收益明细分页。
    func walletEarningDetail(startDate: String, endDate: String, page: Int, pageSize: Int) async throws -> WalletEarningDetailResponse {
        try await client.send(
            APIRequest(
                method: .get,
                path: "/api/yf-handset-app/photog/wallet/earning-detail",
                queryItems: [
                    URLQueryItem(name: "start_date", value: startDate),
                    URLQueryItem(name: "end_date", value: endDate),
                    URLQueryItem(name: "page", value: String(page)),
                    URLQueryItem(name: "page_size", value: String(pageSize))
                ]
            )
        )
    }

    /// 获取提现记录分页。
    func walletWithdrawList(page: Int, pageSize: Int) async throws -> WalletWithdrawListResponse {
        try await client.send(
            APIRequest(
                method: .get,
                path: "/api/yf-handset-app/photog/wallet/withdraw-list",
                queryItems: [
                    URLQueryItem(name: "page", value: String(page)),
                    URLQueryItem(name: "page_size", value: String(pageSize))
                ]
            )
        )
    }

    /// 获取提现申请所需信息。
    func withdrawInfo() async throws -> WithdrawInfoResponse {
        try await client.send(
            APIRequest(method: .get, path: "/api/yf-handset-app/photog/wallet/withdraw-info")
        )
    }

    /// 发送提现短信验证码。
    func withdrawSendSms() async throws {
        let _: EmptyPayload = try await client.send(
            APIRequest(method: .post, path: "/api/yf-handset-app/photog/wallet/withdraw-send-sms", body: EmptyPayload())
        )
    }

    /// 提交提现申请。
    func withdrawApply(amount: String, smsCode: String) async throws {
        let _: EmptyPayload = try await client.send(
            APIRequest(
                method: .post,
                path: "/api/yf-handset-app/photog/wallet/withdraw-apply",
                body: WithdrawApplyRequest(amount: amount, smsCode: smsCode)
            )
        )
    }

    /// 获取银行卡审核和资料信息。
    func bankCardInfo() async throws -> BankCardInfoResponse {
        try await client.send(
            APIRequest(method: .get, path: "/api/yf-handset-app/photog/wallet/bank-card/info")
        )
    }

    /// 获取银行列表。
    func bankList() async throws -> BankListResponse {
        try await client.send(
            APIRequest(method: .get, path: "/api/yf-handset-app/photog/wallet/bank-list")
        )
    }

    /// 获取省市区列表。
    func areas() async throws -> [AreaNode] {
        try await client.send(
            APIRequest(method: .get, path: "/api/app/config/areas")
        )
    }

    /// 发送银行卡设置短信验证码。
    func bankCardVerifyCode() async throws {
        let _: EmptyPayload = try await client.send(
            APIRequest(method: .post, path: "/api/yf-handset-app/photog/wallet/bank-card/sms-verify-code", body: EmptyPayload())
        )
    }

    /// 更新银行卡资料。
    func updateBankInfo(_ request: UpdateBankInfoRequest) async throws {
        let _: EmptyPayload = try await client.send(
            APIRequest(method: .post, path: "/api/yf-handset-app/photog/wallet/bank-card/update", body: request)
        )
    }

    /// 获取积分概览。
    func pointOverview(staffId: Int) async throws -> PointOverviewResponse {
        try await client.send(
            APIRequest(
                method: .post,
                path: "/api/yf-handset-app/photog/point/overview",
                queryItems: [URLQueryItem(name: "staff_id", value: String(staffId))],
                body: EmptyPayload()
            )
        )
    }

    /// 提交积分兑换申请。
    func pointWithdrawApply(points: Int, remark: String = "积分提现申请") async throws {
        let _: EmptyPayload = try await client.send(
            APIRequest(
                method: .post,
                path: "/api/yf-handset-app/photog/point/withdraw/apply",
                body: PointWithdrawApplyRequest(points: points, remark: remark)
            )
        )
    }

    /// 获取积分兑换记录。
    func pointWithdrawList(status: Int? = nil, page: Int, pageSize: Int) async throws -> PointWithdrawListResponse {
        try await client.send(
            APIRequest(
                method: .post,
                path: "/api/yf-handset-app/photog/point/withdraw/list",
                body: PointWithdrawListRequest(status: status, page: page, pageSize: pageSize)
            )
        )
    }
}

extension WalletAPI: WalletServing {}
