package com.b2lmobitech.fieldcloudhrms

import android.app.DatePickerDialog
import android.app.TimePickerDialog
import android.content.Context
import android.os.Bundle
import android.view.View
import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.b2lmobitech.fieldcloudhrms.databinding.ActivityAddLeaveBinding
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale

class AddLeaveActivity : AppCompatActivity() {

    private lateinit var binding: ActivityAddLeaveBinding
    private val calendar = Calendar.getInstance()
    private var accrualType = ""
    private var accrualValue = 1
    private var leaveTypeList = mutableListOf<LeaveType>()
    private var selectedLeaveType: LeaveType? = null
    private var usedDaysForType = 0


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityAddLeaveBinding.inflate(layoutInflater)
        setContentView(binding.root)

        setupLeaveTypeSpinner()
        loadLeaveTypes()
        setupDatePickers()
        setupHalfDay()


        binding.btnBack.setOnClickListener { finish() }

        binding.btnCancel.setOnClickListener { finish() }

        binding.btnSubmit.setOnClickListener { validateAndSubmit() }
    }

    private fun setupLeaveTypeSpinner() {
//        val adapter = ArrayAdapter(
//            this,
//            android.R.layout.simple_spinner_item,
//            resources.getStringArray(R.array.leave_type_array)
//        )
//        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
//        binding.spinnerLeaveType.adapter = adapter

        binding.spinnerLeaveType.onItemSelectedListener =
            object : android.widget.AdapterView.OnItemSelectedListener {
                override fun onItemSelected(
                    parent: android.widget.AdapterView<*>?,
                    view: View?,
                    position: Int,
                    id: Long
                ) {
//                    val leaveType = parent?.getItemAtPosition(position).toString()
                    val selectedLeave = leaveTypeList[position]
                    selectedLeaveType = selectedLeave
                    val leaveType = selectedLeave.leave_type
                    if (!selectedLeave.leave_type.equals("Permission", true)) {
                        fetchLeaveQuotaForType()
                    }

                    if (leaveType.equals("Permission", ignoreCase = true)) {

                        binding.txtPermissionDateLabel.visibility = View.VISIBLE
                        binding.layoutPermissionDate.visibility = View.VISIBLE

                        binding.txtFromDate.text = "Select time"
                        binding.txtToDate.text = "Select time"

                    } else {

                        binding.txtPermissionDateLabel.visibility = View.GONE
                        binding.layoutPermissionDate.visibility = View.GONE

                        binding.txtFromDate.text = "Select date"
                        binding.txtToDate.text = "Select date"
                    }
                }

                override fun onNothingSelected(parent: android.widget.AdapterView<*>?) {}
            }

    }

    private fun setupDatePickers() {

        val dateFormat = SimpleDateFormat("dd-MMM-yyyy", Locale.US)

        binding.layoutPermissionDate.setOnClickListener {
            val dateFormat = SimpleDateFormat("dd-MMM-yyyy", Locale.US)
            val dp = DatePickerDialog(
                this,
                { _, y, m, d ->
                    calendar.set(y, m, d)
                    binding.txtPermissionDate.text = dateFormat.format(calendar.time)
                },
                calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH)
            )
            dp.show()
        }

        binding.layoutFromDate.setOnClickListener {
            val selectedType = binding.spinnerLeaveType.selectedItem.toString()

            if (selectedType.equals("Permission", ignoreCase = true)) {
                // Show time picker
                showTimePicker { time ->
                    binding.txtFromDate.text = time
                }
            } else {
                // Show date picker
                val dp = DatePickerDialog(
                    this,
                    { _, y, m, d ->
                        calendar.set(y, m, d)
                        binding.txtFromDate.text = dateFormat.format(calendar.time)
                    },
                    calendar.get(Calendar.YEAR),
                    calendar.get(Calendar.MONTH),
                    calendar.get(Calendar.DAY_OF_MONTH)
                )
                dp.show()
            }
        }

        binding.layoutToDate.setOnClickListener {
            val selectedType = binding.spinnerLeaveType.selectedItem.toString()

            if (selectedType.equals("Permission", ignoreCase = true)) {
                // Show time picker
                showTimePicker { time ->
                    binding.txtToDate.text = time
                }
            } else {
                // Show date picker
                val dp = DatePickerDialog(
                    this,
                    { _, y, m, d ->
                        calendar.set(y, m, d)
                        binding.txtToDate.text = dateFormat.format(calendar.time)
                    },
                    calendar.get(Calendar.YEAR),
                    calendar.get(Calendar.MONTH),
                    calendar.get(Calendar.DAY_OF_MONTH)
                )
                dp.show()
            }
        }
    }

    private fun validateAndSubmit() {
        val leaveType = if(binding.spinnerLeaveType.selectedItem.toString() != "Permission"){selectedLeaveType!!.leave_type_id} else {binding.spinnerLeaveType.selectedItem.toString()}
        val from = binding.txtFromDate.text.toString()
        val to = binding.txtToDate.text.toString()
        val reason = binding.etReason.text.toString()
        var permissionMinutes = ""
        var leaveDays = ""
        val selectedLeave = selectedLeaveType

        val permissiondate = if (leaveType == "Permission") {
            binding.txtPermissionDate.text.toString()
        } else {""}

        if (leaveType.isEmpty()) {
            Toast.makeText(this, "Select leave type", Toast.LENGTH_SHORT).show()
            return
        }
        if (leaveType == "Permission" && from == "Select time") {
            Toast.makeText(this, "Select from time", Toast.LENGTH_SHORT).show()
            return
        } else if (from == "Select date"){
            Toast.makeText(this, "Select from date", Toast.LENGTH_SHORT).show()
            return
        }
        if (leaveType == "Permission" && to == "Select time") {
            Toast.makeText(this, "Select to time", Toast.LENGTH_SHORT).show()
            return
        } else if (to == "Select date"){
            Toast.makeText(this, "Select to date", Toast.LENGTH_SHORT).show()
            return
        }
        if (leaveType == "Permission" && permissiondate == "Select date") {
            Toast.makeText(this, "Select Permission date", Toast.LENGTH_SHORT).show()
            return
        }
        if (leaveType == "Permission") {
            permissionMinutes = calculateMinutes(from, to).toString()
        } else {
            leaveDays = calculateDays(from, to).toString()
        }
        if (leaveType != "Permission" && selectedLeave != null) {

            val allowedDays = selectedLeave.yearly_quota.toIntOrNull() ?: 0
            val appliedDays = leaveDays.toIntOrNull() ?: 0
            val totalAppliedDays = appliedDays + usedDaysForType

            if (totalAppliedDays > allowedDays) {
                Toast.makeText(
                    this,
                    "You can apply for only $allowedDays day(s).\n" +
                            "Applying $appliedDays exceeds quota ($allowedDays).",
                    Toast.LENGTH_LONG
                ).show()
                return
            }
        }
        val isHalfDay = binding.chkHalfDay.isChecked
        val HalfDay = if (isHalfDay) "yes" else "no"
        if (isHalfDay) {
            leaveDays = "0.5"
        }
        val halfDayType =
            if (isHalfDay) binding.spinnerHalfDayType.selectedItem.toString() else ""

        if (isHalfDay && halfDayType.isEmpty()) {
            Toast.makeText(this, "Select half day type", Toast.LENGTH_SHORT).show()
            return
        }


        submitLeaveToServer(leaveType, from, to, reason, permissiondate, permissionMinutes, leaveDays, HalfDay, halfDayType)
    }

    private fun submitLeaveToServer(
        leaveType: String,
        from: String,
        to: String,
        reason: String,
        permissiondate: String,
        permissionMinutes: String,
        leaveDays: String,
        HalfDay: String,
        halfDayType: String
    ) {
        binding.progressBar.visibility = View.VISIBLE

        val sharedPref = getSharedPreferences("login_pref", Context.MODE_PRIVATE)
        val userId = sharedPref.getString("user_id", "")!!
        val orgId = sharedPref.getString("org_id", "")!!
        val mysqlFrom = if (leaveType == "Permission") formatTimeForMysql(from) else formatForMysql(from)
        val mysqlTo = if (leaveType == "Permission") formatTimeForMysql(to) else formatForMysql(to)
        val mysqlPermissionDate = if (leaveType == "Permission") formatForMysql(permissiondate) else ""

        val apiService = RetrofitClient.instance

        val call = apiService.applyLeave(
            people_id = userId,
            org_id = orgId,
            leave_type = leaveType,
            from = mysqlFrom,
            to = mysqlTo,
            reason = reason,
            permissiondate = mysqlPermissionDate,
            permissionMinutes = permissionMinutes,
            leaveDays =leaveDays,
            halfday = HalfDay,
            halfdaytype = halfDayType
        )

        call.enqueue(object : Callback<SimpleResponse> {
            override fun onResponse(call: Call<SimpleResponse>, response: Response<SimpleResponse>) {
                binding.progressBar.visibility = View.GONE

                if (response.isSuccessful && response.body()?.status == true) {
                    Toast.makeText(
                        this@AddLeaveActivity,
                        "Leave applied successfully",
                        Toast.LENGTH_SHORT
                    ).show()
                    finish()
                } else {
                    Toast.makeText(
                        this@AddLeaveActivity,
                        "Failed: " + response.body()?.message,
                        Toast.LENGTH_SHORT
                    ).show()
                }
            }

            override fun onFailure(call: Call<SimpleResponse>, t: Throwable) {
                binding.progressBar.visibility = View.GONE
                Toast.makeText(
                    this@AddLeaveActivity,
                    "Error: ${t.message}",
                    Toast.LENGTH_SHORT
                ).show()
            }
        })
    }

    private fun showTimePicker(onTimeSelected: (String) -> Unit) {
        val hour = calendar.get(Calendar.HOUR_OF_DAY)
        val minute = calendar.get(Calendar.MINUTE)

        TimePickerDialog(this, { _, h, m ->
            val formatted = String.format(
                Locale.US, "%02d:%02d %s",
                (if (h == 0 || h == 12) 12 else h % 12),
                m,
                if (h < 12) "AM" else "PM"
            )
            onTimeSelected(formatted)
        }, hour, minute, false).show()
    }

    private fun calculateMinutes(from: String, to: String): Int {
        val format = SimpleDateFormat("hh:mm a", Locale.US)
        val start = format.parse(from)
        val end = format.parse(to)
        return ((end.time - start.time) / 60000).toInt()
    }

    private fun calculateDays(from: String, to: String): Int {
        val format = SimpleDateFormat("dd-MMM-yyyy", Locale.US)
        val start = format.parse(from)
        val end = format.parse(to)
        val diff = ((end.time - start.time) / (1000 * 60 * 60 * 24)).toInt() + 1
        if (accrualType == "monthly" && diff > selectedLeaveType!!.yearly_quota!!.toInt()) {
            Toast.makeText(
                this,
                "Only ${selectedLeaveType!!.yearly_quota} day(s) allowed per ${accrualValue} month(es)",
                Toast.LENGTH_LONG
            ).show()
            return diff
        }

        return diff
    }

    private fun formatForMysql(date: String): String {
        val input = SimpleDateFormat("dd-MMM-yyyy", Locale.US)
        val output = SimpleDateFormat("yyyy-MM-dd", Locale.US)
        val parsed = input.parse(date)
        return output.format(parsed)
    }

    private fun formatTimeForMysql(time: String): String {
        val input = SimpleDateFormat("hh:mm a", Locale.US)   // 12-hour
        val output = SimpleDateFormat("HH:mm:00", Locale.US) // 24-hour with zero seconds
        val parsed = input.parse(time)
        return output.format(parsed)
    }

    private fun loadLeaveTypes() {

        val pref = getSharedPreferences("login_pref", Context.MODE_PRIVATE)
        val peopleId = pref.getString("user_id", "")!!
        val orgId = pref.getString("org_id", "")!!

        RetrofitClient.instance.getLeaveTypes(peopleId, orgId)
            .enqueue(object : Callback<LeaveTypeResponse> {

                override fun onResponse(
                    call: Call<LeaveTypeResponse>,
                    response: Response<LeaveTypeResponse>
                ) {
                    if (response.isSuccessful && response.body()?.status == true) {

                        val data = response.body()!!

                        leaveTypeList.clear()

                        accrualType = data.accrual_type
                        accrualValue = data.accrual_value.toInt()
                        leaveTypeList = data.leave_types.toMutableList()

                        leaveTypeList.add(
                            LeaveType(
                                leave_type_id = "permission_",
                                leave_type = "Permission",
                                yearly_quota = "100000"
                            )
                        )


                        val names = leaveTypeList.map { it.leave_type }

                        val adapter = ArrayAdapter(
                            this@AddLeaveActivity,
                            android.R.layout.simple_spinner_item,
                            names
                        )
                        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
                        binding.spinnerLeaveType.adapter = adapter
                    } else {
                        Toast.makeText(
                            this@AddLeaveActivity,
                            response.body()?.message,
                            Toast.LENGTH_SHORT
                        ).show()
                        leaveTypeList.clear()
                        leaveTypeList.add(
                            LeaveType(
                                leave_type_id = "permission_",
                                leave_type = "Permission",
                                yearly_quota = "100000"
                            )
                        )
                        val names = leaveTypeList.map { it.leave_type }

                        val adapter = ArrayAdapter(
                            this@AddLeaveActivity,
                            android.R.layout.simple_spinner_item,
                            names
                        )
                        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
                        binding.spinnerLeaveType.adapter = adapter
                    }
                }

                override fun onFailure(call: Call<LeaveTypeResponse>, t: Throwable) {
                    Toast.makeText(
                        this@AddLeaveActivity,
                        "Failed to load leave types",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            })
    }

    private fun setupHalfDay() {

        val halfDayTypes = listOf("First Half", "Second Half")

        val adapter = ArrayAdapter(
            this,
            android.R.layout.simple_spinner_item,
            halfDayTypes
        )
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
        binding.spinnerHalfDayType.adapter = adapter

        binding.chkHalfDay.visibility = View.GONE

        binding.chkHalfDay.setOnCheckedChangeListener { _, isChecked ->

            val leaveType = selectedLeaveType?.leave_type ?: ""

            binding.txtHalfDayTypeLabel.visibility =
                if (isChecked) View.VISIBLE else View.GONE

            binding.spinnerHalfDayType.visibility =
                if (isChecked) View.VISIBLE else View.GONE
        }
    }

    private fun fetchLeaveQuotaForType() {

        val pref = getSharedPreferences("login_pref", Context.MODE_PRIVATE)
        val peopleId = pref.getString("user_id", "")!!
        val orgId = pref.getString("org_id", "")!!

        val leave = selectedLeaveType ?: return

        RetrofitClient.instance.checkLeaveQuota(
            peopleId,
            orgId,
            leave.leave_type_id,
            leave.yearly_quota
        ).enqueue(object : Callback<LeaveQuotaResponse> {

            override fun onResponse(
                call: Call<LeaveQuotaResponse>,
                response: Response<LeaveQuotaResponse>
            ) {
                if (response.isSuccessful && response.body() != null) {

                    usedDaysForType = response.body()!!.used_days
                    val quota = leave.yearly_quota.toInt()
                    val remaining = quota - usedDaysForType

                    if (remaining <= 0) {
                        Toast.makeText(
                            this@AddLeaveActivity,
                            "No remaining $quota days left for this leave type this month",
                            Toast.LENGTH_LONG
                        ).show()
                    } else {
                        Toast.makeText(
                            this@AddLeaveActivity,
                            "$remaining day(s) remaining for this leave type",
                            Toast.LENGTH_SHORT
                        ).show()
                    }
                }
            }

            override fun onFailure(call: Call<LeaveQuotaResponse>, t: Throwable) {
                Toast.makeText(
                    this@AddLeaveActivity,
                    "Unable to check leave quota",
                    Toast.LENGTH_SHORT
                ).show()
            }
        })
    }



}
