package com.za.water_marker

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Matrix
import android.graphics.Typeface
import android.text.Layout
import android.text.StaticLayout
import android.text.TextPaint
import androidx.exifinterface.media.ExifInterface
import com.blankj.utilcode.util.ConvertUtils
import com.blankj.utilcode.util.DeviceUtils
import com.blankj.utilcode.util.ScreenUtils
import com.za.bean.db.water_marker.WaterMarkerTemplateAndItemRef
import com.za.common.GlobalData
import com.za.common.log.LogUtil
import com.za.common.util.AppFileManager
import com.za.common.util.ImageUtil
import com.za.water_marker.bean.PhotoMarkerInfo
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.Locale

/**
 * 照片水印
 */
object PhotoMarkerManager {
    fun addPhotoMarker(context: Context, photoMarkerInfo: PhotoMarkerInfo): String {
        val waterMarkerTemplateAndItemRef = WaterMarkerTemplateManager.getWaterMarkerTemplate(photoMarkerInfo.taskCode)
        if (waterMarkerTemplateAndItemRef == null) {
            LogUtil.print("使用原有代码中的水印", "info==$photoMarkerInfo")
            return addPhotoMarkerLocal(context, photoMarkerInfo)
        } else {
            LogUtil.print("使用水印模版", "info==$photoMarkerInfo")
            var bitmap = handlerBitmapRotate(photoMarkerInfo.path ?: "")
            if (photoMarkerInfo.needMark == true) {
                bitmap = doAddPhotoMarker(context, photoMarkerInfo, bitmap, waterMarkerTemplateAndItemRef)
            }
            val baos = ByteArrayOutputStream()
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
            return saveBitmap(context, baos)
        }
    }

    @SuppressLint("DefaultLocale")
    private fun doAddPhotoMarker(context: Context,
                                 info: PhotoMarkerInfo,
                                 paramsBitmap: Bitmap,
                                 waterMarkerTemplateAndItemRef: WaterMarkerTemplateAndItemRef): Bitmap {
        val bitmapConfig = paramsBitmap.config
        val bitmap = paramsBitmap.copy(bitmapConfig!!, true)

        val textPaint = TextPaint()
        textPaint.setTypeface(Typeface.createFromAsset(context.assets, "fonts/song.ttf"))
        textPaint.isFakeBoldText = true
        textPaint.isAntiAlias = true

        for (waterMarkerItemBean in waterMarkerTemplateAndItemRef.waterMarkerItemBeanList!!) {
            LogUtil.print("waterMarkerItemBean==", waterMarkerItemBean.toString())
            val content = if (info.needShowPhoneBrand == true) {
                waterMarkerItemBean.content?.replace("@", "")
                    ?.replace("{phoneBrand}", DeviceUtils.getManufacturer() + "  " + DeviceUtils.getModel())
                    ?.replace("{address}", info.address ?: "")
                    ?.replace("{driverName}", info.driverName ?: "")
                    ?.replace("{photoSource}", info.from ?: "")
                    ?.replace("{orderCode}", info.taskCode ?: "")
                    ?.replace("{photoTime}", info.time ?: "")
                    ?.replace("{lat}", java.lang.String.format("%.6f", info.lat))
                    ?.replace("{lng}", java.lang.String.format("%.6f", info.lng))
            } else {
                waterMarkerItemBean.content?.replace("@", "")
                    ?.replace("{phoneBrand}", "")
                    ?.replace("{address}", info.address ?: "")
                    ?.replace("{driverName}", info.driverName ?: "")
                    ?.replace("{photoSource}", info.from ?: "")
                    ?.replace("{orderCode}", info.taskCode ?: "")
                    ?.replace("{photoTime}", info.time ?: "")
                    ?.replace("{lat}", java.lang.String.format("%.6f", info.lat))
                    ?.replace("{lng}", java.lang.String.format("%.6f", info.lng))
            }

            val canvas = Canvas(bitmap)
            canvas.drawBitmap(bitmap, 0f, 0f, null)
            textPaint.setColor(Color.parseColor(waterMarkerItemBean.color))
            if (bitmap.width > bitmap.height) {
                textPaint.textSize = bitmap.width.times(waterMarkerItemBean.wideFont?.toFloatOrNull()
                    ?: 10f)
            } else {
                textPaint.textSize = bitmap.width.times(waterMarkerItemBean.highFont?.toFloatOrNull()
                    ?: 10f)
            }

            val sh: Int = bitmap.height / ScreenUtils.getAppScreenHeight() //高度比

            //文字最大宽度
            val staticLayoutWidth = (canvas.width * 0.5).toInt()

            var sl: StaticLayout? = null
            //居右
            if (waterMarkerItemBean.left == -1.0) {
                sl = getStaticLayout(staticLayoutWidth, content
                    ?: "", textPaint, Layout.Alignment.ALIGN_OPPOSITE)
                if (waterMarkerItemBean.bottom == -1.0) {
                    canvas.translate((canvas.width - sl.width - ConvertUtils.dp2px(waterMarkerItemBean.right.toFloat()) * sh).toFloat(), (ConvertUtils.dp2px(waterMarkerItemBean.top.toFloat()) * sh).toFloat())
                } else {
                    canvas.translate((canvas.width - sl.width - ConvertUtils.dp2px(waterMarkerItemBean.right.toFloat()) * sh).toFloat(), (bitmap.height - sl.height - ConvertUtils.dp2px(waterMarkerItemBean.bottom.toFloat() * sh)).toFloat())
                }
            } else if (waterMarkerItemBean.right == -1.0) { //居左
                sl = getStaticLayout(staticLayoutWidth, content
                    ?: "", textPaint, Layout.Alignment.ALIGN_NORMAL)
                if (waterMarkerItemBean.bottom == -1.0) {
                    canvas.translate((ConvertUtils.dp2px(waterMarkerItemBean.left.toFloat()) * sh).toFloat(), (ConvertUtils.dp2px(waterMarkerItemBean.top.toFloat()) * sh).toFloat())
                } else {
                    canvas.translate((ConvertUtils.dp2px(waterMarkerItemBean.left.toFloat()) * sh).toFloat(), (bitmap.height - sl.height - ConvertUtils.dp2px(waterMarkerItemBean.bottom.toFloat() * sh)).toFloat())
                }
            }
            sl?.draw(canvas)
        }
        return bitmap
    }

