package com.za.ui.order_report

import android.annotation.SuppressLint
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.graphics.PixelFormat
import android.os.Build
import android.os.IBinder
import android.provider.Settings
import android.view.Gravity
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
import android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
import android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
import android.view.WindowManager.LayoutParams.TYPE_PHONE
import android.view.WindowManager.LayoutParams.WRAP_CONTENT
import android.view.animation.OvershootInterpolator
import android.widget.ImageView
import androidx.core.app.NotificationCompat
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.ServiceUtils
import com.za.servicing.R
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlin.math.abs

class ReportFloatingManager : Service() {
	private var windowManager : WindowManager? = null
	private var floatingView : View? = null
	private var touchJob : Job? = null
	private var initialX : Int = 0
	private var initialY : Int = 0
	private var initialTouchX : Float = 0f
	private var initialTouchY : Float = 0f
	private var isMoving = false
	private var startClickTime = 0L
	private lateinit var prefs : SharedPreferences
	private var lastUpdateTime = 0L
	private var screenWidth = 0
	private var screenHeight = 0
	private var viewWidth = 0
	private var viewHeight = 0
	private var isDragging = false

	private val params = WindowManager.LayoutParams(WRAP_CONTENT,
		WRAP_CONTENT,
		getWindowType(),
		FLAG_NOT_FOCUSABLE or FLAG_NOT_TOUCH_MODAL,
		PixelFormat.TRANSLUCENT)

