package com.gamedog.vididin.main.fragments.task

import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.view.View
import com.ama.core.common.util.dp
import com.ama.core.common.util.sp
import com.gamedog.vididin.R
import android.graphics.*
import com.ama.core.architecture.BaseApp
import com.ama.core.architecture.util.ResUtil
import com.ama.core.architecture.util.eventbus.NotifyMan
import com.gamedog.vididin.VididinEvents
import com.gamedog.vididin.manager.TaskManager


class WeekStatusView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private var completedColor = Color.parseColor("#4CAF50")
    private var pendingColor = Color.parseColor("#FF9800")
    private var dayColor = Color.parseColor("#FF999999")
    private var dayPastColor = Color.parseColor("#FFD4D4D4")
    private var rewardTextColor = Color.parseColor("#FF9800")
    private var rewardTextSignedColor = Color.parseColor("#999999")
    private var todayHighlightColor = Color.parseColor("#4CAF50")
    private var bgRectColor = Color.parseColor("#ffffedd7")


    private var circleRadius = 46.5F
    private var dayTextSize = 12f.sp.toFloat()
    private var rewardTextSize = 14f.sp.toFloat()
    private var HoriMagin = 5F.dp.toFloat()
    private var vertiMagin = 5F.dp.toFloat()
    private var componentGap = 15F.dp.toFloat()
    private var todayStrokeWidth = 3f.dp.toFloat()
    private var bgRectHeight = 10.dp.toFloat()

    // Paints
    private val bgPaint = Paint().apply {
        isAntiAlias = true
        style = Paint.Style.FILL
        color = bgRectColor
    }
    private val circlePaint = Paint().apply {
        isAntiAlias = true
        style = Paint.Style.FILL
    }
    private val textPaint = Paint().apply {
        isAntiAlias = true
        textAlign = Paint.Align.CENTER
    }


    private val mEventCallback: NotifyMan.ICallback = object : NotifyMan.ICallback(true) {
        override fun onEvent(data: NotifyMan.NotifyData<*>?) {
            invalidate()
        }
    }



    init {
        setupAttributes(attrs)
        initDatas()
    }

    private fun setupAttributes(attrs: AttributeSet?) {
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.WeekStatusView)

        completedColor = typedArray.getColor(R.styleable.WeekStatusView_completedColor, completedColor)
        pendingColor = typedArray.getColor(R.styleable.WeekStatusView_pendingColor, pendingColor)
        dayColor = typedArray.getColor(R.styleable.WeekStatusView_textColor, dayColor)
        rewardTextColor = typedArray.getColor(R.styleable.WeekStatusView_rewardTextColor, rewardTextColor)
        todayHighlightColor = typedArray.getColor(R.styleable.WeekStatusView_todayHighlightColor, todayHighlightColor)

        circleRadius = typedArray.getDimension(R.styleable.WeekStatusView_circleRadius, circleRadius)
        dayTextSize = typedArray.getDimension(R.styleable.WeekStatusView_textSize, dayTextSize)
        rewardTextSize = typedArray.getDimension(R.styleable.WeekStatusView_rewardTextSize, rewardTextSize)
        vertiMagin = typedArray.getDimension(R.styleable.WeekStatusView_itemSpacing, vertiMagin)
        todayStrokeWidth = typedArray.getDimension(R.styleable.WeekStatusView_todayStrokeWidth, todayStrokeWidth)

        typedArray.recycle()
    }

    private fun initDatas() {

    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        NotifyMan.instance().register(mEventCallback, VididinEvents.Event_Sign_State_Changed)
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        NotifyMan.instance().unregister(mEventCallback)
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val desiredWidth = MeasureSpec.getSize(widthMeasureSpec)
        val desiredHeight = (circleRadius * 2 + dayTextSize + rewardTextSize + vertiMagin * 2 + 2*componentGap).toInt()

        setMeasuredDimension(
            resolveSize(desiredWidth, widthMeasureSpec),
            resolveSize(desiredHeight, heightMeasureSpec)
        )
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        val dayStateList = TaskManager.instance().dailySignStatus().getDayStateList()
        if (dayStateList.isEmpty()) return

        val totalWidth = measuredWidth.toFloat()
        val totalItemCount = dayStateList.size
        val itemHoriGapPixel = (totalWidth - 2 * circleRadius - 2 * HoriMagin) / (totalItemCount - 1)

        // bg rect
        val bgTop = vertiMagin + dayTextSize + componentGap + (circleRadius - bgRectHeight/2)
        canvas.drawRect(circleRadius + HoriMagin, bgTop,
            totalWidth - circleRadius - HoriMagin, bgTop + bgRectHeight, bgPaint)

        dayStateList.forEachIndexed { index, dayStatus ->
            val centerX = HoriMagin + circleRadius + itemHoriGapPixel * index

            // day text 'dia'
            textPaint.color = if (dayStatus.hasSigned) dayPastColor else dayColor
            textPaint.textSize = dayTextSize
            canvas.drawText(ResUtil.getString(R.string.day) + " $index", centerX, vertiMagin + dayTextSize/2, textPaint)

            // icons
            val iconRes = if (dayStatus.hasSigned) R.mipmap.task_week_view_done else R.mipmap.task_week_view_ongoing
            canvas.drawBitmap(getBitmap(iconRes)!!, centerX - circleRadius, vertiMagin + dayTextSize + componentGap, circlePaint)

            // reward text
            textPaint.textSize = rewardTextSize
            val rewardNum = TaskManager.instance().dailySignStatus().getRewardNumOfDailySign(index)
            textPaint.color = if (dayStatus.hasSigned) rewardTextSignedColor else rewardTextColor
            canvas.drawText(rewardNum.toString(), centerX, vertiMagin + dayTextSize + componentGap + 2*circleRadius + componentGap, textPaint)
        }
    }


    fun getBitmap(resId: Int): Bitmap? {
        return try {
            BitmapFactory.decodeResource(BaseApp.appContext().resources, resId)
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }




}