    private fun getStaticLayout(width: Int, content: String, textPaint: TextPaint, alignment: Layout.Alignment): StaticLayout {
        val sl = StaticLayout.Builder.obtain(content, 0, content.length, textPaint, width)
            .setLineSpacing(0f, 1.3f)
            .setAlignment(alignment)
            .build()
        return sl
    }

    private fun saveBitmap(context: Context, baos: ByteArrayOutputStream): String {
        var cacheFile: File? = null
        try {
            cacheFile = if (GlobalData.currentOrder == null) {
                File(AppFileManager.orderWaterMarkerPath(context), "${System.currentTimeMillis()}_marked.jpg")
            } else {
                File(AppFileManager.orderWaterMarkerPath(context), "${GlobalData.currentOrder?.taskCode}_${System.currentTimeMillis()}_marked.jpg")
            }
            val fos = FileOutputStream(cacheFile)
            fos.write(baos.toByteArray())
            fos.flush()
            fos.close()
        } catch (e: Exception) {
            LogUtil.print("ImageMonitor", "ImageMonitor addPhotoMarker AddMarker exception" + e.message)
        } finally {
            try {
                baos.flush()
                baos.close()
            } catch (e: IOException) {
                LogUtil.print("ImageMonitor2", "ImageMonitor addPhotoMarker AddMarker exception" + e.message)
            }
        }
        return if (null != cacheFile) cacheFile.absolutePath else ""
    }

    private fun handlerBitmapRotate(path: String): Bitmap {
        LogUtil.print("addPhotoMarker", "PhotoMarkerInfo==$path")
        var bitmap: Bitmap = BitmapFactory.decodeFile(path)
        // 旋转
        var exifInterface: ExifInterface? = null
        try {
            exifInterface = ExifInterface(path)
        } catch (e: IOException) {
            LogUtil.print("ImageMonitor", "ImageMonitor:addPhotoMarker ExifInterface exception" + e.message)
        }
        val o = exifInterface?.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
        val matrix = Matrix()
        when (o) {
            ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> bitmap = convertBmp(bitmap)
            ExifInterface.ORIENTATION_ROTATE_90 -> matrix.setRotate(90f)
            ExifInterface.ORIENTATION_ROTATE_180 -> matrix.setRotate(180f)
            ExifInterface.ORIENTATION_ROTATE_270 -> matrix.setRotate(270f)
            ExifInterface.ORIENTATION_TRANSVERSE -> {
                matrix.setRotate(90f)
                bitmap = convertBmp(bitmap)
            }
        }
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
    }

    // 照片镜像翻转
    private fun convertBmp(bmp: Bitmap): Bitmap {
        val w = bmp.width
        val h = bmp.height
        val matrix = Matrix()
        matrix.postScale(-1f, 1f) // 镜像水平翻转
        return Bitmap.createBitmap(bmp, 0, 0, w, h, matrix, true)
    }


