//
//  UserCore.swift

//
//  Created by Leon on 2025/7/12.
//

import Foundation
import NIMSDK

typealias UserInfoUpdatedClosure = ((_ result: Bool) -> Void)

let UDTokenKey = "UDTokenKey"
let UDUserInfoKey = "UDUserInfoKey"

@objcMembers class UserCore: NSObject {
    public static let shared = UserCore()
    
    @Published private(set) var user: User?
    private(set) var token: String = ""
    
    override init() {
        super.init()

        NotificationCenter.default.addObserver(self, selector: #selector(notiLoginSuccess), name: AppNotificationName.userLoginSuccess.notificationName, object: nil)
    }
    
    // MARK: - public

    public func isLogin() -> Bool {
//        #warning("test")
//        return true
        return token.count > 0
    }
    
    public func isSelf(id: Int?) -> Bool{
        guard let uid = user?.userId, let fromUid = id else { return false }
        return uid == fromUid
    }
    
    public func refreshUserInfo(block: UserInfoUpdatedClosure?) {
        let tokenNow = token
        guard tokenNow.count > 0 else {
            block?(false)
            dlog("⚠️ token is nil, cannot load user info")
            return
        }
        
        UserProvider.request(.userInfoSelfGet, modelType: User.self) {[weak self] result in
            switch result {
            case let .success(model):
                if model != nil {
                    self?.updateLocalUser(userNew: model)
                    block?(true)
                    NotificationCenter.post(name: .userInfoUpdated, object: nil, userInfo: nil)
                } else {
                    block?(false)
                }
                
            case let .failure(error):
                dlog("refresh user info error: \(error)")
                block?(false)
                print(error)
            }
        }
    }
    
    @discardableResult
    public func checkUserLoginIfNotPushUserToLogin() -> Bool {
        if isLogin() {
            return true
        }

        NotificationCenter.post(name: .presentSignInVc, object: nil, userInfo: nil)
        return false
    }
    
    // MARK: - Core
    public func autoLoginTry() {
        if let dict: String = UserDefaults.standard.object(forKey: UDUserInfoKey) as? String {
            dlog("👩👩 userInfo restore from UD: \(dict)")
            if let userNow = CodableHelper.decode(User.self, from: dict){//User.deserialize(from: dict).
                user = userNow
            }
        }

        if let tokenUD = UserDefaults.standard.string(forKey: UDTokenKey), tokenUD.count > 0 {
            dlog("🔥 user token: \r\(tokenUD)")
            token = tokenUD

            refreshUserInfo {[weak self] result in
                if result {
                    dlog("👩自动用户登录OK \(tokenUD)")
                    if let cpUserInfo = self?.user?.cpUserInfo, cpUserInfo == true{
                        AppRouter.goPersonalInformationFill(tokenUD)
                    }
                } else {
                    dlog("👩自动用户登录 Error")
                }
            }
            
        } else {
            dlog("👩未登录")
        }
    }
    
    @discardableResult
    public func logout() -> Bool {
        if isLogin() == false {
            return false
        }
        
        IMManager.shared.logoutIM()
        
        UIApplication.shared.applicationIconBadgeNumber = 0
        emptyToken()
        UserDefaults.standard.removeObject(forKey: UDUserInfoKey)
        UserDefaults.standard.synchronize()
        
        user = User()
        
        // #warning("登录之前的请求继续请求？")

        NotificationCenter.post(name: .userInfoUpdated, object: nil, userInfo: nil)
        NotificationCenter.post(name: .userLogout, object: nil, userInfo: nil)
        
        // 三方登出
        return true
    }
    
    // MARK: - Helper
    
    
    public func updateToken(tokenNew: String) {
        if tokenNew.count == 0 {
            assert(false)
            return
        }
        UserDefaults.standard.set(tokenNew, forKey: UDTokenKey)
        token = tokenNew
    }

    func updateLocalUser(userNew: User?) {
        user = userNew
        if let u = userNew, let validToken = u.token, validToken.isEmpty{
            token = validToken
        }
        if let jsonString = CodableHelper.encodeToJSONString(userNew){
            dlog("Save to UD user jsonstring: \(jsonString)")
            UserDefaults.standard.set(jsonString, forKey: UDUserInfoKey)
        }
        NotificationCenter.post(name: .userInfoUpdated, object: nil, userInfo: nil)
    }

    private func emptyToken() {
        token = ""
        UserDefaults.standard.removeObject(forKey: UDTokenKey)
        UserDefaults.standard.synchronize()
    }
    
    func isSelfByUid(uid: Int?) -> Bool{
        guard let userId = uid, let userLogged = self.user else {return false}
        if userLogged.userId == userId{
            return true
        }
        return false
    }
    
    // MARK: - noti

    func notiLoginSuccess() {
        // 一些只在登录后需要上传的内容：如地理信息，暂无
        // ...
    }
}
