//
//  WalletModels.swift
//  suixinkan
//

import Foundation

/// 钱包汇总响应，用于展示累计金额、当前余额和可提现金额。
struct WalletSummaryResponse: Decodable, Equatable {
    let amountTotal: String
    let amountCurrentBalance: String
    let amountWithdrawable: String

    enum CodingKeys: String, CodingKey {
        case amountTotal = "amount_total"
        case amountCurrentBalance = "amount_current_balance"
        case amountWithdrawable = "amount_withdrawable"
    }

    /// 创建钱包汇总响应。
    init(amountTotal: String = "", amountCurrentBalance: String = "", amountWithdrawable: String = "") {
        self.amountTotal = amountTotal
        self.amountCurrentBalance = amountCurrentBalance
        self.amountWithdrawable = amountWithdrawable
    }

    /// 宽松解码钱包汇总金额字段。
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        amountTotal = try container.decodeWalletLossyString(forKey: .amountTotal)
        amountCurrentBalance = try container.decodeWalletLossyString(forKey: .amountCurrentBalance)
        amountWithdrawable = try container.decodeWalletLossyString(forKey: .amountWithdrawable)
    }
}

/// 钱包流水列表响应，用于邀请奖励记录。
struct WalletTransactionListResponse: Decodable, Equatable {
    let total: Int
    let list: [WalletTransactionItem]

    /// 创建钱包流水列表响应。
    init(total: Int = 0, list: [WalletTransactionItem] = []) {
        self.total = total
        self.list = list
    }
}

/// 钱包流水实体，表示一条收入或提现相关记录。
struct WalletTransactionItem: Decodable, Hashable {
    let id: Int
    let amount: String
    let transactionType: Int
    let transactionTypeLabel: String
    let createdAt: String
    let orderNumberSuffix: String
    let withdrawLabel: String

    enum CodingKeys: String, CodingKey {
        case id
        case amount
        case transactionType = "transaction_type"
        case transactionTypeLabel = "transaction_type_label"
        case createdAt = "created_at"
        case orderNumberSuffix = "order_number_suffix"
        case withdrawLabel = "withdraw_label"
    }

    /// 创建钱包流水实体。
    init(
        id: Int,
        amount: String,
        transactionType: Int = 0,
        transactionTypeLabel: String = "",
        createdAt: String,
        orderNumberSuffix: String = "",
        withdrawLabel: String = ""
    ) {
        self.id = id
        self.amount = amount
        self.transactionType = transactionType
        self.transactionTypeLabel = transactionTypeLabel
        self.createdAt = createdAt
        self.orderNumberSuffix = orderNumberSuffix
        self.withdrawLabel = withdrawLabel
    }

    /// 宽松解码钱包流水字段。
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        id = try container.decodeWalletLossyInt(forKey: .id) ?? 0
        amount = try container.decodeWalletLossyString(forKey: .amount)
        transactionType = try container.decodeWalletLossyInt(forKey: .transactionType) ?? 0
        transactionTypeLabel = try container.decodeWalletLossyString(forKey: .transactionTypeLabel)
        createdAt = try container.decodeWalletLossyString(forKey: .createdAt)
        orderNumberSuffix = try container.decodeWalletLossyString(forKey: .orderNumberSuffix)
        withdrawLabel = try container.decodeWalletLossyString(forKey: .withdrawLabel)
    }
}

private extension KeyedDecodingContainer {
    func decodeWalletLossyString(forKey key: Key) throws -> String {
        if let value = try? decodeIfPresent(String.self, forKey: key) {
            return value
        }
        if let value = try? decodeIfPresent(Int.self, forKey: key) {
            return String(value)
        }
        if let value = try? decodeIfPresent(Double.self, forKey: key) {
            return String(value)
        }
        return ""
    }

    func decodeWalletLossyInt(forKey key: Key) throws -> Int? {
        if let value = try? decodeIfPresent(Int.self, forKey: key) {
            return value
        }
        if let value = try? decodeIfPresent(Double.self, forKey: key) {
            return Int(value)
        }
        if let value = try? decodeIfPresent(String.self, forKey: key) {
            let text = value.trimmingCharacters(in: .whitespacesAndNewlines)
            return Int(text) ?? Double(text).map(Int.init)
        }
        return nil
    }
}
