package cc.winboll.studio.powerbell.views;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.ToastUtils;
import cc.winboll.studio.powerbell.App;
import cc.winboll.studio.powerbell.models.BackgroundBean;
import java.io.File;

/**
 * 基于Java7的BackgroundView（LinearLayout+ImageView，保持原图比例居中平铺）
 * 核心：ImageView保持原图比例，在LinearLayout中居中平铺，无拉伸、无裁剪
 * 改进：强制保持缓存策略，无论内存是否紧张，不自动清理任何缓存
 */
public class BackgroundView extends RelativeLayout {

    public static final String TAG = "BackgroundView";
    // 记录当前已缓存的图片路径
    private String mCurrentCachedPath = "";

    private Context mContext;
    private LinearLayout mLlContainer; // 主容器LinearLayout
    private ImageView mIvBackground;   // 图片显示控件
    private float mImageAspectRatio = 1.0f; // 原图宽高比（宽/高）

    // ====================================== 构造器（Java7兼容） ======================================
    public BackgroundView(Context context) {
        super(context);
        LogUtils.d(TAG, "=== BackgroundView 构造器1 启动 ===");
        this.mContext = context;
        initView();
    }

    public BackgroundView(Context context, AttributeSet attrs) {
        super(context, attrs);
        LogUtils.d(TAG, "=== BackgroundView 构造器2 启动 ===");
        this.mContext = context;
        initView();
    }

