package com.app.wave.keyboard.kbhelper;

import android.annotation.SuppressLint;
import android.graphics.drawable.Drawable;
import android.inputmethodservice.InputMethodService;
import android.media.MediaPlayer;
import android.os.Build;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.ImageView;
import android.widget.VideoView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.bumptech.glide.Glide;
import com.bumptech.glide.integration.webp.decoder.WebpDrawable;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.app.wave.keyboard.App;
import com.app.wave.keyboard.R;
import com.app.wave.keyboard.utils.MyKeyName;
import com.app.wave.keyboard.utils.Comutils;
import com.app.wave.keyboard.utils.SavePresentKB;
import com.app.wave.keyboard.sourcecode.KBCode;
import com.app.wave.keyboard.sourcecode.KBCodeView;

import kotlin.Unit;
import kotlin.jvm.functions.Function2;

public class InputService extends InputMethodService implements KBCodeView.OnKeyboardActionListener {

    private KBView myKeyBoardView;
    private KBCode mKeyBoard;
    private View parentView;
    private ImageView imBG;
    private VideoView videoView;

    private int a = R.xml.xml_one;
    private int b = R.xml.xml_two;
    private int c = R.xml.xml_three;

    private int curImeAction = EditorInfo.IME_ACTION_UNSPECIFIED;

