package com.example.smart119

import android.graphics.Color
import android.view.View
import android.widget.TextView
import com.example.smart119.datas.HospitalSearch
import com.example.smart119.datas.SaveLogin
import com.example.smart119.interfaces.RetrofitClient
import com.example.smart119.views.FragmentHandler
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.text.SimpleDateFormat
import java.util.Date
import java.util.concurrent.atomic.AtomicBoolean

enum class TransferState {
    IDLE, // 유휴상태
    STARTED, // 이송시작
    CANCELED, // 이송취소
    COMPLETED, // 이송완료
    END, // 이송 종료
    CHANGED // 이송변경
}

enum class ETAState {
    CONTINUE, // API 계속 진행 상태
    END // API 정지 or Cancel
}

object TransferManager {
    @Volatile
    private var currentState: TransferState = TransferState.IDLE
    public var serverState = AtomicBoolean(false)

    @Volatile
    private var ETA_STATE: ETAState = ETAState.CONTINUE

    private var transferThread: Thread? = null
    private val isRunning = AtomicBoolean(false)
    private val sleepTime: Long = 5000

    private var isKeepFindPath = AtomicBoolean(false)

    private var isUpdateETA = AtomicBoolean(false)
    private val updateDelayTime: Long = 10000; //5초 update eta 지연 수행 시간
    private val runningEvtListener = mutableMapOf<String, (JsonObject?) -> Unit>()

    private var errorDefLon: Double = 127.00663305137988;
    private var errorDefLat: Double = 37.56777199202061;

    private var _selectedHospInfo:JsonObject = JsonObject();

    private var lastUpdateData:JsonObject = JsonObject().apply {
        addProperty("hpid", "")
        addProperty("levelState", "")
        addProperty("eta", "")
        addProperty("currentTime", "")
        addProperty("leftDistance", "")
        addProperty("transferState", "")
    };

    fun set_transfer_data(
        hpid:String, levelState:String, eta:String,
        currentTime:String, leftDistance:String, transferState:String
    ) {
        if (hpid != "") lastUpdateData.addProperty("hpid", hpid)
        if (levelState != "") lastUpdateData.addProperty("levelState", levelState)
        if (eta != "") lastUpdateData.addProperty("eta", eta)
        if (currentTime != "") lastUpdateData.addProperty("currentTime", currentTime)
        if (leftDistance != "") lastUpdateData.addProperty("leftDistance", leftDistance)
        if (transferState != "") {

            lastUpdateData.addProperty("transferState", transferState)
        }
    }
    fun get_transfer_data():JsonObject {
        return lastUpdateData
    }
    // 이벤트 리스너 등록
    fun registerListener(key: String, listener: (JsonObject?) -> Unit) {
        if (runningEvtListener.containsKey(key)) {
//            println("Listener with key '$key' already registered.")
        } else {
            runningEvtListener[key] = listener
//            println("Listener with key '$key' registered.")
        }
    }

    // 이벤트 발생
    private fun dispatchEvent(eventName: String, data: JsonObject? = null) {
        val listener = runningEvtListener[eventName]
        if (listener != null) {
            println("Dispatching event: $eventName")
            listener(data)
        } else {
            println("No listener registered for event: $eventName")
        }
    }

    fun getState(): TransferState {
        return currentState
    }


    // 이송 시작
    fun startTransfer():Boolean {
        if (currentState == TransferState.STARTED) {
            println("Transfer is already started.")
            return false
        }

        currentState = TransferState.STARTED
        ETA_STATE = ETAState.CONTINUE;
        isRunning.set(true)
        isKeepFindPath.set(true)
        // "/startEmergency.do" 먼저 실행 후, 결과에 따라 thread 시작

        try {
            _SET_HOSPINFO(HospitalSearch.getSelectedData())
            UpdateTransferInfomation();
        }
        catch (e:Exception) {
            println(e.message)
        }

        if (API_STARTEMG()) {
            transferThread = Thread {
                println("Transfer started.")
                while (isRunning.get() && currentState == TransferState.STARTED) {
                    try {
                        // 이송 중 반복 작업 수행
                        println("Transfer in progress... SLEEP TIME[${sleepTime}ms]")
                        // 등록한 이벤트 함수로 update중인 상태 전달
//                        if (!RandomNumberUtil.num_increase()) {
//                            println("END!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
//                            API_END_TRANSFER();
//                            continue
//                        }
                        //#region 서버로부터 종료 코드를 받는 경우,
                        //#endregion

//                        println("이전 데이터");
//                        println(HospitalSearch.getSelectedData());
//                        println("변경 데이터");
//                        println(_GET_HOSPINFO());

                        Thread.sleep(sleepTime) // 1초마다 실행
                    } catch (e: InterruptedException) {
                        println("Transfer loop interrupted.")
                    }
                }
                println("Transfer loop stopped.")
                isKeepFindPath.set(false);
            }

            transferThread?.start()
            return true;
        } else {
            isKeepFindPath.set(false);
            SendDialogMsg("응급 이송 시작 오류", "API START시 오류 발생")
            return false;
        }
    }