    public BackgroundView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        LogUtils.d(TAG, "=== BackgroundView 构造器3 启动 ===");
        this.mContext = context;
        initView();
    }

    // ====================================== 初始化 ======================================
    private void initView() {
        LogUtils.d(TAG, "=== initView 启动 ===");
        // 1. 配置当前控件：全屏+透明
        setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

        // 2. 初始化主容器LinearLayout
        initLinearLayout();

        // 3. 初始化ImageView
        initImageView();

        // 初始设置透明背景
        setDefaultTransparentBackground();

        LogUtils.d(TAG, "=== initView 完成 ===");
    }

    private void initLinearLayout() {
        LogUtils.d(TAG, "=== initLinearLayout 启动 ===");
        mLlContainer = new LinearLayout(mContext);
        // 配置LinearLayout：全屏+垂直方向+居中
        LinearLayout.LayoutParams llParams = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT,
            LinearLayout.LayoutParams.MATCH_PARENT
        );
        mLlContainer.setLayoutParams(llParams);
        mLlContainer.setOrientation(LinearLayout.VERTICAL);
        mLlContainer.setGravity(android.view.Gravity.CENTER); // 子View居中
        mLlContainer.setBackgroundColor(0x00000000);
        this.addView(mLlContainer);
        LogUtils.d(TAG, "=== initLinearLayout 完成 ===");
    }

    private void initImageView() {
        LogUtils.d(TAG, "=== initImageView 启动 ===");
        mIvBackground = new ImageView(mContext);
        // 配置ImageView：wrap_content+居中+透明背景
        LinearLayout.LayoutParams ivParams = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.WRAP_CONTENT
        );
        mIvBackground.setLayoutParams(ivParams);
        mIvBackground.setScaleType(ScaleType.FIT_CENTER); // 保持比例+居中平铺
        mIvBackground.setBackgroundColor(0x00000000);
        mLlContainer.addView(mIvBackground);
        LogUtils.d(TAG, "=== initImageView 完成 ===");
    }

    public void loadByBackgroundBean(BackgroundBean bean) {
        loadByBackgroundBean(bean, false);
    }

    public void loadByBackgroundBean(BackgroundBean bean, boolean isRefresh) {
        if (!bean.isUseBackgroundFile()) {
            setDefaultTransparentBackground();
            return;
        }
        String targetPath = bean.isUseBackgroundScaledCompressFile()
            ? bean.getBackgroundScaledCompressFilePath()
            : bean.getBackgroundFilePath();

        if (!(new File(targetPath).exists())) {
            LogUtils.d(TAG, String.format("视图控件图片不存在：%s", targetPath));
            return;
        }

        // 核心修改：刷新时不删除旧缓存，仅重新解码并更新缓存（强制保持策略）
        if (isRefresh) {
            LogUtils.d(TAG, "loadByBackgroundBean: 刷新图片，重新解码并更新缓存 - " + targetPath);
            // 刷新时直接解码，更新缓存（不删除旧缓存）
            Bitmap newBitmap = decodeBitmapWithCompress(new File(targetPath), 1080, 1920);
            if (newBitmap != null) {
                App.sBitmapCacheUtils.cacheBitmap(targetPath, newBitmap);
                // 增加引用计数
                App.sBitmapCacheUtils.increaseRefCount(targetPath);
            }
        }
        loadImage(targetPath);
    }

    // ====================================== 对外方法 ======================================
    /**
     * 改进版：强制保持缓存策略，不自动清理任何缓存，强化引用计数管理
     * @param imagePath 图片绝对路径
     */
    public void loadImage(String imagePath) {
        LogUtils.d(TAG, "=== loadImage 启动，路径：" + imagePath + " ===");
        if (TextUtils.isEmpty(imagePath)) {
            setDefaultTransparentBackground();
            return;
        }

        File imageFile = new File(imagePath);
        if (!imageFile.exists() || !imageFile.isFile()) {
            LogUtils.e(TAG, "图片文件无效");
            setDefaultTransparentBackground();
            return;
        }

        mIvBackground.setVisibility(View.GONE);

        // ======================== 路径判断逻辑（强制缓存版） ========================
        // 1. 路径未变化：校验缓存有效性，无效则重加载（不删除旧缓存）
        if (imagePath.equals(mCurrentCachedPath)) {
            Bitmap cachedBitmap = App.sBitmapCacheUtils.getCachedBitmap(imagePath);
            if (isBitmapValid(cachedBitmap)) {
                LogUtils.d(TAG, "loadImage: 路径未变，使用有效缓存 Bitmap");
                mImageAspectRatio = (float) cachedBitmap.getWidth() / cachedBitmap.getHeight();
                mIvBackground.setImageBitmap(cachedBitmap);
                adjustImageViewSize();
                return;
            } else {
                LogUtils.e(TAG, "loadImage: 缓存Bitmap无效，尝试重加载 - " + imagePath);
                // 缓存无效，直接重加载（不删除旧缓存，强制保持策略）
            }
        }

        // 2. 路径已更新：保留旧缓存，仅更新当前路径记录（核心修改：不删除旧缓存）
        if (!TextUtils.isEmpty(mCurrentCachedPath) && !mCurrentCachedPath.equals(imagePath)) {
            LogUtils.d(TAG, "loadImage: 路径已更新，保留旧缓存，当前路径从 " + mCurrentCachedPath + " 切换到 " + imagePath);
            // 仅更新当前路径记录，不删除旧缓存
        }
        // ======================== 路径判断逻辑结束 ========================

        // 无缓存/缓存无效/路径更新：重新加载图片
        if (!calculateImageAspectRatio(imageFile)) {
            setDefaultTransparentBackground();
            return;
        }

        // 先尝试从缓存获取
        Bitmap bitmap = App.sBitmapCacheUtils.getCachedBitmap(imagePath);
        if (isBitmapValid(bitmap)) {
            LogUtils.d(TAG, "loadImage: 从缓存获取有效Bitmap - " + imagePath);
        } else {
            // 缓存无效应解码
            bitmap = decodeBitmapWithCompress(imageFile, 1080, 1920);
            if (bitmap == null) {
                LogUtils.e(TAG, "loadImage: 图片解码失败");
                ToastUtils.show("图片解码失败，无法加载");
                setDefaultTransparentBackground();
                return;
            }
            // 缓存新图片（强制保持）
            App.sBitmapCacheUtils.cacheBitmap(imagePath, bitmap);
            LogUtils.d(TAG, "loadImage: 加载新图片并缓存 - " + imagePath);
        }

        // 增加引用计数（配合全局缓存工具的引用计数机制）
        App.sBitmapCacheUtils.increaseRefCount(imagePath);
        // 更新当前缓存路径记录
        mCurrentCachedPath = imagePath;

        // 直接使用setImageBitmap，避免BitmapDrawable包装的引用风险
        mIvBackground.setImageBitmap(bitmap);
        adjustImageViewSize();
        LogUtils.d(TAG, "=== loadImage 完成 ===");
    }

    // ====================================== 内部工具方法 ======================================
    /**
     * 工具方法：判断Bitmap是否有效（非空且未被回收）
     */
    private boolean isBitmapValid(Bitmap bitmap) {
        return bitmap != null && !bitmap.isRecycled();
    }

    private boolean calculateImageAspectRatio(File file) {
        try {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(file.getAbsolutePath(), options);

            int width = options.outWidth;
            int height = options.outHeight;
            if (width <= 0 || height <= 0) {
                LogUtils.e(TAG, "图片尺寸无效");
                return false;
            }

            mImageAspectRatio = (float) width / height;
            LogUtils.d(TAG, "原图比例：" + mImageAspectRatio);
            return true;
        } catch (Exception e) {
            LogUtils.e(TAG, "计算比例失败：" + e.getMessage());
            return false;
        }
    }

    /**
     * 改进版解码方法：强制缓存策略，关闭可回收标志，使用高压缩比减少OOM风险
     */
    private Bitmap decodeBitmapWithCompress(File file, int maxWidth, int maxHeight) {
        try {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(file.getAbsolutePath(), options);

            // 更精准的采样率计算（避免过度压缩）
            int scaleX = (int) Math.ceil((float) options.outWidth / maxWidth);
            int scaleY = (int) Math.ceil((float) options.outHeight / maxHeight);
            int inSampleSize = Math.max(scaleX, scaleY);
            inSampleSize = Math.max(1, inSampleSize); // 确保采样率≥1

            options.inJustDecodeBounds = false;
            options.inSampleSize = inSampleSize;
            options.inPreferredConfig = Bitmap.Config.RGB_565; // 节省内存
            // 核心修改：关闭可回收标志，防止系统主动回收（强制缓存策略）
            options.inPurgeable = false;
            options.inInputShareable = false;
            return BitmapFactory.decodeFile(file.getAbsolutePath(), options);
        } catch (Exception e) {
            LogUtils.e(TAG, "压缩解码失败：" + e.getMessage());
            return null;
        }
    }

    private void adjustImageViewSize() {
        if (mLlContainer == null || mIvBackground == null) {
            return;
        }

        int llWidth = mLlContainer.getWidth();
        int llHeight = mLlContainer.getHeight();

        if (llWidth == 0 || llHeight == 0) {
            LogUtils.w(TAG, "adjustImageViewSize: 容器尺寸未初始化，延迟调整");
            // 延迟调整（容器尺寸未就绪时）
            post(new Runnable() {
					@Override
					public void run() {
						adjustImageViewSize();
					}
				});
            return;
        }

        int ivWidth, ivHeight;
        if (mImageAspectRatio >= 1.0f) {
            ivWidth = Math.min((int) (llHeight * mImageAspectRatio), llWidth);
            ivHeight = (int) (ivWidth / mImageAspectRatio);
        } else {
            ivHeight = Math.min((int) (llWidth / mImageAspectRatio), llHeight);
            ivWidth = (int) (ivHeight * mImageAspectRatio);
        }

        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mIvBackground.getLayoutParams();
        params.width = ivWidth;
        params.height = ivHeight;
        mIvBackground.setLayoutParams(params);
        mIvBackground.setScaleType(ScaleType.FIT_CENTER);
        mIvBackground.setVisibility(View.VISIBLE);
    }

    private void setDefaultTransparentBackground() {
        // 清空ImageView的Drawable，释放本地引用（不影响全局缓存）
        mIvBackground.setImageDrawable(null);
        mIvBackground.setBackgroundColor(0x00000000);
        mImageAspectRatio = 1.0f;
        // 核心修改：路径清空时减少引用计数，不删除缓存
        if (!TextUtils.isEmpty(mCurrentCachedPath)) {
            App.sBitmapCacheUtils.decreaseRefCount(mCurrentCachedPath);
            mCurrentCachedPath = "";
        }
    }

    // ====================================== 重写方法（核心改进） ======================================
    /**
     * 重写：绘制前强制校验Bitmap有效性，防止已回收Bitmap崩溃
     */
    @Override
    protected void onDraw(Canvas canvas) {
        Drawable drawable = mIvBackground.getDrawable();
        if (drawable instanceof BitmapDrawable) {
            BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
            Bitmap bitmap = bitmapDrawable.getBitmap();
            if (!isBitmapValid(bitmap)) {
                LogUtils.e(TAG, "onDraw: 检测到已回收Bitmap，清空本地绘制（保留全局缓存）");
                mIvBackground.setImageDrawable(null);
                return;
            }
        }
        super.onDraw(canvas);
    }

    /**
     * 重写：View从窗口移除时仅减少引用计数，不删除全局缓存（强制保持策略）
     */
    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        LogUtils.d(TAG, "onDetachedFromWindow: 减少引用计数，保留全局缓存");
        // 清空ImageView的Drawable，释放本地引用
        mIvBackground.setImageDrawable(null);
        // 核心修改：仅减少引用计数，不删除全局缓存
        if (!TextUtils.isEmpty(mCurrentCachedPath)) {
            App.sBitmapCacheUtils.decreaseRefCount(mCurrentCachedPath);
            mCurrentCachedPath = "";
        }
    }

    /**
     * 重写：恢复尺寸调整逻辑，确保View尺寸变化时正确显示
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        adjustImageViewSize(); // 恢复尺寸调整
    }
}

