//
//  LoginViewModel.swift
//  AcaMate
//
//  Created by Sean Kim on 12/14/24.
//

import SwiftUI
import Combine

class LoginViewModel: ObservableObject {
    private let appVM: AppViewModel
    
    private var cancellables = Set<AnyCancellable>()
    
    //    @Published var toggleLoading: Bool = false
    //    @Published var pathName: PathName = .NONE
    
    @UserDefault(key: "token", defaultValue: "accToken") var accToken
    @UserDefault(key: "refresh", defaultValue: "refreshToken") var refresh
    @UserDefault(key: "header", defaultValue: "headerValue") var headerValue
    
    @Published var devId: String = ""
    
    var bidArray: [String] = []
    
    
    init(_ appVM: AppViewModel) {
        self.appVM = appVM
    }
    
    func loginAction(type: SNSLoginType) {
        appVM.isLoading = true
        let acctype: String = type == .Apple ? "ST00": (type == .Kakao ? "ST01" : "ST02")
        LoginController().login(type, devId)
            .flatMap{ snsId in
                self.appVM.apiManager.loadAPIData(
                    APIRequest(path: "/api/v1/in/user/login",
                               headers: [API_HEADER : self.headerValue],
                               parameters: [
                                "acctype": acctype,
                                "snsId": "\(snsId.snsId)"
                               ],
                               decoding: APIResponse<User_Token>.self))
                .map { response in
                    return (snsId: snsId.snsId, response: response)
                }
            }
            .sink { [weak self] completion  in
                guard let self = self else { return }
                // API 자체적으로 내보내는 에러는 여기서 거를거고
                switch completion {
                case .failure(let error):
                    self.appVM.isLoading = false
                    printLog("\(error)")
                case .finished:
                    self.appVM.isLoading = false
                }
            } receiveValue: { [weak self] response in
                guard let self = self else { return }
                let snsId = response.snsId
                switch response.response.status.code {
                case .success(let code):
                    if code == "000" {
                        if let data = response.response.data,
                           let accToken = data.token,
                           let refresh = data.refresh {
                            printLog(accToken)
                            printLog(refresh)
                            
                            self.accToken = accToken
                            self.refresh = refresh
                            
                            appVM.naviState.set(act: .ADD, path: .SelectAcademy)
                            
                        }
                    } else {
                        // 회원가입 진행
                        // 여기다가 타입도 추가해야 함
                        appVM.naviState.set(act: .ADD, path: .Register(type, id: "\(snsId)"))
                    }
                case .anything(let apiCode):
                    // MARK: TO-DO
                    // 이거도 걍 에러인데? 에러 처리 로직으로 
                    printLog("\(apiCode) : 로그인 정보 없음")
                    printLog("ERROR")
                    //                    self.pathName = .Register(type, id: "\(id)")
                default:
                    // 그외에 서버에서 처리를 하다가 문제가 생겨서 발생하는 에러는 여기로 보낼거임
                    printLog("ERROR")
                }
            }
            .store(in: &cancellables)
    }
}
