//
//  IntroViewModel.swift
//  AcaMate
//
//  Created by TAnine on 3/20/25.
//

import SwiftUI
import Combine


class IntroViewModel: ObservableObject {
    private let appVM: AppViewModel
    
    private var cancellables = Set<AnyCancellable>()
    
    @UserDefault(key: "header", defaultValue: "headerValue") var headerValue
    
    init(_ appVM: AppViewModel) {
        self.appVM = appVM
    }
    
    func appStart() {
        subscribeAlertAction()
        searchHeader()
            .flatMap { success -> Future<VersionData, Error> in
                return self.loadVersion()
            }
            .sink { [weak self]  completion in
                guard let self = self else {return}
                switch completion {
                case .failure(let error):
                    // 만약 여기서 에러가 난다면 서버에 문제가 있다는 것
                    printLog(error)
                    self.appVM.alertData = SetAlertData().setServerError(action: appVM.alertAction)
                    self.appVM.showAlert.toggle()
                case .finished: break
                }
            } receiveValue: { [weak self] version in
                guard let self = self else {return}
                @UserDefault(key:"currentVer", defaultValue: "0.0.0") var currentVer
                @UserDefault(key:"finalVer", defaultValue: "0.0.0") var finalVer
                currentVer = currentVersion()
                finalVer = version.final_ver
                
                let compareForce = compareVersion(version.force_ver, currentVer)//currentVersion())
                let compareChoice = compareVersion(version.final_ver, currentVer)//currentVersion())
                
                if compareForce == .bigger {
                    appVM.alertData = SetAlertData().setForceUpdate(
                        action: appVM.alertAction
                    )
                    appVM.showAlert.toggle()
                } else if compareChoice == .bigger && version.choice_update_yn {
                    appVM.alertData = SetAlertData().setSelectUpdate(
                        action: appVM.alertAction
                    )
                    appVM.showAlert.toggle()
                } else {
                    // 정상 동작 넘어감
                    appVM.naviState.set(act: .RESET, path: .Login)
                    
                }
            }
            .store(in: &cancellables)
    }
    
    func searchHeader() -> Future<Bool, Error> {
        return Future { [weak self] promise in
            
            guard let self = self else {
                promise(.failure(ACA_ERROR("Self 전환 오류")))
                return
            }
            
            guard let deviceId = UIDevice.current.identifierForVendor?.uuidString,
                  let bundleId = Bundle.main.bundleIdentifier else {
                promise(.failure(ACA_ERROR("번들/디바이스 아이디 조회 불량")))
                return
            }
            
            let request = APIRequest(path: "/api/v1/in/app",
                                     parameters: ["type": "I", "specific": deviceId, "project": bundleId],
                                     decoding: APIResponse<Header>.self)
            appVM.apiManager.loadAPIData(request)
                .sink { completion in
                    switch completion {
                    case .failure(let error):
                        printLog("최종 에러: \(error)")
                        promise(.failure(error))
                        
                    case .finished:
                        break
                    }
                } receiveValue: { [weak self] response in
                    guard let self = self else {return}
                    if let data = response.data {
                        self.headerValue = data.header
                        promise(.success(true))
                    }
                    else {
                        promise(.failure(ACA_ERROR("데이터 없음")))
                    }
                }
                .store(in: &self.cancellables)
        }
        //
    }
    
    
    private func subscribeAlertAction() {
        appVM.alertAction
            .compactMap { $0 }
            .sink { [weak self] action in
                guard let self = self else {return}
                if action == "exit" {
                    exit(1)
                } else if action == "updateNow" {
                    exit(1)
                    //MARK: - TODO (앱스토어 이동 로직 넣을 것)
                } else {
                    appVM.naviState.set(act: .RESET, path: .Login)
                }
            }.store(in: &cancellables)
    }
    
    private func loadVersion() -> Future<VersionData, Error> {
        return Future { [weak self] promise in
            guard let self = self else {return}
            let request = APIRequest(path: "/api/v1/in/app/version",
                                     headers: [API_HEADER : self.headerValue],
                                     parameters: ["type":"I"],
                                     decoding: APIResponse<VersionData>.self)
            
            appVM.apiManager.loadAPIData(request)
                .sink { completion in
                    switch completion {
                    case .failure(let error):
                        printLog("\(error)")
                        promise(.failure(error))
                    case .finished: break
                    }
                } receiveValue: { versionData in
                    guard let version = versionData.data else {return}
                    printLog("\(version.toStringDict())")
                    promise(.success(version))
                }
                .store(in: &cancellables)
        }
        
    }
    
    private func currentVersion() -> String {
        guard let currentVer = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String else { return "" }
        return currentVer
        
    }
    
    private func versionChange(ver: String) -> [Int] {
        return ver.components(separatedBy: ["."]).map {Int($0) ?? 0}
    }
    
    
}