    private fun _SET_HOSPINFO(hospInfo:JsonObject?) {
        val copiedJson = JsonParser.parseString(hospInfo.toString()).asJsonObject
        _selectedHospInfo = copiedJson
    }

    private fun _GET_HOSPINFO():JsonObject? {
        return _selectedHospInfo;
    }

    fun SendDialogMsg(title:String, msg:String) {
        var sendMsg = JsonObject().apply {
            addProperty("title", title)
            addProperty("msg", msg)
        }

//        val transferHandler = FragmentHandler.getView("TransferFragment");
//        if (transferHandler != null) {
//            val bottomNaviView = transferHandler.findViewById<BottomNavigationView>(R.id.bottom_navigation)
//            bottomNaviView.selectedItemId = R.id.hospSearch;
//        }
        dispatchEvent("transfer_dialogmsg_event", sendMsg)
    }

    // 이송 취소
    fun cancelTransfer() {
        if (currentState != TransferState.STARTED &&
            serverState == AtomicBoolean(false)) {
            println("Cannot cancel. Transfer is not active.")
            return
        }

        currentState = TransferState.CANCELED
        println("Transfer set CANCELED")
        API_END_TRANSFER()
    }

    // 이송 종료
    fun completeTransfer() {
        if (currentState != TransferState.STARTED) {
            println("Cannot complete. Transfer is not active.")
            return
        }

        currentState = TransferState.COMPLETED
        println("Transfer set COMPLETED")
        API_END_TRANSFER()
        stopTransferLoop()
    }

    // 이송 변경
    fun changeTransfer() {
        if (currentState != TransferState.STARTED) {
            println("Cannot change. Transfer is not active.")
            return
        }

//        currentState = TransferState.CHANGED
        ///updateETDHospId.do
        println("Transfer state changed.")
        // 이송 변경에 따른 추가 작업 수행
        API_CHANGE_HOSPITAL()
    }

    // 이송 종료 상태로 설정
    fun setEnd() {
        if (currentState == TransferState.STARTED) {
            isRunning.set(false)
            isKeepFindPath.set(false)
            transferThread?.interrupt()
            transferThread = null
        }
        currentState = TransferState.END;
        println("Transfer set to END state.")

        SendDialogMsg("이송 종료", "응급 이송이 종료되었습니다.")
    }

    fun setCancel() {
        isRunning.set(false)
        isKeepFindPath.set(false)
        transferThread?.interrupt()
        transferThread = null

        currentState = TransferState.END;
        SendDialogMsg("이송 종료", "응급 이송이 취소되었습니다.")
    }

    // IDLE 상태로 설정
    fun setIdle() {
        if (currentState == TransferState.STARTED) {
            stopTransferLoop()
        }
        currentState = TransferState.IDLE
        println("Transfer set to IDLE state.")
    }

    // 루프 중단
    private fun stopTransferLoop() {
        isRunning.set(false)
        isKeepFindPath.set(false)
        transferThread?.interrupt()
        transferThread = null
        ETA_STATE = ETAState.END

        currentState = TransferState.IDLE
        SendDialogMsg("응급 이송 종료", "이송이 종료되었습니다.")
    }

    // 현재 상태 조회
    fun getCurrentState(): TransferState {
        return currentState
    }