	private fun getWindowType() : Int {
		return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
			TYPE_APPLICATION_OVERLAY
		} else {
			TYPE_PHONE
		}
	}

	override fun onBind(intent : Intent?) : IBinder? = null

	override fun onCreate() {
		super.onCreate()
		lastUpdateTime = System.currentTimeMillis()
		prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE)
		initializeFloatingWindow()
		setupTouchListener()
		createNotificationChannel()
		startForeground(NOTIFICATION_ID, createNotification())
	}

	private fun initializeFloatingWindow() {
		windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
		floatingView = LayoutInflater.from(this).inflate(R.layout.floating_view_layout, null)

		// 获取屏幕尺寸
		val metrics = resources.displayMetrics
		screenWidth = metrics.widthPixels
		screenHeight = metrics.heightPixels

		// 测量视图尺寸
		floatingView?.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
		viewWidth = floatingView?.measuredWidth ?: 0
		viewHeight = floatingView?.measuredHeight ?: 0

		// 确保初始位置在屏幕内
		params.apply {
			gravity = Gravity.TOP or Gravity.START
			x = validateX(prefs.getInt(PREF_X, 0))
			y = validateY(prefs.getInt(PREF_Y, 100))
		}

		// 设置应用图标
		floatingView?.findViewById<ImageView>(R.id.floating_image)
			?.setImageResource(R.drawable.sv_order_report)

		windowManager?.addView(floatingView, params)
		animateWindowAppear()
	}

	private fun animateWindowAppear() {
		floatingView?.apply {
			alpha = 0f
			scaleX = 0.5f
			scaleY = 0.5f
			animate().alpha(1f).scaleX(1f).scaleY(1f).setDuration(300)
				.setInterpolator(OvershootInterpolator()).start()
		}
	}

	@SuppressLint("ClickableViewAccessibility")
	private fun setupTouchListener() {
		floatingView?.setOnTouchListener { _, event ->
			when (event.action) {
				MotionEvent.ACTION_DOWN -> handleTouchDown(event)
				MotionEvent.ACTION_MOVE -> handleTouchMove(event)
				MotionEvent.ACTION_UP -> handleTouchUp()
				else -> false
			}
		}
	}

	private fun handleTouchDown(event : MotionEvent) : Boolean {
		isDragging = false
		isMoving = false
		startClickTime = System.currentTimeMillis()
		initialX = params.x
		initialY = params.y
		initialTouchX = event.rawX
		initialTouchY = event.rawY

		// 缩小效果
		floatingView?.animate()?.scaleX(0.95f)?.scaleY(0.95f)?.setDuration(100)?.start()

		return true
	}

	private fun handleTouchMove(event : MotionEvent) : Boolean {
		touchJob?.cancel()
		touchJob = CoroutineScope(Dispatchers.Main).launch {
			val deltaX = (event.rawX - initialTouchX).toInt()
			val deltaY = (event.rawY - initialTouchY).toInt()

			if (! isDragging && (abs(deltaX) > MOVE_THRESHOLD || abs(deltaY) > MOVE_THRESHOLD)) {
				isDragging = true
				isMoving = true // 开始拖动时的视觉反馈
				floatingView?.alpha = 0.8f
			}

			if (isDragging) {
				params.x = validateX(initialX + deltaX)
				params.y = validateY(initialY + deltaY)
				try {
					windowManager?.updateViewLayout(floatingView, params)
				} catch (e : Exception) {
					e.printStackTrace()
				}
			}
		}
		return true
	}

	private fun handleTouchUp() : Boolean {
		touchJob?.cancel()

		// 恢复原始状态
		floatingView?.apply {
			animate().scaleX(1f).scaleY(1f).alpha(1f).setDuration(100).start()
		}

		if (! isMoving && System.currentTimeMillis() - startClickTime < CLICK_THRESHOLD) {
			openMainActivity()
		} else if (isDragging) { // 只保存位置，不执行吸附
			savePosition()
		}

		isDragging = false
		return true
	}

	private fun openMainActivity() { // 否则打开主页面
		if (ActivityUtils.getTopActivity() is OrderReportActivity) {
			return
		}
		val intent = Intent(this, OrderReportActivity::class.java).apply {
			flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
		}
		startActivity(intent)
	}

	override fun onStartCommand(intent : Intent?, flags : Int, startId : Int) : Int {
		return START_STICKY
	}

	override fun onDestroy() {
		super.onDestroy()
		touchJob?.cancel()
		windowManager?.removeView(floatingView)
	}

	private fun validateX(x : Int) : Int {
		return x.coerceIn(- viewWidth / 2, screenWidth - viewWidth / 2)
	}

	private fun validateY(y : Int) : Int {
		val statusBarHeight = getStatusBarHeight()
		return y.coerceIn(statusBarHeight, screenHeight - viewHeight - getNavigationBarHeight())
	}

	private fun getStatusBarHeight() : Int {
		val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
		return if (resourceId > 0) {
			resources.getDimensionPixelSize(resourceId)
		} else {
			0
		}
	}

	private fun getNavigationBarHeight() : Int {
		val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android")
		return if (resourceId > 0) {
			resources.getDimensionPixelSize(resourceId)
		} else {
			0
		}
	}

	private fun savePosition() {
		prefs.edit().putInt(PREF_X, params.x).putInt(PREF_Y, params.y).apply()
	}


	private fun createNotificationChannel() {
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
			val channel = NotificationChannel(CHANNEL_ID,
				"悬浮窗服务",
				NotificationManager.IMPORTANCE_LOW).apply {
				description = "保持应用在后台运行"
			}

			val notificationManager =
				getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
			notificationManager.createNotificationChannel(channel)
		}
	}

	private fun createNotification() =
		NotificationCompat.Builder(this, CHANNEL_ID).setContentTitle("应用正在后台运行")
			.setContentText("点击返回应用").setSmallIcon(R.mipmap.ic_launcher)
			.setPriority(NotificationCompat.PRIORITY_LOW).build()

	// 检查悬浮窗权限

	companion object {
		private const val PREFS_NAME = "report_floating_window_prefs"
		private const val PREF_X = "report_window_x"
		private const val PREF_Y = "report_window_y"
		private const val MOVE_THRESHOLD = 10
		private const val CLICK_THRESHOLD = 200L
		private const val NOTIFICATION_ID = 1
		private const val CHANNEL_ID = "floating_window_channel"

		@SuppressLint("ObsoleteSdkInt")
		private fun checkOverlayPermission(context : Context) : Boolean {
			return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
				Settings.canDrawOverlays(context)
			} else {
				true
			}
		}

		fun startService(context : Context) {
			if (ServiceUtils.isServiceRunning(ReportFloatingManager::class.java)) {
				return
			}
			if (checkOverlayPermission(context)) {
				ServiceUtils.startService(ReportFloatingManager::class.java)
			}
		}

		fun stopService() {
			if (ServiceUtils.isServiceRunning(ReportFloatingManager::class.java)) {
				ServiceUtils.stopService(ReportFloatingManager::class.java)
			}
		}
	}

}