package com.za.ui.servicing.wait_to_start

import com.amap.api.maps.AMapUtils
import com.amap.api.maps.model.BitmapDescriptorFactory
import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.MarkerOptions
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.route.BusRouteResult
import com.amap.api.services.route.DriveRouteResult
import com.amap.api.services.route.RideRouteResult
import com.amap.api.services.route.RouteSearch
import com.amap.api.services.route.WalkRouteResult
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.ToastUtils
import com.za.base.IServicingVm
import com.za.base.view.LoadingManager
import com.za.bean.db.order.OrderInfo
import com.za.bean.request.UpdateTaskBean
import com.za.bean.request.UpdateTaskRequest
import com.za.common.GlobalData
import com.za.common.log.LogUtil
import com.za.common.util.ImageUtil
import com.za.ext.toJson
import com.za.net.CommonMethod
import com.za.service.location.ZdLocationManager
import com.za.servicing.R
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale

class WaitToStartVm : IServicingVm<WaitToStartVm.Action, WaitToStartVm.UiState>() {
	private val _uiState = MutableStateFlow(UiState())
	val uiState get() = _uiState
	override fun updateState(uiState : UiState) {
		_uiState.value = uiState
	}

	override fun dispatch(action : Action) {
		when (action) {
			is Action.Init -> init()
			is Action.UpdateTask -> updateTask()
			is Action.UpdateState -> updateState(action.uiState)
			is Action.StartTimer -> startTimer()
			is Action.UpdateTimer -> updateTimer()
		}
	}

	private fun updateTask() {
		LoadingManager.showLoading()
		ZdLocationManager.getSingleLocation(success = {
			LoadingManager.hideLoading()
			val taskRequest = UpdateTaskRequest(type = "START",
				taskId = getCurrentOrder()?.taskId,
				userId = GlobalData.driverInfoBean?.userId,
				vehicleId = GlobalData.driverInfoBean?.vehicleId,
				currentState = getCurrentOrder()?.taskState,
				offlineMode = 0,
				operateTime = System.currentTimeMillis().toString(),
				lat = it.latitude,
				lng = it.longitude)
			doUploadTask(request = taskRequest)
		}, failed = {
			LoadingManager.hideLoading()
			ToastUtils.showShort(it)
		})
	}

	private fun doUploadTask(request : UpdateTaskRequest) {
		LoadingManager.showLoading()
		CommonMethod.updateTask(request, success = { data ->
			LoadingManager.hideLoading()
			updateOrder(getCurrentOrder()?.copy(taskState = data?.nextState))
			updateState(uiState.value.copy(goNextPage = data, orderInfo = getCurrentOrder()))
		}, failed = { msg, _ ->
			LoadingManager.hideLoading()
			ToastUtils.showShort(msg)
			LogUtil.print("$tag doUploadTask", "状态更新失败==${request.toJson()} msg==$msg")
		})
	}

	private fun init() {
		val order = getCurrentOrder()
		updateState(uiState = uiState.value.copy(orderInfo = order))
		buildMarkers(order)
		searchDrivingRoute(order)
		dispatch(Action.StartTimer)
	}

	private fun buildMarkers(orderInfo : OrderInfo?) {
		val markers = arrayListOf<MarkerOptions>()

		// 添加救援地点标记
		if (orderInfo?.lat != null && orderInfo.lat != 0.0 && orderInfo.lng != null && orderInfo.lng != 0.0) {

			val startMarker = MarkerOptions().position(LatLng(orderInfo.lat !!, orderInfo.lng !!))
				.title(orderInfo.address).snippet("救援地点")
				.icon(BitmapDescriptorFactory.fromResource(R.mipmap.sv_rescuing_map))
				.anchor(0.5f, 0.5f).zIndex(2f).visible(true)

			markers.add(startMarker)
		}

		// 添加目的地标记
		if (orderInfo?.distLat != null && orderInfo.distLat != 0.0 && orderInfo.distLng != null && orderInfo.distLng != 0.0) {

			val destMarker =
				MarkerOptions().position(LatLng(orderInfo.distLat !!, orderInfo.distLng !!))
					.title(orderInfo.distAddress).snippet("目的地").icon(ImageUtil.vectorToBitmap(
						ActivityUtils.getTopActivity(),
						R.drawable.sv_map_dist)).anchor(0.5f, 0.5f).zIndex(2f).visible(true)

			markers.add(destMarker)
		}

		updateState(uiState.value.copy(markers = markers))
	}