    //pingpong을 위한 메시지 api 수행
    private fun FindPath_ETA() {
        isUpdateETA.set(false)
        if (!isRunning.get() && currentState != TransferState.STARTED) return;

        try {
//            val resObj = res.getAsJsonObject();
//            val callResult = resObj["isSuccess"]?.asBoolean ?: true;
            val lon = LocationHelper.getCurrentLon();
            val lat = LocationHelper.getCurrentLat();
//            val lon = resObj["lon"]?.asDouble ?: 0.0;
//            val lat = resObj["lat"]?.asDouble ?: 0.0;

            val src_pos = "${lon}, ${lat}";

            val selectedHospital = _GET_HOSPINFO();
            var hosp_lon = selectedHospital?.get("lon")?.asString
            var hosp_lat = selectedHospital?.get("lat")?.asString
            if (hosp_lon == "null" || hosp_lon == "") {
                hosp_lon = errorDefLon.toString()
            }
            if (hosp_lat == "null" || hosp_lat == "") {
                hosp_lat = errorDefLat.toString()
            }
            var dst_pos = "${hosp_lon}, ${hosp_lat}";

            if (isKeepFindPath.get()) {
                HelpUtility.delay_executor(updateDelayTime) {
                    RetrofitClient.pathInstance.findPath(
                        API_Helper.make_findpath_param(src_pos, dst_pos)
                    ).enqueue(findPathResponse())
                }
            }
            else {
                UpdateTransferInfomation_TIME()
            }


        } catch (e: Exception) {
            println(e.message)
//                SendDialogMsg("오류 발생", "길찾기 중 오류가 발생하였습니다. ${e.message}")
        }

    }

    private fun UpdateTransferInfomation_ETA(loc:JsonObject) {

        try {
            var tfView = FragmentHandler.getView("TransferFragment")
            if (tfView != null) {
                var _eta = loc["eta"].asInt;
                var _leftDistance = loc["leftDistance"].asString

                val currentTime = SimpleDateFormat("HH:mm:ss").format(Date())
                val updateTimeTxt = tfView.findViewById<TextView>(R.id.infoUpdateTime)
                updateTimeTxt?.text = currentTime;

                var _hospInfo = _GET_HOSPINFO()
                //#region eta 업데이트
                if (_eta != -1 && _eta != null) {
                    val etaTxt = tfView.findViewById<TextView>(R.id.tvLeftTimeVal)
                    val _etaStrSec = API_Helper.ETA_SEC_TO_STRING(_eta);
                    etaTxt?.text = _etaStrSec
                    if (_hospInfo != null) { _hospInfo.addProperty("eta", _etaStrSec) }
                }
                //#endregion

                //#region etd 업데이트
                if (_leftDistance != "" && _leftDistance != null) {
                    val etdTxt = tfView.findViewById<TextView>(R.id.tvLeftDistVal)
                    val _etdStrKM = API_Helper.DISTANCE_FORMAT_METER_TO_KM(_leftDistance);
                    etdTxt?.text = _etdStrKM;
                    if (_hospInfo != null) { _hospInfo.addProperty("leftDistance", _etdStrKM) }
                }
                //#endregion
            }
        } catch (e: Exception) {
            println(e.message)
        }
    }

    private fun UpdateTransferInfomation_TIME() {
        var tfView = FragmentHandler.getView("TransferFragment")
        if (tfView != null) {
            val currentTime = SimpleDateFormat("HH:mm:ss").format(Date())
            val updateTimeTxt = tfView.findViewById<TextView>(R.id.infoUpdateTime)
            updateTimeTxt?.text = currentTime
        }
    }

