package com.example.smart119.views

import android.graphics.Typeface
import android.os.Bundle
import android.text.Spannable
import android.text.SpannableStringBuilder
import android.text.style.StyleSpan
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.Button
import android.widget.Spinner
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.NavHostFragment
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.smart119.API_Helper
import com.example.smart119.AlertDialogUtil
import com.example.smart119.ListItem
import com.example.smart119.LoginManager
import com.example.smart119.MedicalInfo
import com.example.smart119.R
import com.example.smart119.SpreadsheetAdapter
import com.example.smart119.TransferManager
import com.example.smart119.TransferState
import com.example.smart119.datas.HospitalSearch
import com.example.smart119.datas.SaveLogin
import com.example.smart119.interfaces.RetrofitClient
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.android.material.textfield.TextInputEditText
import com.google.gson.JsonObject
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.util.*

class AddressSearchFragment : Fragment() {

    private lateinit var asAdapter: SpreadsheetAdapter

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.address_search_page, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        FragmentHandler.registerView("AddressSearchFragment", view)

        hospitalInit(view);
        HospitalSearch.clearAllData()

        //#region 광역시/도 콤보박스 설정
        val siItems = mutableListOf(HospitalSearch.GET_SIDO_DEFAULT_NAME())
        val siSpinner: Spinner = view.findViewById(R.id.siSelectSpinner)
        val arrAdapterSi =
            ArrayAdapter(requireContext(), android.R.layout.simple_spinner_dropdown_item, siItems)
        siSpinner.adapter = arrAdapterSi;
        //#endregion
//        //#region 시/군/구 콤보박스 설정
//        val gunGuItems = HospitalSearch.getGunGuNameList()
//        val guGunSpinner: Spinner = view.findViewById(R.id.guGunSelectSpinner)
//        val arrAdapterGuGun = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_dropdown_item, gunGuItems)
//        guGunSpinner.adapter = arrAdapterGuGun;
//        //#endregion

        val searchButtonAS = view.findViewById<Button>(R.id.hospSearchButtonAS)
        searchButtonAS.setOnClickListener {
            address_hospital_search(view);
        }

        val gugunSelectorTV = view.findViewById<TextView>(R.id.gunGuSelectText)
        gugunSelectorTV.setOnClickListener {
            GunGuSelector_Dialog.show(requireContext())
        }

        val hospCatTV = view.findViewById<TextView>(R.id.hospCatText)
        hospCatTV.setOnClickListener {
            HospitalCategoryAddress_Dialog.show(requireContext())
        }

        val prtTV = view.findViewById<TextView>(R.id.prtText)
        prtTV.setOnClickListener {
            DepartmentAddress_Dialog.show(requireContext())
        }

        val prevASButton = view.findViewById<Button>(R.id.pagePrevAS)
        prevASButton.setOnClickListener {
            if (HospitalSearch.getAllData().size > 0) {
                var bChanged = PaginationHelper.prevPage(requireView(), { page ->
                    page_onclick_listener(page)
                })
                //request page
                if (bChanged) {
                    var currPage = PaginationHelper.currentPage;
//                    println("prev request number ${PaginationHelper.currentPage}")
                    page_onclick_listener(currPage)
                }
//                else println("no request prev")
            }
        }

        val nextASButton = view.findViewById<Button>(R.id.pageNextAS)
        nextASButton.setOnClickListener {
            if (HospitalSearch.getAllData().size > 0) {
                var bChanged = PaginationHelper.nextPage(requireView(), { page ->
                    page_onclick_listener(page)
                })
                //request page
                if (bChanged) {
                    var currPage = PaginationHelper.currentPage;
//                    println("next request number ${PaginationHelper.currentPage}")
                    page_onclick_listener(currPage)
                }
//                else println("no request next")
            }
        }

        GunGuSelector_Dialog.registerCallback { evtString ->
            println("군구 선택 이벤트!! ${evtString}")
            address_hospital_search(view);
        }