    @SuppressLint("InflateParams")
    @Override
    public View onCreateInputView() {
        parentView = getLayoutInflater().inflate(R.layout.item_keyboard_preview, null);

        // API 30+ 的特殊处理
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            // 设置窗口标志，确保键盘正确显示
            try {
                if (getWindow() != null && getWindow().getWindow() != null) {
                    getWindow().getWindow().addFlags(
                            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
                                    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                    );

                    // 对于 API 31+
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                        getWindow().getWindow().setDecorFitsSystemWindows(false);
                    }
                }
            } catch (Exception e) {
                Log.e(App.TAG, "Error setting window flags: " + e.getMessage());
            }
        }

        findView();
        return parentView;
    }

    private void findView() {
        imBG = parentView.findViewById(R.id.gif_bg);
        videoView = parentView.findViewById(R.id.video_view);
        mKeyBoard = new KBCode(this, a);
        myKeyBoardView = parentView.findViewById(R.id.custom_input_view);
        myKeyBoardView.setEnabled(true);
        myKeyBoardView.setPreviewEnabled(false);
        myKeyBoardView.setKeyboard(mKeyBoard);
        myKeyBoardView.setOnKeyboardActionListener(this);

        // API 31+ 的特殊处理
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            myKeyBoardView.setFocusable(true);
            myKeyBoardView.setFocusableInTouchMode(true);
        }
    }

    @Override
    public void onStartInputView(EditorInfo info, boolean restarting) {
        super.onStartInputView(info, restarting);

        // API 31+ 可能需要额外的初始化
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            // 确保键盘视图正确初始化
            if (myKeyBoardView != null) {
                myKeyBoardView.requestFocus();
            }
        }

        // 更新当前输入法动作
        if (info != null) {
            curImeAction = Comutils.INSTANCE.getTextForImeAction(info.imeOptions);
            Log.d(App.TAG, "onStartInputView: curImeAction = " + curImeAction);
        }
    }

    @Override
    public void onWindowHidden() {
        super.onWindowHidden();
        if (videoView != null && videoView.isPlaying()) {
            videoView.pause();
        }
    }

    @Override
    public void onWindowShown() {
        super.onWindowShown();

        // 获取当前编辑信息
        EditorInfo currentInputEditorInfo = getCurrentInputEditorInfo();
        if (currentInputEditorInfo != null) {
            curImeAction = Comutils.INSTANCE.getTextForImeAction(currentInputEditorInfo.imeOptions);
        }

        String skinPath = SavePresentKB.INSTANCE.getSkinPath();

        if (skinPath == null || skinPath.isEmpty()) {
            Log.d(App.TAG, "---------skinPath= null");
            if (myKeyBoardView != null) {
                myKeyBoardView.updateUi(curImeAction);
            }
        } else {
            Log.d(App.TAG, "---------skinPath= " + skinPath);
            KbFuncs.INSTANCE.readBgOrVideo(this, new Function2<String, Drawable, Unit>() {
                @Override
                public Unit invoke(String s, Drawable drawable) {
                    Log.d(App.TAG, "---------s= " + s + "---------drawable=" + drawable);

                    // 检查视图是否仍然有效
                    if (myKeyBoardView == null || imBG == null || videoView == null) {
                        return null;
                    }

                    if (s != null) {
                        myKeyBoardView.setBackground(null);
                        if (s.endsWith(".gif")) {
                            imBG.setVisibility(View.VISIBLE);
                            videoView.setVisibility(View.GONE);
                            try {
                                Glide.with(InputService.this)
                                        .load(s)
                                        .addListener(new RequestListener<Drawable>() {
                                            @Override
                                            public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
                                                Log.e(App.TAG, "Failed to load GIF: " + s);
                                                return false;
                                            }

                                            @Override
                                            public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
                                                if (resource instanceof WebpDrawable) {
                                                    ((WebpDrawable) resource).setLoopCount(WebpDrawable.LOOP_FOREVER);
                                                }
                                                return false;
                                            }
                                        }).into(imBG);
                            } catch (Exception e) {
                                Log.e(App.TAG, "Error loading GIF: " + e.getMessage());
                            }
                        } else if (s.endsWith(".mp4")) {
                            imBG.setVisibility(View.GONE);
                            videoView.setVisibility(View.VISIBLE);
                            try {
                                videoView.setVideoPath(s);
                                videoView.start();
                                videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                                    @Override
                                    public void onPrepared(MediaPlayer mp) {
                                        mp.setLooping(true);
                                    }
                                });
                            } catch (Exception e) {
                                Log.e(App.TAG, "Error playing video: " + e.getMessage());
                            }
                        } else {
                            Log.w(App.TAG, "Unknown media type: " + s);
                        }
                    } else if (drawable != null) {
                        myKeyBoardView.setBackground(drawable);
                    }

                    if (myKeyBoardView != null) {
                        myKeyBoardView.updateUi(curImeAction);
                    }

                    return null;
                }
            });
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (videoView != null) {
            videoView.stopPlayback();
        }

        // 清理资源
        if (myKeyBoardView != null) {
            myKeyBoardView.setOnKeyboardActionListener(null);
        }
    }

    @Override
    public void onPress(int primaryCode) {
        // 可选：播放按键音效或提供触觉反馈
    }

    @Override
    public void onRelease(int primaryCode) {
        // 可选：释放资源
    }

    @Override
    public void onKey(int primaryCode, int[] keyCodes) {
        InputConnection curInputConnect = getCurrentInputConnection();
        if (curInputConnect == null) {
            Log.w(App.TAG, "InputConnection is null");
            return;
        }

        switch (primaryCode) {
            case MyKeyName.KEY_CODE_DELETE:
                curInputConnect.deleteSurroundingText(1, 0);
                break;
            case MyKeyName.KEY_CODE_SHIFT:
                switchShift();
                break;
            case MyKeyName.KEY_CODE_NUMBER_SHIFT:
            case MyKeyName.KEY_CODE_SYMBOL_SHIFT:
                switchMoreOrNumber();
                break;
            case MyKeyName.KEY_CODE_CHANGE_NUMBER:
            case MyKeyName.KEY_CODE_BACK:
                switchNormalOrNumber();
                break;

            case MyKeyName.KEY_CODE_COMPLETE:
            case MyKeyName.KEY_CODE_CANCEL:
                if (curImeAction != EditorInfo.IME_ACTION_UNSPECIFIED) {
                    curInputConnect.performEditorAction(curImeAction);
                } else {
                    // 如果没有指定动作，使用完成动作
                    curInputConnect.performEditorAction(EditorInfo.IME_ACTION_DONE);
                }
                break;
            default:
                String codeToChar = KbFuncs.INSTANCE.primaryCodeToChar(primaryCode);
                if (codeToChar != null) {
                    curInputConnect.commitText(codeToChar, 1);
                    if (myKeyBoardView != null && myKeyBoardView.isLowerCase() == 1) {
                        // 自动转小写
                        myKeyBoardView.setLowerCase(0);
                        KbFuncs.INSTANCE.keyToLowerCase(mKeyBoard);
                        myKeyBoardView.setKeyboard(mKeyBoard);
                    }
                }
                break;
        }
    }

    private void switchMoreOrNumber() {
        if (myKeyBoardView == null) return;

        int mode = myKeyBoardView.getMode();
        switch (mode) {
            case 1:
                mKeyBoard = new KBCode(this, c);
                myKeyBoardView.setMode(2);
                myKeyBoardView.setKeyboard(mKeyBoard);
                break;
            case 2:
                mKeyBoard = new KBCode(this, b);
                myKeyBoardView.setMode(1);
                myKeyBoardView.setKeyboard(mKeyBoard);
                break;
        }
    }

    private void switchNormalOrNumber() {
        if (myKeyBoardView == null) return;

        int mode = myKeyBoardView.getMode();
        switch (mode) {
            case 0:
                mKeyBoard = new KBCode(this, b);
                myKeyBoardView.setMode(1);
                myKeyBoardView.setKeyboard(mKeyBoard);
                break;
            case 1:
            case 2:
                mKeyBoard = new KBCode(this, a);
                myKeyBoardView.setMode(0);
                myKeyBoardView.setKeyboard(mKeyBoard);
                break;
        }
    }

    private void switchShift() {
        if (myKeyBoardView == null) return;

        int lowerCase = myKeyBoardView.isLowerCase();
        switch (lowerCase) {
            case 0:
                // 当前小写转大写
                myKeyBoardView.setLowerCase(1);
                KbFuncs.INSTANCE.keyToUpper(mKeyBoard);
                myKeyBoardView.setKeyboard(mKeyBoard);
                break;
            case 1:
                // 当前大写转锁定大写
                myKeyBoardView.setLowerCase(2);
                break;
            case 2:
                // 当前锁定大写转小写
                myKeyBoardView.setLowerCase(0);
                KbFuncs.INSTANCE.keyToLowerCase(mKeyBoard);
                myKeyBoardView.setKeyboard(mKeyBoard);
                break;
        }
    }

    @Override
    public void onText(CharSequence text) {
        // 处理文本输入
    }

    @Override
    public void swipeLeft() {
        // 处理向左滑动
    }

    @Override
    public void swipeRight() {
        // 处理向右滑动
    }

    @Override
    public void swipeDown() {
        // 处理向下滑动
    }

    @Override
    public void swipeUp() {
        // 处理向上滑动
    }
}