//
//  LNHttpManager+GameMate.swift
//  Lanu
//
//  Created by OneeChan on 2025/11/20.
//

import Foundation

private let kNetPath_GameMate_Category = "/biz/categorys"
private let kNetPath_GameMate_Filter = "/biz/categorys/filter/condition"

private let kNetPath_GameMate_List = "/skill/list"

private let kNetPath_GameMate_Skills = "/skill/user/goods"
private let kNetPath_GameMate_Info = "/user/playmate/info"
private let kNetPath_GameMate_Skill_Detail = "/skill/detail"
private let kNetPath_GameMate_Score = "/user/playmate/charmStar"
private let kNetPath_GameMate_Skill_Comment = "/skill/goods/comments"

private let kNetPath_GameMate_Search = "/playmate/search"
private let kNetPath_GameMate_Mixed_Search = "/search/mixed/list"

private let kNetPath_GameMate_Join_Infos = "/playmate/apply/curInfo"
private let kNetPath_GameMate_Join_Improve_BaseInfo = "/playmate/apply/improve/info"
private let kNetPath_GameMate_Join_Skill_Field = "/playmate/apply/setp3/info/get"
private let kNetPath_GameMate_Join_Apply = "/playmate/apply/submit"

private let kNetPath_GameMate_Settings_Info = "/playmate/business/info"
private let kNetPath_GameMate_Settings_Switch = "/playmate/business/switch"
private let kNetPath_GameMate_Settings_Time = "/playmate/getAcceptSet"
private let kNetPath_GameMate_Settings_Time_Set = "/playmate/acceptSet"
private let kNetPath_GameMate_Settings_Skill_List = "/playmate/skill/list"

private let kNetPath_GameMate_Visitors = "/user/visitors"

private let kNetPath_GameMate_Skill_Switch = "/skill/switch/get"
private let kNetPath_GameMate_Skill_Switch_Set = "/skill/switch/set"
private let kNetPath_GameMate_Skill_Fields = "/skill/editInfo/get"
private let kNetPath_GameMate_Skill_Edit = "/skill/edit"

private let kNetPath_GameMate_AutoReply_Switch = "/playmate/autoWelcome/switch"
private let kNetPath_GameMate_AutoReply_List = "/playmate/welcome/list"
private let kNetPath_GameMate_AutoReply_Create = "/playmate/welcome/create"
private let kNetPath_GameMate_AutoReply_Update = "/playmate/welcome/update"
private let kNetPath_GameMate_AutoReply_Delete = "/playmate/welcome/delete"
private let kNetPath_GameMate_AutoReply_Send = "/playmate/welcome/trigger"
private let kNetPath_GameMate_AutoReply_Mark = "/playmate/push/chat/submit"
private let kNetPath_GameMate_AutoReply_Query = "/playmate/push/chat/quota"

private let kNetPath_GameMate_PotentialUsers_List = "/playmate/push/list"

enum LNGameMateAgeRange: Int, CaseIterable {
    case all = -1
    case `15-25` = 0
    case `25-35` = 1
    case `>35` = 2
    
    var text: String {
        switch self {
        case .`15-25`: "15-25"
        case .`25-35`: "25-35"
        case .`>35`: "> 35"
        case .all: .init(key: "A00008")
        }
    }
}

enum LNGameMatePriceRange: Int, CaseIterable {
    case all = -1
    case `0-10` = 0
    case `10-15` = 1
    case `15-25` = 2
    case `25-50` = 3
    case `>50` = 4
    
    var text: String {
        switch self {
        case .`0-10`: "0-10"
        case .`10-15`: "10-15"
        case .`15-25`: "15-25"
        case .`25-50`: "25-50"
        case .`>50`: "> 50"
        case .all: .init(key: "A00008")
        }
    }
}

enum LNGameMateGenderRange: Int, CaseIterable {
    case all = -1
    case unknow = 0
    case male = 1
    case female = 2
    
    var text: String {
        switch self {
        case .all: .init(key: "A00008")
        case .unknow: .init(key: "A00016")
        case .male: .init(key: "A00014")
        case .female: .init(key: "A00015")
        }
    }
}

class LNGameMateFilter {
    var ageRange: LNGameMateAgeRange = .all
    var gender: LNGameMateGenderRange = .all
    var areCode: String = ""
    var sortByStar: LNSortedType = .none
    var sortByPrice: LNSortedType = .none
    var priceRange: LNGameMatePriceRange = .all
    var categoryFilters: [(fieldCode: String, filterValues: [String])] = []
}

// MARK: 获取大品类类型
extension LNHttpManager {
    func getGameCategories(completion: @escaping(LNGameTypeListResponse?, LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_Category, completion: completion)
    }
    