    private fun UpdateTransferInfomation() {
        try {
            var tfView = FragmentHandler.getView("TransferFragment")
            if (tfView != null) {
                //병원 이름, 혼잡도
                var hosp_info = _GET_HOSPINFO();
                if (hosp_info != null) {
                    println(hosp_info)
                    var levelState = hosp_info["levelState"].asString
                    var hospName = hosp_info["title"].asString

                    val hospNameTxt = tfView.findViewById<TextView>(R.id.tvTFHospName)
                    hospNameTxt?.text = hospName
                    val lidarValTxt = tfView.findViewById<TextView>(R.id.tvTFLidarValue)
                    lidarValTxt?.text = levelState

                    val lLidarView : View = tfView.findViewById(R.id.tvTFLidarColor)
                    lLidarView?.setBackgroundColor(
                        Color.parseColor(API_Helper.lidar_levelState_Color(levelState))
                    )

                    val tfStateTxt = tfView.findViewById<TextView>(R.id.tfState)
                    when (currentState) {
                        TransferState.IDLE -> tfStateTxt.text = "유휴 상태"
                        TransferState.STARTED -> tfStateTxt.text = "이송 시작"
                        TransferState.CANCELED -> tfStateTxt.text = "이송 취소"
                        TransferState.COMPLETED -> tfStateTxt.text = "이송 완료"
                        TransferState.END -> tfStateTxt.text = "이송 종료"
                        else -> tfStateTxt.text = "-"
                    }

                    println()
                }
            }
        } catch (e: Exception) {
            println(e.message)
        }
    }
    fun SetLastHospitalInfo() {
        try {
            var tfView = FragmentHandler.getView("TransferFragment")
            if (tfView != null) {
                //병원 이름, 혼잡도
                var hosp_info = _GET_HOSPINFO();
                if (hosp_info != null) {
                    println(hosp_info)
                    var levelState = hosp_info["levelState"].asString
                    var hospName = hosp_info["title"].asString

                    val hospNameTxt = tfView.findViewById<TextView>(R.id.tvTFHospName)
                    hospNameTxt?.text = hospName
                    val lidarValTxt = tfView.findViewById<TextView>(R.id.tvTFLidarValue)
                    lidarValTxt?.text = levelState
                    val lLidarView : View = tfView.findViewById(R.id.tvTFLidarColor)
                    lLidarView?.setBackgroundColor(
                        Color.parseColor(API_Helper.lidar_levelState_Color(levelState))
                    )

                    val tfStateTxt = tfView.findViewById<TextView>(R.id.tfState)
                    when (currentState) {
                        TransferState.IDLE -> tfStateTxt.text = "유휴 상태"
                        TransferState.STARTED -> tfStateTxt.text = "이송 시작"
                        TransferState.CANCELED -> tfStateTxt.text = "이송 취소"
                        TransferState.COMPLETED -> tfStateTxt.text = "이송 완료"
                        TransferState.END -> tfStateTxt.text = "이송 종료"
                        else -> tfStateTxt.text = "-"
                    }

                    var last_eta = "-";
                    var last_etd = "-";
                    //#region last eta 업데이트
                    val etaTxt = tfView.findViewById<TextView>(R.id.tvLeftTimeVal)
                    if (hosp_info["eta"] != null) {
                        last_eta = hosp_info["eta"].asString
                        etaTxt?.text = last_eta
                    }
                    //#endregion

                    //#region last etd 업데이트
                    val etdTxt = tfView.findViewById<TextView>(R.id.tvLeftDistVal)
                    if (hosp_info["leftDistance"] != null) {
                        last_etd = hosp_info["leftDistance"].asString
                        etdTxt?.text = last_etd;
                    }
                    //#endregion

                    UpdateTransferInfomation_TIME();
                }
            }
        } catch (e: Exception) {
            println(e.message)
        }
    }

    private fun API_STARTEMG(): Boolean {
        val selectedData = HospitalSearch.getSelectedData()
        if (selectedData != null) {
            var hpid = selectedData["hpid"].toString().trim('"')
            var reqBody = JsonObject().apply {
                addProperty("hpid", hpid)
                addProperty("hosp_name", selectedData.asJsonObject["title"].asString)
            }
            RetrofitClient.transferInstance.startEMG(reqBody).enqueue(startTransferResponse())
            return true;
        } else return false;
    }

    // 업데이트 ETA API 함수
    private fun API_UPDATEETA(reqBody:JsonObject): Boolean {
        // API URL : /updateETDDuration
        RetrofitClient.transferInstance.updateHospETA(reqBody).enqueue(updateETAResponse())
        return false;
    }

    private fun API_CHANGE_HOSPITAL(): Boolean {
        val selectedData = HospitalSearch.getSelectedData()
        if (selectedData != null) {
            var _sel_hpid = selectedData["hpid"].asString
            var _updateETDhospId_body = JsonObject().apply {
                addProperty("hpid", _sel_hpid)
                addProperty("hosp_name", selectedData.asJsonObject["title"].asString)
            }
            RetrofitClient.transferInstance.changeHospital(_updateETDhospId_body).enqueue(changeHospitalResponse())
            return true;
        }
        return false;
    }

    private fun API_END_TRANSFER(): Boolean {
        RetrofitClient.transferInstance.endEMG().enqueue(endTransferResponse())
        return true;
    }

