//
//  InviteModels.swift
//  suixinkan
//

import Foundation

/// 邀请信息响应实体，表示邀请码、邀请链接和规则文案。
struct InviteInfoResponse: Decodable, Equatable {
    let enableInvite: Bool
    let inviteCode: String
    let inviteUrl: String
    let description: [String]

    enum CodingKeys: String, CodingKey {
        case enableInvite = "enable_invite"
        case inviteCode = "invite_code"
        case inviteUrl = "invite_url"
        case description
    }

    /// 创建邀请信息响应实体。
    init(enableInvite: Bool, inviteCode: String, inviteUrl: String, description: [String]) {
        self.enableInvite = enableInvite
        self.inviteCode = inviteCode
        self.inviteUrl = inviteUrl
        self.description = description
    }

    /// 宽松解码邀请信息，兼容后端字符串/数字/布尔混用。
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        enableInvite = try container.decodeInviteLossyBool(forKey: .enableInvite) ?? true
        inviteCode = try container.decodeInviteLossyString(forKey: .inviteCode)
        inviteUrl = try container.decodeInviteLossyString(forKey: .inviteUrl)
        description = (try? container.decodeIfPresent([String].self, forKey: .description)) ?? []
    }
}

/// 邀请用户实体，表示邀请记录里的摄影师。
struct InviteUserItem: Decodable, Hashable {
    let id: Int
    let realName: String
    let phone: String
    let avatar: String
    let createdAt: String
    let inviteLevel: Int

    enum CodingKeys: String, CodingKey {
        case id
        case realName = "real_name"
        case phone
        case avatar
        case createdAt = "created_at"
        case inviteLevel = "invite_level"
    }

    /// 创建邀请用户实体。
    init(id: Int, realName: String, phone: String, avatar: String, createdAt: String, inviteLevel: Int) {
        self.id = id
        self.realName = realName
        self.phone = phone
        self.avatar = avatar
        self.createdAt = createdAt
        self.inviteLevel = inviteLevel
    }

    /// 宽松解码邀请用户字段。
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        id = try container.decodeInviteLossyInt(forKey: .id) ?? 0
        realName = try container.decodeInviteLossyString(forKey: .realName)
        phone = try container.decodeInviteLossyString(forKey: .phone)
        avatar = try container.decodeInviteLossyString(forKey: .avatar)
        createdAt = try container.decodeInviteLossyString(forKey: .createdAt)
        inviteLevel = try container.decodeInviteLossyInt(forKey: .inviteLevel) ?? 1
    }
}

/// 邀请记录分段类型。
enum InviteRecordTab: Int, CaseIterable, Equatable {
    case invite = 0
    case reward = 1

    /// 分段标题。
    var title: String {
        switch self {
        case .invite:
            return "邀请记录"
        case .reward:
            return "奖励记录"
        }
    }
}

/// 邀请记录行展示实体。
struct InviteDisplayRow: Hashable {
    let id: String
    let title: String
    let phone: String
    let avatar: String
    let time: String
    let inviteLevel: Int

    /// 邀请层级文案。
    var levelText: String {
        inviteLevel == 1 ? "一级" : "二级"
    }

    /// 邀请层级是否为一级。
    var isPrimaryLevel: Bool {
        inviteLevel == 1
    }

    /// 头像缺省显示文字。
    var avatarPlaceholder: String {
        if let first = title.first {
            return String(first)
        }
        if let first = phone.first {
            return String(first)
        }
        return "?"
    }
}

private extension KeyedDecodingContainer {
    func decodeInviteLossyString(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)
        }
        if let value = try? decodeIfPresent(Bool.self, forKey: key) {
            return value ? "1" : "0"
        }
        return ""
    }

    func decodeInviteLossyInt(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
    }

    func decodeInviteLossyBool(forKey key: Key) throws -> Bool? {
        if let value = try? decodeIfPresent(Bool.self, forKey: key) {
            return value
        }
        if let value = try? decodeIfPresent(Int.self, forKey: key) {
            return value != 0
        }
        if let value = try? decodeIfPresent(String.self, forKey: key) {
            let text = value.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
            if ["1", "true", "yes"].contains(text) { return true }
            if ["0", "false", "no"].contains(text) { return false }
        }
        return nil
    }
}