        HospitalCategoryAddress_Dialog.registerCallback { evtString ->
            println("병원분류명 선택 이벤트!! ${evtString}")
        }

        DepartmentAddress_Dialog.registerCallback { evtString ->
            println("진료과목 선택 이벤트!! ${evtString}")
        }


    }

    private fun address_hospital_search(view: View) {
        asAdapter.clearHospitalList();
        HospitalSearch.clearAllData();

        var filter_si = "서울특별시";//searchObject["si"].asString;
        var filter_gu = "";//searchObject["gu"].asString;
        var filter_relate = "";//searchObject["relate"].asString;
        var sPage = "1";
        var sRow = "4";
        var filter_qd = ""; // 병원분류코드
        var filter_qz = ""; // 진료과목코드

        val siSpin = view.findViewById<Spinner>(R.id.siSelectSpinner);
        val gunSpin = view.findViewById<Spinner>(R.id.guGunSelectSpinner);
        val editText = view.findViewById<TextInputEditText>(R.id.relateInput)
        filter_si = siSpin.selectedItem.toString()
        filter_gu =
            view.findViewById<TextView>(R.id.gunGuSelectText).text.toString()//HospitalSearch.get_selectGunGu()//gunSpin.selectedItem.toString()
        filter_qz =
            view.findViewById<TextView>(R.id.hospCatText).text.toString()//HospitalSearch.get_selectHospCatAddress()
        filter_qd =
            view.findViewById<TextView>(R.id.prtText).text.toString()//HospitalSearch.get_selectPrtAddress()
        filter_relate = editText.text.toString()

        //#region 항목별 코드 변환
        filter_qz = MedicalInfo.get_addressQZ_code(filter_qz).toString()
        filter_qd = MedicalInfo.get_prt_code(filter_qd).toString()
        //#endregion

        if (filter_gu == "null" || filter_gu == "군구선택") {
            filter_gu = ""
        }
        if (filter_qz == "null" || filter_qz == "병원분류명선택") {
            filter_qz = ""
        }
        if (filter_qd == "null" || filter_qd == "진료과목선택") {
            filter_qd = ""
        }
        if (filter_relate == "null") {
            filter_relate = ""
        }

        println("${filter_si}, ${filter_gu}, ${filter_qz}, ${filter_qd}, ${filter_relate}")

        var reqBody: JsonObject = API_Helper.make_addressHosp_param(
            filter_si, filter_gu, filter_qd, filter_qz, filter_relate,
            sPage, sRow
        );
        try {
            LoadingDialog.showDlg(requireContext())
            HospitalSearch.SET_SearchRequest(true, reqBody)
            RetrofitClient.locInstance.getAddressHospitalList(reqBody)
                .enqueue(getAddressResponse())
        } catch (e: Exception) {
            println(e.message)
            LoadingDialog.hideDlg()
        }
    }

    override fun onResume() {
        super.onResume()
//        Toast.makeText(requireContext(), "위치기반 탭 활성화!", Toast.LENGTH_SHORT).show()
//        println("주소기반 탭 활성화!")

        //#region 서남병원으로 요청 고정
        try {
//            RetrofitClient.transferInstance.currentAction().enqueue(currentActionResponse())

            LoadingDialog.showDlg(requireContext())
            var reqBody: JsonObject = API_Helper.make_addressHosp_param(
                "서울특별시", "", "", "", "서남병원",
                "1", "4"
            );
            RetrofitClient.locInstance.getAddressHospitalList(reqBody)
                .enqueue(getAddressResponse())
        } catch (e: Exception) {
            println(e.message)
            LoadingDialog.hideDlg()
        }
        //#endregion
    }

    override fun onPause() {
        super.onPause()
//        println("주소기반 탭 비 활성화!")
        asAdapter.clearHospitalList()
        HospitalSearch.clearAllData()
        PaginationHelper.setupPaginationLayout(
            requireView(),
            0, 0, { page ->
                page_onclick_listener(page)
            }
        )
    }

    private fun getAddressResponse(): Callback<JsonObject> {
        return object : Callback<JsonObject> {
            override fun onResponse(call: Call<JsonObject>, response: Response<JsonObject>) {
                LoadingDialog.hideDlg()
                if (response.isSuccessful) {
                    val resBody = response.body();
                    if (resBody != null) {
                        set_hospital_list(resBody)
                    } else {
                        nav_to_login();
                    }
                } else {
                    nav_to_login();
                }
            }

            override fun onFailure(call: Call<JsonObject>, t: Throwable) {
                LoadingDialog.hideDlg()
                println(t.message)
                nav_to_login();
            }
        }
    }

    private fun hospitalInit(view: View) {
        var items = listOf(
            ListItem.Header(listOf("병원이름")), // 헤더 열 정의
            ListItem.Header(listOf("주소")),
            ListItem.Header(listOf("전화번호")),
            ListItem.Header(listOf("라이다 혼잡도")),
            ListItem.Header(listOf("거리")),
            ListItem.Header(listOf("병원별 이송 시작"))
        )
        val recyclerViewLS: RecyclerView = view.findViewById(R.id.reCyclerViewLS)

        val spanCount = 6;
        asAdapter = SpreadsheetAdapter(
            items,
            onButtonClick = { row, pos ->
                //row.values[0]
                asAdapter.setSelectedHospitalPos(pos)
                HospitalSearch.setIdx(asAdapter.getSelectedPosition())
                var selectedHospital = asAdapter.getSelectedHospital()
                var getSelData = HospitalSearch.getSelectedData()
                if (selectedHospital is ListItem.Row) {
                    var hospitalName = selectedHospital.values[0];
                    var hospitalAddress = selectedHospital.values[1];
                    var hospitalCallNumber = selectedHospital.values[2];
                    var hospitalLiDAR = selectedHospital.values[3];
                    var hospitalDistance = selectedHospital.values[4];
                    if (TransferManager.getState() == TransferState.STARTED) {
                        //이송 변경
                        //변경된 병원 정보 설정
                        val spannableMessage = SpannableStringBuilder().apply {
                            val preText = "병원 이름 : ${hospitalName}" + "\n" +
                                    "주소 : ${hospitalAddress}" + "\n" +
                                    "전화번호 : ${hospitalCallNumber}" + "\n" +
                                    "라이다혼잡도 : ${hospitalLiDAR}" + "\n"
                            append(preText)

                            val boldText = "확인"
                            append(boldText)
                            setSpan(
                                StyleSpan(Typeface.BOLD), preText.length,
                                preText.length + boldText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                            )
                            append(" 선택시 환자정보가 전송됩니다.(변경 시 기존 이송 병원이 변경됩니다.)\n")
                        }

                        AlertDialogUtil.showAlert_CUSTOM(
                            context = requireActivity(),
                            title = "이송 병원 정보",
                            sppStr = spannableMessage,
                            onPositiveClick = {
                                AlertDialogUtil.showAlert_OK(
                                    context = requireActivity(),
                                    title = "진행 전 확인사항",
                                    message = "진행하시기 전에, 구급활동일지 임시저장을 하셨는지 확인해 주세요\n",
                                    onPositiveClick = {
                                        val bottomNaviView =
                                            requireActivity().findViewById<BottomNavigationView>(R.id.bottom_navigation)
                                        bottomNaviView.selectedItemId = R.id.hospTransfer;
                                        TransferManager.changeTransfer()
                                    }
                                )

                            },
                            onNegativeClick = {}
                        )
                    } else {
                        val spannableMessage = SpannableStringBuilder().apply {
                            val preText = "병원 이름 : ${hospitalName}" + "\n" +
                                    "주소 : ${hospitalAddress}" + "\n" +
                                    "전화번호 : ${hospitalCallNumber}" + "\n" +
                                    "라이다혼잡도 : ${hospitalLiDAR}" + "\n"
                            append(preText)

                            val boldText = "확인"
                            append(boldText)
                            setSpan(
                                StyleSpan(Typeface.BOLD), preText.length,
                                preText.length + boldText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                            )
                            append(" 선택시 환자정보가 전송됩니다.\n")
                        }
                        AlertDialogUtil.showAlert_CUSTOM(
                            context = requireActivity(),
                            title = "이송 병원 정보",
                            sppStr = spannableMessage,
                            onPositiveClick = {
                                AlertDialogUtil.showAlert_OK(
                                    context = requireActivity(),
                                    title = "진행 전 확인사항",
                                    message = "진행하시기 전에, 구급활동일지 임시저장을 하셨는지 확인해 주세요\n",
                                    onPositiveClick = {
                                        if (TransferManager.startTransfer()) {
                                            val bottomNaviView =
                                                requireActivity().findViewById<BottomNavigationView>(R.id.bottom_navigation)
                                            bottomNaviView.selectedItemId = R.id.hospTransfer;
                                        } else {
                                            // 시작되지 않았습니다.
                                            Toast.makeText(
                                                requireActivity(), "이송이 시작되지 않았습니다. 다시 전송해주세요.",
                                                Toast.LENGTH_SHORT
                                            ).show()
                                        }
                                    }
                                )
                            },
                            onNegativeClick = {}
                        )
                    }
                } else {
                    AlertDialogUtil.showAlert(
                        context = requireActivity(),
                        title = "선택된 병원 정보",
                        message = "병원 검색 후 선택해주세요!"
                    )
                }
                //pos, row(ListItem상 선택 위치, 선택한 row 정보) -> hpid는?
            },
            onRowClick = { row ->
//                Toast.makeText(requireActivity(), "${row.values[0]}이 선택되었습니다.", Toast.LENGTH_SHORT)
//                    .show()
            }
        )
        asAdapter.setColumnCount(spanCount)
        recyclerViewLS.adapter = asAdapter

        // GridLayoutManager 설정
        val layoutManager = GridLayoutManager(requireActivity(), spanCount)
        layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
            override fun getSpanSize(position: Int): Int {
//                return if (adapter.getItemViewType(position) == SpreadsheetAdapter.VIEW_TYPE_HEADER) 3 else 1
                return if (asAdapter.getItemViewType(position) == SpreadsheetAdapter.VIEW_TYPE_ROW) {
                    spanCount // Row가 전체 열을 차지하도록 설정
                } else {
                    1 // 기본적으로 각 항목은 한 열을 차지
                }
            }
        }
        recyclerViewLS.layoutManager = layoutManager
    }

    fun set_hospital_list(resobj: JsonObject?) {
        var totPages = resobj?.get("totalPages") // 총 페이지
        var totRows = resobj?.get("totalRows") // 총 행 개수
        var searchRows = resobj?.get("row") // 검색 페이지 행 개수
        var searchPage = resobj?.get("page") // 검색 페이지 번호
        var resData = resobj?.getAsJsonArray("resData")
        var dataSize = resData?.size() ?: 0;

        var hospitalSearchRes: List<List<String>> = mutableListOf()
        var hpidList: MutableList<String> = mutableListOf()
        if (dataSize > 0) {
            // region 검색 결과 리스트에 세팅
            try {
                resData?.forEach { item ->
                    val itemObj = item.asJsonObject;
                    var levelState =
                        API_Helper.lidar_levelState(itemObj.get("levelState").asInt)
                    var itemHpid = itemObj.get("hpid").toString().trim('"');
                    hpidList.add(itemHpid)
                    var itemDistance = ""
                    var itemTel = ""
                    var itemTitle = ""
                    itemTel = itemObj.get("dutyTel1").toString().trim('"')
                    itemTitle = itemObj.get("dutyName").toString().trim('"')

                    var itemLon = itemObj.get("wgs84Lon").toString().trim('"');
                    var itemLat = itemObj.get("wgs84Lat").toString().trim('"');

                    HospitalSearch.addDataHospitalItems(
                        listOf(
                            HospitalSearch.itemStructure(
                                itemHpid, levelState, itemDistance,
                                itemObj.get("city").toString().trim('"'),
                                itemObj.get("district").toString().trim('"'),
                                itemTel, itemTitle, itemLon, itemLat
                            )
                        )
                    )
                }

                var total_Page = totPages?.asInt;
                if (total_Page == null) total_Page = 0;
                var total_Row = totRows?.asInt;
                if (total_Row == null) total_Row = 0;
                PaginationHelper.setupPaginationLayout(
                    requireView(),
                    total_Page,
                    total_Row,
                    { page ->
                        page_onclick_listener(page)
                    })

            } catch (e: Exception) {
                Toast.makeText(requireActivity(), "${e.message}", Toast.LENGTH_LONG)
                    .show()
            } finally {
            }

            hospitalSearchRes = HospitalSearch.getAllData();
        } else {
            AlertDialogUtil.showAlert(
                context = requireActivity(),
                title = "병원 검색 결과",
                message = "병원이 검색되지 않았습니다. 다시 시도해주세요."
            )

            if (!PaginationHelper.pageRequest) PaginationHelper.setupPaginationLayout(
                requireView(),
                0, 0, { page ->
                    page_onclick_listener(page)
                }
            )
        }

        //병원 검색 결과 설정
        if (hospitalSearchRes.size > 0) asAdapter.hospitalListUpdate(hospitalSearchRes, hpidList)
        // endregion
    }

    private fun page_onclick_listener(page: Int) {
//        println("clicked page ${page}")
        var reqBody = HospitalSearch.GET_SearchRequest()
        if (reqBody != null) {
            try {
//                if (HospitalSearch.isAddressSearch()) {
                LoadingDialog.showDlg(requireContext())
                reqBody = reqBody.getAsJsonObject("reqBody")
                reqBody.addProperty("page", "${page}")
                RetrofitClient.locInstance.getAddressHospitalList(reqBody).enqueue(
                    getAddress_Paging_Response()
                )
//                } else {
//                LoadingDialog.showDlg(requireContext())
//                reqBody = reqBody.getAsJsonObject("reqBody")
//                reqBody.addProperty("page", "${page}")
//                RetrofitClient.locInstance.getAroundHospitalList(reqBody)
//                    .enqueue(arroundHospital_Paging_Response())
//                }
            } catch (e: Exception) {
                println(e.message)
                LoadingDialog.hideDlg()
            } finally {
//                LoadingDialog.hideDlg()
            }
        }
    }

    private fun getAddress_Paging_Response(): Callback<JsonObject> {
        return object : Callback<JsonObject> {
            override fun onResponse(call: Call<JsonObject>, response: Response<JsonObject>) {
                LoadingDialog.hideDlg()
                if (response.isSuccessful) {
                    val resBody = response.body();
                    if (resBody != null) {
                        set_hospital_list_page(resBody)
                    } else {
                        nav_to_login();
                    }

                } else {
                    nav_to_login();
                }
            }

            override fun onFailure(call: Call<JsonObject>, t: Throwable) {
                LoadingDialog.hideDlg()
                println(t.message)
                nav_to_login();
            }
        }
    }

    fun set_hospital_list_page(resobj: JsonObject?) {
        // region 현재 병원 리스트 초기화
        asAdapter.clearHospitalList();
        HospitalSearch.clearAllData();
        // endregion

        var totPages = resobj?.get("totalPages") // 총 페이지
        var totRows = resobj?.get("totalRows") // 총 행 개수
        var searchRows = resobj?.get("row") // 검색 페이지 행 개수
        var searchPage = resobj?.get("page") // 검색 페이지 번호
        var resData = resobj?.getAsJsonArray("resData")
        var dataSize = resData?.size() ?: 0;

        var hospitalSearchRes: List<List<String>> = mutableListOf()
        var hpidList: MutableList<String> = mutableListOf()
        if (dataSize > 0) {
            // region 검색 결과 리스트에 세팅
            try {
                resData?.forEach { item ->
                    val itemObj = item.asJsonObject;
                    var levelState =
                        API_Helper.lidar_levelState(itemObj.get("levelState").asInt)
                    var itemHpid = itemObj.get("hpid").toString().trim('"');
                    hpidList.add(itemHpid)
                    var itemDistance = ""
                    var itemTel = ""
                    var itemTitle = ""
                    ///주소 검색 시 사용하는 곳
                    itemTel = itemObj.get("dutyTel1").toString().trim('"')
                    itemTitle = itemObj.get("dutyName").toString().trim('"')
                    var itemLon = itemObj.get("wgs84Lon").toString().trim('"');
                    var itemLat = itemObj.get("wgs84Lat").toString().trim('"');

                    HospitalSearch.addDataHospitalItems(
                        listOf(
                            HospitalSearch.itemStructure(
                                itemHpid, levelState, itemDistance,
                                itemObj.get("city").toString().trim('"'),
                                itemObj.get("district").toString().trim('"'),
                                itemTel, itemTitle, itemLon, itemLat
                            )
                        )
                    )
                }

                var total_Page = totPages?.asInt;
                if (total_Page == null) total_Page = 0;
                var total_Row = totRows?.asInt;
                if (total_Row == null) total_Row = 0;

//                PaginationHelper.rePaginationLayout(requireView(), { page ->
//                    page_onclick_listener(page)
//                })
//                PaginationHelper.setupPaginationLayout(requireView(), total_Page, total_Row, { page ->
//                    page_onclick_listener(page)
//                })

            } catch (e: Exception) {
                Toast.makeText(requireActivity(), "${e.message}", Toast.LENGTH_LONG)
                    .show()
            } finally {
            }

            hospitalSearchRes = HospitalSearch.getAllData();
        } else {
            AlertDialogUtil.showAlert(
                context = requireActivity(),
                title = "병원 검색 결과",
                message = "병원이 검색되지 않았습니다. 다시 시도해주세요."
            )

            if (!PaginationHelper.pageRequest) PaginationHelper.setupPaginationLayout(
                requireView(),
                0, 0, { page ->
                    page_onclick_listener(page)
                }
            )
        }

        //병원 검색 결과 설정
        if (hospitalSearchRes.size > 0) asAdapter.hospitalListUpdate(hospitalSearchRes, hpidList)
        // endregion
    }