	private fun searchDrivingRoute(orderInfo : OrderInfo?) { // 如果没有当前位置，则不进行路径规划
		if (GlobalData.currentLocation == null) return

		val startPoint = LatLonPoint(GlobalData.currentLocation?.latitude ?: 0.0,
			GlobalData.currentLocation?.longitude ?: 0.0)

		// 获取救援地点坐标
		val rescuePoint =
			if (orderInfo?.lat != null && orderInfo.lat != 0.0 && orderInfo.lng != null && orderInfo.lng != 0.0) {
				LatLonPoint(orderInfo.lat !!, orderInfo.lng !!)
			} else null

		// 如果没有救援地点，则不进行规划
		if (rescuePoint == null) {
			LogUtil.print("searchDrivingRoute", "没有有效的终点")
			return
		}

		// 使用 Application Context
		RouteSearch(GlobalData.application).apply {
			setRouteSearchListener(object : RouteSearch.OnRouteSearchListener {
				override fun onDriveRouteSearched(result : DriveRouteResult?, errorCode : Int) {
					if (errorCode == 1000 && result != null && result.paths.isNotEmpty()) {
						val path = result.paths[0]
						val points = path.steps.flatMap { step ->
							step.polyline.map { LatLng(it.latitude, it.longitude) }
						}
						val duration = path.duration
						val arrivalTime = System.currentTimeMillis() + duration * 1000
						val dateFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
						val estimatedTime = dateFormat.format(Date(arrivalTime))
						updateState(uiState.value.copy(routePoints = points,
							estimatedArrivalTime = estimatedTime,
							remainingDistance = path.distance))
					} else {
						LogUtil.print("searchDrivingRoute", "路径规划失败: errorCode=$errorCode")
					}
				}

				override fun onBusRouteSearched(p0 : BusRouteResult?, p1 : Int) {}
				override fun onWalkRouteSearched(p0 : WalkRouteResult?, p1 : Int) {}
				override fun onRideRouteSearched(p0 : RideRouteResult?, p1 : Int) {}
			})

			val fromAndTo = RouteSearch.FromAndTo(startPoint, rescuePoint)
			val query =
				RouteSearch.DriveRouteQuery(fromAndTo, RouteSearch.DrivingDefault, null, null, "")
			calculateDriveRouteAsyn(query)
		}
	}

	private var timerJob : Job? = null

	private fun startTimer() { //		timerJob?.cancel()
		//		timerJob = viewModelScope.launch {
		//			while (isActive) { // 计算从当前位置到目标点的距离和到达时间
		//				val (distance, arrivalTime) = calculateRemainingDistance()
		//				_uiState.update {
		//					it.copy(remainingDistance = distance, estimatedArrivalTime = arrivalTime)
		//				}
		//				delay(1000) // 每秒更新一次
		//			}
		//		}
	}

	private fun calculateRemainingDistance() : Pair<Float, String> {
		val currentLocation = GlobalData.currentLocation ?: return Pair(0f, "")
		val orderInfo = _uiState.value.orderInfo ?: return Pair(0f, "")

		// 计算到救援地点的距离
		val rescueDistance = if (orderInfo.lat != null && orderInfo.lng != null) {
			AMapUtils.calculateLineDistance(LatLng(currentLocation.latitude,
				currentLocation.longitude), LatLng(orderInfo.lat !!, orderInfo.lng !!))
		} else 0f

		// 计算到目的地的距离
		val destDistance = if (orderInfo.distLat != null && orderInfo.distLng != null) {
			AMapUtils.calculateLineDistance(LatLng(currentLocation.latitude,
				currentLocation.longitude), LatLng(orderInfo.distLat !!, orderInfo.distLng !!))
		} else 0f

		// 取较短的距离
		val shortestDistance = minOf(rescueDistance.takeIf { it > 0f } ?: Float.MAX_VALUE,
			destDistance.takeIf { it > 0f } ?: Float.MAX_VALUE)

		if (shortestDistance == Float.MAX_VALUE) {
			return Pair(0f, "")
		}

		// 计算预计到达时间（假设平均速度40km/h）
		val timeInSeconds = ((shortestDistance / 1000.0 * 60.0 / 40.0) * 60).toInt()
		val calendar = Calendar.getInstance()
		calendar.add(Calendar.SECOND, timeInSeconds)
		val arrivalTime = SimpleDateFormat("HH:mm", Locale.getDefault()).format(calendar.time)

		return Pair(shortestDistance, arrivalTime)
	}

	private fun updateTimer() { // 在这里处理倒计时更新逻辑
	}

	override fun onCleared() {
		super.onCleared()
		timerJob?.cancel()
	}

	sealed class Action {
		data object Init : Action()
		data object UpdateTask : Action()
		data class UpdateState(val uiState : UiState) : Action()
		data object StartTimer : Action()
		data object UpdateTimer : Action()
	}

	data class UiState(val orderInfo : OrderInfo? = null,
		val showCallPhoneDialog : Boolean? = false,
		val markers : ArrayList<MarkerOptions>? = null,
		val goNextPage : UpdateTaskBean? = null,
		val isGoNextPageDialog : Boolean? = null,
		val routePoints : List<LatLng>? = null,
		val remainingDistance : Float = 0f,
		val showServicePeopleConfirmDialog : Boolean? = false,
		val estimatedArrivalTime : String = "")
}