    private fun startTransferResponse(): Callback<JsonObject> {
        return object : Callback<JsonObject> {
            override fun onResponse(call: Call<JsonObject>, response: Response<JsonObject>) {
                if (response.isSuccessful) { //200 ok
                    val resBody = response.body();
                    if (resBody != null) {
                        var _status = resBody.get("status")?.asString;
                        //response.status = "success" or "duplicate"
                        if (_status == "success") {
                            UpdateTransferInfomation()
                            FindPath_ETA();
                            println("이송 시작 [onResponse - Success] : ${response.message()}")
                        }
                        else {
                            println("이송 시작 [onResponse - Fail] : ${response.message()}")
                            //검색창, 다시 환자 정보 전송
                            SendDialogMsg("동일한 환자정보가 이미 존재합니다",
                                "같은 차량으로 동일한 환자정보가 이미 전송되어 있습니다.")
//                        nav_to_hospsearch();
                        }
                    }
                    else {

                    }
                } else { //200 아닌 코드들
                    println("이송 시작 [onResponse - Fail] : ${response.message()}")
                    val parseBody = JsonParser.parseString(response.errorBody()?.string())
                    if (parseBody != null) {
                        val resStatus = parseBody.asJsonObject["status"].asString
                        if (resStatus == "duplicate") {
                            SendDialogMsg("환자정보 전송 실패",
                            "같은 차량으로 동일한 환자정보가 이미 전송되어 있습니다.")
                            clear_state();
                        }
                        else {
                            SendDialogMsg("환자정보 전송 실패",
                                "알수없는 오류로 전송에 실패하였습니다. 담당자에게 문의해주세요.")
                            clear_state();
                        }
                    }
                    else {
                        SendDialogMsg("환자정보 전송 실패",
                            "알수없는 오류로 전송에 실패하였습니다. 담당자에게 문의해주세요.")
                        clear_state();
                    }
                }
            }

            override fun onFailure(call: Call<JsonObject>, t: Throwable) {
                println("이송 시작 [onFailure] ${t.message}")
                SendDialogMsg("환자 정보 전송 실패",
                    "알수없는 오류로 전송에 실패하였습니다. 담당자에게 문의해주세요.")
                clear_state();
            }
        }
    }

    // 업데이트 ETA API 결과
    private fun updateETAResponse(): Callback<JsonObject> {
        return object : Callback<JsonObject> {
            override fun onResponse(call: Call<JsonObject>, response: Response<JsonObject>) {
                if (response.isSuccessful) {
                    var resBody = response.body()
                    var _status = resBody?.get("status")?.asString;
                    if (_status == "continue") {
                        FindPath_ETA();
                        println("API_ETA_TRANSFER[onResponse - Success] : ${response.message()}")
                    }
                    else {
                        //이송 종료 처리
                        if (currentState != TransferState.END) setEnd()
                    }
                } else {
                    println("API_ETA_TRANSFER[onResponse - Fail] : ${response.message()}")
                    isKeepFindPath.set(false)
                }
            }

            override fun onFailure(call: Call<JsonObject>, t: Throwable) {
                //대부분 네트워크 문제
                println("API_ETA_TRANSFER[OnFailure] : ${t.message}")
                isKeepFindPath.set(false)
            }
        }
    }

    // 업데이트 ETA API 결과
    private fun changeHospitalResponse(): Callback<JsonObject> {
        return object : Callback<JsonObject> {
            override fun onResponse(call: Call<JsonObject>, response: Response<JsonObject>) {
                if (response.isSuccessful) {
                    try {
                        _SET_HOSPINFO(HospitalSearch.getSelectedData())
                        UpdateTransferInfomation();
                    }
                    catch (e:Exception) {
                        println(e.message)
                    }
                    println("API_CHANGE_HOSPITAL[onResponse - Success] : ${response.message()}")
                } else {
                    println("API_CHANGE_HOSPITAL[onResponse - Fail] : ${response.message()}")
                    isKeepFindPath.set(false)
                    SendDialogMsg("병원 정보 변경 실패",
                        "알수없는 오류로 전송에 실패하였습니다. 담당자에게 문의해주세요.")
                    clear_state();
                }
            }

            override fun onFailure(call: Call<JsonObject>, t: Throwable) {
//                ETA_STATE = ETAState.END //?
                println("API_CHANGE_HOSPITAL[onFailure] : ${t.message}")

            }
        }
    }

    // 업데이트 ETA API 결과
    private fun endTransferResponse(): Callback<JsonObject> {
        return object : Callback<JsonObject> {
            override fun onResponse(call: Call<JsonObject>, response: Response<JsonObject>) {
                if (response.isSuccessful) {
                    var resBody = response.body()
                    var _status = resBody?.get("status")?.asString;
                    setCancel()
                } else {
//                    ETA_STATE = ETAState.END //?
                    println("API_END_TRANSFER[onResponse - Fail] : ${response.message()}")
                    isKeepFindPath.set(false)
                    clear_state()
                }
            }

            override fun onFailure(call: Call<JsonObject>, t: Throwable) {
//                ETA_STATE = ETAState.END //?
                //대부분 네트워크 문제
//                println("API_END_TRANSFER[OnFailure] : ${t.message}")
                isKeepFindPath.set(false)
                clear_state()
            }
        }
    }