//    fun req_gun_list(si:String) {
//        RetrofitClient.locInstance.getSiGunGuList(JsonObject().apply {
//            addProperty("code", get_si_code(si) ?: "")
//        }).enqueue(siGunGuResponse())
//    }

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

    fun get_default_seonam(): JsonObject {
        var seonam: JsonObject = JsonObject().apply {
            addProperty("userId", "")
            addProperty("carNo", "")
            addProperty("ver", "")
        }

        return seonam;
    }

    override fun onDestroyView() {
        super.onDestroyView()
        FragmentHandler.unregisterView("AddressSearchFragment")
    }

    private fun currentActionResponse(): Callback<JsonObject> {
        return object : Callback<JsonObject> {
            override fun onResponse(call: Call<JsonObject>, response: Response<JsonObject>) {
                if (response.isSuccessful) {
                    try {
                        val resBody = response.body();
                        val status = resBody?.get("status")?.asString;
                        if (status == "true") {
                            TransferManager.serverState.set(true);
                            AlertDialogUtil.showAlert(
                                context = requireContext(),
                                title = "진행 중인 전송 정보",
                                message = "현재 접속 정보로 진행중인 이송 건이 있습니다. 취소하시겠습니까?",
                                onPositiveClick = {
                                    TransferManager.cancelTransfer()
                                },
                                onNegativeClick = {}
                            )
                            //시작된 상황
                        }
                        else {
                            println();
                            TransferManager.serverState.set(false);
                            //시작 아닌 상황
                        }
                    } catch (e: Exception) {
                        println(e.message)
                    }

                } else {
                    println();
                }
            }

            override fun onFailure(call: Call<JsonObject>, t: Throwable) {
                println();
            }
        }
    }
}