    //都么有获取的情况下使用本地水印
    @SuppressLint("DefaultLocale")
    fun addPhotoMarkerLocal(context: Context, myInfo: PhotoMarkerInfo): String {
        val bitmap = handlerBitmapRotate(myInfo.path ?: "")
        val baos: ByteArrayOutputStream
        var info = myInfo
        if (info.needMark == true) {
            val w = bitmap.width
            val fontSize = (w * 0.025).toInt()
            val size = (fontSize * 1.4).toInt()

            val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
            val dateFormat2 = SimpleDateFormat("yyyy:MM:dd HH:mm:ss", Locale.getDefault())
            try {
                dateFormat.parse(info.time ?: "")
            } catch (e: ParseException) {
                try {
                    val date = dateFormat2.parse(info.time ?: "")
                    info = info.copy(time = dateFormat.format(date ?: ""))
                } catch (parseException: ParseException) {
                    parseException.printStackTrace()
                    LogUtil.print("ImageMonitor", "时间解析异常" + e.message)
                }
            }

            val textBitmap: Bitmap = ImageUtil.drawTextToRightTop(context, bitmap, info.from + info.time, fontSize, Color.RED, fontSize, size * 2)
            bitmapRecycle(bitmap)

            val text6Bitmap: Bitmap = ImageUtil.drawTextToRightTop(context, textBitmap, "救援师傅：" + info.driverName, fontSize, Color.RED, fontSize, size)
            bitmapRecycle(textBitmap)

            val text7Bitmap: Bitmap = ImageUtil.drawTextToLeftBottom(context, text6Bitmap, "SINO", fontSize, Color.RED, fontSize, size * 2)
            bitmapRecycle(text6Bitmap)

            val text1Bitmap: Bitmap = ImageUtil.drawTextToLeftBottom(context, text7Bitmap, info.taskCode
                ?: "", fontSize, Color.RED, fontSize, size)
            bitmapRecycle(text7Bitmap)
            val text5Bitmap: Bitmap
            var phoneBrandBitmap: Bitmap? = null
            val latLon = "lat: " + java.lang.String.format("%.6f", info.lat) + "; lng: " + java.lang.String.format("%.6f", info.lng)
            if (info.address?.length!! > 20) {
                val address1 = info.address?.substring(0, 16)
                val address2 = info.address?.substring(16)
                val text3Bitmap: Bitmap = ImageUtil.drawTextToRightTop(context, text1Bitmap, address1
                    ?: "", fontSize, Color.RED, fontSize, size * 3)

                val text2Bitmap: Bitmap = ImageUtil.drawTextToRightTop(context, text3Bitmap, address2
                    ?: "", fontSize, Color.RED, fontSize, size * 4)

                bitmapRecycle(text3Bitmap)

                text5Bitmap = ImageUtil.drawTextToRightTop(context, text2Bitmap, latLon, fontSize, Color.RED, fontSize, size * 5)

                if (info.needShowPhoneBrand == true) {
                    phoneBrandBitmap = ImageUtil.drawTextToRightTop(context, text5Bitmap, "手机型号：" + DeviceUtils.getManufacturer() + "  " + DeviceUtils.getModel(), fontSize, Color.RED, fontSize, size * 6)
                }
                bitmapRecycle(text2Bitmap)
            } else {
                val text2Bitmap: Bitmap = ImageUtil.drawTextToRightTop(context, text1Bitmap, info.address
                    ?: "", fontSize, Color.RED, fontSize, size * 3)

                text5Bitmap = ImageUtil.drawTextToRightTop(context, text2Bitmap, latLon, fontSize, Color.RED, fontSize, size * 4)

                if (info.needShowPhoneBrand == true) {
                    phoneBrandBitmap = ImageUtil.drawTextToRightTop(context, text5Bitmap, "手机型号：" + DeviceUtils.getManufacturer() + "  " + DeviceUtils.getModel(), fontSize, Color.RED, fontSize, size * 5)
                }
                bitmapRecycle(text2Bitmap)
            }
            bitmapRecycle(text1Bitmap)
            baos = ByteArrayOutputStream()

            if (info.needShowPhoneBrand == true && phoneBrandBitmap != null) {
                phoneBrandBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
                bitmapRecycle(text5Bitmap)
            } else {
                text5Bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
            }
        } else {
            baos = ByteArrayOutputStream()
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
        }
        return saveBitmap(context, baos)
    }

    private fun bitmapRecycle(bitmap: Bitmap?) {
        if (bitmap != null && !bitmap.isRecycled) {
            bitmap.recycle()
        }
    }
}