    func getGameFilterConfig(completion: @escaping (LNSkillFilterConfigList?, LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_Filter, completion: completion)
    }
}

// MARK: 获取陪玩师列表
extension LNHttpManager {
    func getGameMateList(
        topCategory: String, category: String?,
        filter: LNGameMateFilter, size: Int, next: String,
        completion: @escaping (LNGameMateListResponse?, LNHttpError?) -> Void)
    {
        var params: [String: Any] = [
            "firstCode": topCategory,
            "code": category ?? "",
            "ageRange": filter.ageRange.rawValue,
            "gender": filter.gender.rawValue,
            "areCode": filter.areCode,
            "sortByStar": filter.sortByStar.rawValue,
            "sortByPrice": filter.sortByPrice.rawValue,
            "priceRange": filter.priceRange.rawValue,
            "page": [
                "size": size,
                "next": next
            ]
        ]
        var filters: [[String: any Encodable]] = []
        for item in filter.categoryFilters {
            filters.append([
                "fieldCode": item.fieldCode,
                "filterValues": item.filterValues
            ])
        }
        if !filters.isEmpty {
            params["categoryFilters"] = filters
        }
        post(path: kNetPath_GameMate_List,
             params: params,
             completion: completion)
    }
}

// MARK: 陪玩师信息查询
extension LNHttpManager {
    func getUserSkills(uid: String, completion: @escaping (LNGameMateSkillListResponse?, LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_Skills, params: ["id": uid], completion: completion)
    }
    
    func getGameMateInfo(uid: String, completion: @escaping (LNGameMateInfoResponse?, LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_Info, params: ["id": uid], completion: completion)
    }
    
    func getSkillDetail(skillId: String, completion: @escaping (LNGameMateSkillDetailVO?, LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_Skill_Detail, params: ["id": skillId], completion: completion)
    }
    
    func searchGameMate(keyword: String, size: Int,
                        next: String,
                        completion: @escaping (LNGameMateSearchResponse?, LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_Search, params: [
            "keyword": keyword,
            "page": [
                "size": size,
                "next": next
            ]
        ], completion: completion)
    }
    
    func mixSearch(keyword: String, completion: @escaping (LNMixSearchResponse?, LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_Mixed_Search, params: [
            "keyword": keyword
        ], completion: completion)
    }
    
    func scoreGameMate(uid: String, score: Int, completion: @escaping (LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_Score, params: [
            "userNo": uid,
            "star": score
        ], completion: completion)
    }
    
    func getSkillCommentList(id: String, size: Int, next: String,
                             completion: @escaping (LNSkillCommentListResponse?, LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_Skill_Comment, params: [
            "skillId": id,
            "page": [
                "size": size,
                "next": next
            ]
        ], completion: completion)
    }
}

// MARK: 陪玩师申请
class LNCreateSkillFieldInfo {
    var fieldCode: String = ""
    var value: (any Encodable)?
    var duration: Int?
}

class LNCreateSkillFieldsInfo {
    var bizCategoryCode = ""
    var fields: [LNCreateSkillFieldInfo] = []
}

extension LNHttpManager {
    func getJoinGameMateInfo(completion: @escaping (LNJoinUsInputInfosResponse?, LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_Join_Infos, completion: completion)
    }
    
    func setJoinGameMateBaseInfo(
        info: LNJoinUsBaseInfoVO,
        completion: @escaping (LNJoinUsInputInfosResponse?, LNHttpError?) -> Void)
    {
        post(path: kNetPath_GameMate_Join_Improve_BaseInfo, params: [
            "avatar": info.avatar,
            "nickname": info.nickname,
            "gender": info.gender.rawValue,
            "birthday": info.birthday,
            "intro": info.intro,
            "languageCodes": info.languageCodes
        ], completion: completion)
    }
    
    func getCreateSkillFields(id: String, completion: @escaping (LNCreateSkillInputFieldsVO?, LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_Join_Skill_Field, params: [
            "id": id
        ], completion: completion)
    }
    
    func createSkill(info: LNCreateSkillFieldsInfo, completion: @escaping (LNHttpError?) -> Void) {
        var fields: [[String: Any]] = []
        info.fields.forEach {
            var field: [String: Any] = [
                "fieldCode": $0.fieldCode,
                "value": $0.value as Any
            ]
            if let duration = $0.duration {
                field["duration"] = duration
            }
            
            fields.append(field)
        }
        post(path: kNetPath_GameMate_Join_Apply, params: [
            "bizCategoryCode": info.bizCategoryCode,
            "fields": fields
        ], completion: completion)
    }
}

// MARK: 陪玩师管理
class LNEditSkillFieldsInfo {
    var skillId: String = ""
    var apply: Bool = false
    var fields: [LNCreateSkillFieldInfo] = []
}