    //길찾기 API 결과
    private fun findPathResponse(): Callback<JsonObject> {
        return object : Callback<JsonObject> {
            override fun onResponse(call: Call<JsonObject>, response: Response<JsonObject>) {
                if (response.isSuccessful) {
                    try {
                        var resBody = response.body()
                        var routes = resBody?.get("routes")?.asJsonArray
                        if (routes != null && routes.size() > 0) {
                            var f_route = routes[0].asJsonObject;
                            var res_code = f_route["result_code"].asString
                            when(res_code) {
                                "0" -> {
                                    var f_summary = f_route["summary"].asJsonObject
                                    var _distance = f_summary["distance"].asString;
                                    var _duration = f_summary["duration"].asString;
                                    var _updateETA = JsonObject().apply {
                                        addProperty("leftDistance", _distance)
                                        addProperty("eta", _duration)
                                    }
                                    
                                    //duration : 초, distance : 미터
                                    println("distance : ${_distance}km, duration : ${_duration}sec")
                                    UpdateTransferInfomation_ETA(_updateETA)

                                    var _updateETA_body = JsonObject().apply {
                                        addProperty("duration", _duration)
                                    }
                                    API_UPDATEETA(_updateETA_body)
                                }
                                "1" -> FindPath_ETA() // 길찾기 결과를 찾을 수 없음, 종료
                                "101" -> FindPath_ETA() // 경유지 지점 주변의 도로를 탐색할 수 없음, 계속 찾기
                                "102" -> FindPath_ETA() // 시작 지점 주변의 도로를 탐색할 수 없음, 계속 찾기
                                "103" -> FindPath_ETA() // 도착 지점 주변의 도로를 탐색할 수 없음, 계속 찾기
                                "104" -> isKeepFindPath.set(false) // 출발지와 도착지가 5 m 이내로 설정된 경우 경로를 탐색할 수 없음, 이 경우엔 패스
                                "105" -> FindPath_ETA() // 시작 지점 주변의 도로에 유고 정보(교통 장애)가 있음, 계속 찾기
                                "106" -> FindPath_ETA() // 도착 지점 주변의 도로에 유고 정보(교통 장애)가 있음, 계속 찾기
                                "107" -> FindPath_ETA() // 경유지 주변의 도로에 유고 정보(교통 장애)가 있음, 계속 찾기
                                else -> FindPath_ETA() // 길찾기 시 알수 없는 코드가 나왔을때,
                            }
                        }
                    } catch (e: Exception) {
                        println(e.message)
                        isKeepFindPath.set(false)
                    }
                } else {
                    println("길찾기 결과[Fail] : ${response.message()}")
                    isKeepFindPath.set(false)
                }
            }

            override fun onFailure(call: Call<JsonObject>, t: Throwable) {
                //대부분 네트워크 문제
                println("길찾기 결과[OnFailure] : ${t.message}")
                isKeepFindPath.set(false)
            }
        }
    }

    fun nav_to_login() {
        val activity = AlertDialogUtil.getActivityContext()
        if (activity != null) {
            AlertDialogUtil.showAlert_OK(
                context = activity,
                title = "세션 만료",
                message = "기존 세션이 만료되었습니다. 다시 로그인 해주시기 바랍니다.\n",
                onPositiveClick = {
                    SaveLogin.setLogin(false)
                    LoginManager.setLoggedIn(false);
                    val bottomNaviView =
                        activity.findViewById<BottomNavigationView>(R.id.bottom_navigation)
                    bottomNaviView.selectedItemId = R.id.emgLogin;
                }
            )
        }
    }

    fun nav_to_hospsearch() {
        val activity = AlertDialogUtil.getActivityContext()
        val bottomNav = activity?.findViewById<BottomNavigationView>(R.id.bottom_navigation)
        if (bottomNav != null &&
            bottomNav.selectedItemId != R.id.hospSearch
        ){
            bottomNav.selectedItemId = R.id.hospSearch
        }
    }

    fun clear_state() {
        currentState = TransferState.IDLE
        isRunning.set(false)
        isKeepFindPath.set(false)
        transferThread?.interrupt()
        transferThread = null
        println("Logout, Clear Transfer State.")
    }
}