//
//  RegisterViewModel.swift
//  AcaMate
//
//  Created by TAnine on 3/24/25.
//

import SwiftUI
import Combine

class RegisterViewModel: ObservableObject {
    private var cancellables = Set<AnyCancellable>()
    private let appVM: AppViewModel
    private let responseValue: (SNSLoginType, String)
    
    init(_ appVM: AppViewModel, type: SNSLoginType, snsID: String) {
        self.appVM = appVM
        self.responseValue = (type, snsID)
    }
    
    @UserDefault(key: "token", defaultValue: "accToken") var accToken
    @UserDefault(key: "refresh", defaultValue: "refreshToken") var refresh
    @UserDefault(key: "header", defaultValue: "headerValue") var headerValue
    @UserDefault(key: "pushToken", defaultValue: "pushToken") var pushToken
    
    let addressBtnID = UUID()
    let registerBtnID = UUID()
    let policyBtn1ID = UUID()
    
    @Published var selectDate: Date = {
        let calendar = Calendar.current
        return calendar.date(byAdding: .year, value: 0, to: Date()) ?? Date()
    }() {
        didSet {
            if selectDate != oldValue {
                changeDate = true
            }
        }
    }
    
    @Published var changeDate: Bool = false
    
    @Published var nameText: String = ""
    @Published var emailFrontText: String = ""
    @Published var emailTailText: String = ""
    @Published var numberHead: String = ""
    @Published var phoneTextSet: (String,String,String) = ("","","")
    @Published var addressText: String = "주소 입력"
    @Published var addrDetailText: String = ""
    
    let numberHeadList = ["010","011","016","017","018","019"]
    let emailTailList = ["gmail.com",
                         "naver.com",
                         "daum.net",
                         "hanmail.net",
                         "nate.com",
                         "outlook.com",
                         "icloud.com",
                         "kakao.com",
                         "yahoo.com",
                         "protonmail.com",
                         "직접 입력"]
    
    func registerUser() async {
        // 필수 값
        if nameText != "" && emailFrontText != "" && emailTailText != "" && phoneTextSet.0 != "" && phoneTextSet.1 != "" && phoneTextSet.2 != "" {
            var param: [String:Any] = [:]
            
            param["name"] = "\(nameText)"
            if changeDate { param["birth"] = "\(selectDate.convertString("yyyy-MM-dd"))"}
            param["type"] = UserType.ETC.code //"UT05" // 일반 유저
            
            if let deviceId = await UIDevice.current.identifierForVendor?.uuidString {
                param["device_id"] = "\(deviceId)"
            }
            
            param["auto_login_yn"] = false
            param["login_date"] = Date().convertString("yyyy-MM-dd'T'HH:mm:ss")
            param["push_token"] = "\(pushToken)"
            param["email"] = "\(emailFrontText)@\(emailTailText)"
            
            param["phone"] = "\(phoneTextSet.0)\(phoneTextSet.1)\(phoneTextSet.2)"
            if addressText != "주소 입력" {
                if addrDetailText == "" { param["address"] = "\(self.addressText)" }
                else { param["address"] = "\(self.addressText) \(self.addrDetailText)"}
            }
            param["location_yn"] = appVM.permissionManager.checkLocationPermission()
            param["camera_yn"] = appVM.permissionManager.checkCameraPermission()
            param["photo_yn"] = appVM.permissionManager.checkPhotoPermission()
            appVM.permissionManager.checkPushPermission(completion: { status in
                param["push_yn"] = status
            })
            
            param["market_app_yn"] = true
            param["market_sms_yn"] = true
            param["market_email_yn"] = true
            
            param["sns_id"] = self.responseValue.1
            param["sns_type"] = self.responseValue.0.rawValue
            
            
            if !changeDate || addressText == "주소 입력" {
                appVM.alertData = AlertData(
                    title: "알림",
                    body: "\(changeDate ? "":"[생일]")\((addressText != "주소 입력") ? "":"[주소]")의 내용이 없습니다.\n 계속해서 진행할까요?",
                    button: [
                        ButtonType(name: "돌아가기", role: .destructive, function: nil),
                        ButtonType(name: "가입하기", role: .cancel) {
                            self.callAPI(param)
                        }
                    ]
                )
                appVM.showAlert.toggle()
                // 넘어가는 로직도 추가
            } else {
                self.callAPI(param)
                //정상 동작
            }
            
        }
        else {
            appVM.alertData = AlertData(
                title: "경고", body: "필수 입력 사항이 누락되었습니다.",
                button: [ButtonType(name: "확인", role: .cancel, function: nil)])
            appVM.showAlert.toggle()
        }
    }
    
    private func callAPI(_ param: [String: Any]) {
        
        self.appVM.apiManager.loadAPIData(
            APIRequest(path: "/api/v1/in/user/register",
                       method: .post,
                       headers: [API_HEADER : self.headerValue],
                       parameters: param,
                       decoding: APIResponse<User_Token>.self)
        )
        .sink { [weak self] completion  in
            guard let self = self else { return }
            // API 자체적으로 내보내는 에러는 여기서 거를거고
            switch completion {
            case .failure(let error):
                printLog("\(error)")
            case .finished:
                break
            }
        } receiveValue: {  [weak self] response in
            guard let self = self else { return }
            switch response.status.code {
            case .success(let code):
                if code == "000" {
                    if let data = response.data, let accToken = data.token, let refresh = data.refresh{
                        self.accToken = accToken
                        self.refresh = refresh
                        
                        appVM.naviState.set(act: .ADD, path: .SelectAcademy)
                    }
                }
            default:
                break
            }
            
        }
        .store(in: &cancellables)

    }
    
}