extension LNHttpManager {
    func getGameMateManagerInfo(completion: @escaping (LNGameMateManagerInfo?, LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_Settings_Info, completion: completion)
    }
    
    func enableGameMate(open: Bool, completion: @escaping (LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_Settings_Switch, params: [
            "open": open
        ], completion: completion)
    }
    
    func getOrderAccetpConfig(completion: @escaping (LNOrderAcceptConfig?, LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_Settings_Time, completion: completion)
    }
    
    func setOrderAcceptConfig(config: LNOrderAcceptConfig, completion: @escaping (LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_Settings_Time_Set, params: [
            "timeRange": config.timeRange,
            "weekNums": config.weekNums.compactMap({ $0.rawValue })
        ], completion: completion)
    }
    
    func getMySkillList(onlyOpen: Bool = false, completion: @escaping (LNMySkillListResponse?, LNHttpError?) -> Void) {
        var params: [String: Any] = [:]
        if onlyOpen {
            params["open"] = true
        }
        post(path: kNetPath_GameMate_Settings_Skill_List, params: params, completion: completion)
    }
    
    func enableSkill(skillId: String, open: Bool, mainSkill: Bool? = nil, completion: @escaping (LNHttpError?) -> Void) {
        var params: [String: (any Encodable)] = [
            "skillId": skillId,
            "open": open
        ]
        if let mainSkill {
            params["mainSkill"] = mainSkill
        }
        post(path: kNetPath_GameMate_Skill_Switch_Set, params: params, completion: completion)
    }
    
    func getVisitorsList(next: String, size: Int, completion: @escaping (LNVisitorsListResponse?, LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_Visitors, params: [
            "size": size,
            "next": next
        ], completion: completion)
    }
    
    func getSkillEditFields(id: String, completion: @escaping (LNSkillEditFieldsResponse?, LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_Skill_Fields, params: [
            "id": id
        ], completion: completion)
    }
    
    func commitSkillEdit(info: LNEditSkillFieldsInfo, completion: @escaping (LNHttpError?) -> Void) {
        var fields: [[String: Any]] = []
        info.fields.forEach {
            var field: [String: Any] = [
                "fieldCode": $0.fieldCode,
                "value": $0.value as Any
            ]
            if let duration = $0.duration {
                field["duration"] = duration
            }
            
            fields.append(field)
        }
        
        post(path: kNetPath_GameMate_Skill_Edit, params: [
            "skillId": info.skillId,
            "apply": info.apply,
            "fields": fields
        ], completion: completion)
    }
    
    func getSkillSwitchInfo(id: String, completion: @escaping (LNSkillSwitchResponse?, LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_Skill_Switch, params: [
            "id": id
        ], completion: completion)
    }
}
 
// MARK: 欢迎语(自动回复)
extension LNHttpManager {
    func enableAutoReplay(on: Bool, completion: @escaping (LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_AutoReply_Switch, params: [
            "autoWelcomeOpen": on
        ], completion: completion)
    }
    
    func getAutoReplayList(completion: @escaping (LNAutoReplyResponse?, LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_AutoReply_List, completion: completion)
    }
    
    func deleteAutoReplay(id: String, completion: @escaping (LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_AutoReply_Delete, params: [
            "id": id
        ], completion: completion)
    }
    
    func createAutoReplay(item: LNAutoReplyVO, completion: @escaping (LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_AutoReply_Create, params: [
            "type": item.type.rawValue,
            "textContent": item.textContent,
            "voiceUrl": item.voiceUrl,
            "voiceDuration": item.voiceDuration
        ], completion: completion)
    }
    
    func updateAutoReplay(item: LNAutoReplyVO, completion: @escaping (LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_AutoReply_Update, params: [
            "id": item.id,
            "type": item.type.rawValue,
            "textContent": item.textContent,
            "voiceUrl": item.voiceUrl,
            "voiceDuration": item.voiceDuration
        ], completion: completion)
    }
    
    func triggerAutoReplayIfNeed(uid: String, completion: @escaping (LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_AutoReply_Send, params: [
            "playmateUserNo": uid
        ], completion: completion)
    }
    
    func markUseAutoReplay(uid: String, completion: @escaping (LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_AutoReply_Mark, params: [
            "userNo": uid
        ], completion: completion)
    }
    
    func fetchAutoReplyQuota(uid: String, completion: @escaping (LNAutoReplyQuotaResponse?, LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_AutoReply_Query, params: [
            "userNo": uid
        ], completion: completion)
    }
}

// MARK: 潜在用户
extension LNHttpManager {
    func getPotentialUsers(completion: @escaping (LNPotentialUsersResponse?, LNHttpError?) -> Void) {
        post(path: kNetPath_GameMate_PotentialUsers_List, completion: completion)
    }
}
