package eu.toldi.infinityforlemmy.utils;

import android.app.WallpaperColors;
import android.app.WallpaperManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Build;
import android.os.Handler;

import androidx.annotation.ColorInt;
import androidx.annotation.Nullable;

import org.greenrobot.eventbus.EventBus;

import java.util.concurrent.Executor;

import eu.toldi.infinityforlemmy.RedditDataRoomDatabase;
import eu.toldi.infinityforlemmy.customtheme.CustomTheme;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.events.RecreateActivityEvent;

public class MaterialYouUtils {
    public interface CheckThemeNameListener {
        void themeNotExists();
        void themeExists();
    }

    public static void checkThemeName(Executor executor, Handler handler,
                                      RedditDataRoomDatabase redditDataRoomDatabase,
                                      CheckThemeNameListener checkThemeNameListener) {
        executor.execute(() -> {
            if (redditDataRoomDatabase.customThemeDao().getCustomTheme("Material You") != null
                    || redditDataRoomDatabase.customThemeDao().getCustomTheme("Material You Dark") != null
                    || redditDataRoomDatabase.customThemeDao().getCustomTheme("Material You Amoled") != null) {
                handler.post(checkThemeNameListener::themeExists);
            } else {
                handler.post(checkThemeNameListener::themeNotExists);
            }
        });
    }

    public static void changeThemeSync(Context context,
                                        RedditDataRoomDatabase redditDataRoomDatabase,
                                        CustomThemeWrapper customThemeWrapper,
                                        SharedPreferences lightThemeSharedPreferences,
                                        SharedPreferences darkThemeSharedPreferences,
                                        SharedPreferences amoledThemeSharedPreferences) {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ignored) { }
        if (changeTheme(context, redditDataRoomDatabase, customThemeWrapper, lightThemeSharedPreferences, darkThemeSharedPreferences, amoledThemeSharedPreferences)) {
            EventBus.getDefault().post(new RecreateActivityEvent());
        }
    }

    public static void changeThemeASync(Context context, Executor executor, Handler handler,
                                        RedditDataRoomDatabase redditDataRoomDatabase,
                                        CustomThemeWrapper customThemeWrapper,
                                        SharedPreferences lightThemeSharedPreferences,
                                        SharedPreferences darkThemeSharedPreferences,
                                        SharedPreferences amoledThemeSharedPreferences,
                                        @Nullable MaterialYouListener materialYouListener) {
        executor.execute(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException ignored) { }
            if (changeTheme(context, redditDataRoomDatabase, customThemeWrapper, lightThemeSharedPreferences, darkThemeSharedPreferences, amoledThemeSharedPreferences)) {
                handler.post(() -> {
                    if (materialYouListener != null) {
                        materialYouListener.applied();
                    }
                    EventBus.getDefault().post(new RecreateActivityEvent());
                });
            }
        });
    }

    private static boolean changeTheme(Context context,
                             RedditDataRoomDatabase redditDataRoomDatabase,
                             CustomThemeWrapper customThemeWrapper,
                             SharedPreferences lightThemeSharedPreferences,
                             SharedPreferences darkThemeSharedPreferences,
                             SharedPreferences amoledThemeSharedPreferences) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            CustomTheme lightTheme = CustomThemeWrapper.getIndigo(context);
            CustomTheme darkTheme = CustomThemeWrapper.getIndigoDark(context);
            CustomTheme amoledTheme = CustomThemeWrapper.getIndigoAmoled(context);

            lightTheme.colorPrimary = context.getColor(android.R.color.system_accent1_100);
            lightTheme.colorPrimaryDark = lightTheme.colorPrimary;
            lightTheme.colorAccent = context.getColor(android.R.color.system_accent3_300);
            lightTheme.colorPrimaryLightTheme = lightTheme.colorPrimary;
            lightTheme.backgroundColor = context.getColor(android.R.color.system_neutral1_50);
            lightTheme.cardViewBackgroundColor = context.getColor(android.R.color.system_neutral2_10);
            lightTheme.filledCardViewBackgroundColor = lightTheme.cardViewBackgroundColor;
            lightTheme.commentBackgroundColor = context.getColor(android.R.color.system_neutral2_10);
            lightTheme.awardedCommentBackgroundColor = context.getColor(android.R.color.system_neutral2_10);
            lightTheme.bottomAppBarBackgroundColor = lightTheme.colorPrimary;
            lightTheme.navBarColor = lightTheme.colorPrimary;
            lightTheme.primaryTextColor = context.getColor(android.R.color.system_neutral1_900);
            lightTheme.secondaryTextColor = context.getColor(android.R.color.system_neutral1_700);
            lightTheme.buttonTextColor = lightTheme.primaryTextColor;
            lightTheme.bottomAppBarIconColor = lightTheme.buttonTextColor;
            lightTheme.primaryIconColor = context.getColor(android.R.color.system_accent1_400);
            lightTheme.fabIconColor = lightTheme.buttonTextColor;
            lightTheme.toolbarPrimaryTextAndIconColor = lightTheme.buttonTextColor;
            lightTheme.toolbarSecondaryTextColor = lightTheme.buttonTextColor;
            lightTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = lightTheme.buttonTextColor;
            lightTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = lightTheme.buttonTextColor;
            lightTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = lightTheme.colorPrimary;
            lightTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = lightTheme.backgroundColor;
            lightTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = lightTheme.buttonTextColor;
            lightTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = lightTheme.buttonTextColor;
            lightTheme.circularProgressBarBackground = context.getColor(android.R.color.system_accent1_10);
            lightTheme.dividerColor = context.getColor(android.R.color.system_neutral1_400);
            lightTheme.isLightStatusBar = true;
            lightTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = true;
            lightTheme.name = "Material You";

            darkTheme.colorPrimary = context.getColor(android.R.color.system_accent2_800);
            darkTheme.colorPrimaryDark = darkTheme.colorPrimary;
            darkTheme.colorAccent = context.getColor(android.R.color.system_accent3_100);
            darkTheme.colorPrimaryLightTheme = lightTheme.colorPrimary;
            darkTheme.backgroundColor = context.getColor(android.R.color.system_neutral1_900);
            darkTheme.cardViewBackgroundColor = context.getColor(android.R.color.system_neutral2_800);
            darkTheme.filledCardViewBackgroundColor = darkTheme.cardViewBackgroundColor;
            darkTheme.commentBackgroundColor = darkTheme.cardViewBackgroundColor;
            darkTheme.awardedCommentBackgroundColor = darkTheme.cardViewBackgroundColor;
            darkTheme.bottomAppBarBackgroundColor = darkTheme.colorPrimary;
            darkTheme.navBarColor = darkTheme.colorPrimary;
            darkTheme.primaryTextColor = context.getColor(android.R.color.system_neutral1_10);
            darkTheme.secondaryTextColor = context.getColor(android.R.color.system_neutral1_10);
            darkTheme.buttonTextColor = context.getColor(android.R.color.system_neutral1_900);
            darkTheme.bottomAppBarIconColor = context.getColor(android.R.color.system_accent1_100);
            darkTheme.primaryIconColor = context.getColor(android.R.color.system_accent1_100);
            darkTheme.fabIconColor = context.getColor(android.R.color.system_neutral1_900);
            darkTheme.toolbarPrimaryTextAndIconColor = context.getColor(android.R.color.system_accent2_100);
            darkTheme.toolbarSecondaryTextColor = darkTheme.toolbarPrimaryTextAndIconColor;
            darkTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = darkTheme.toolbarPrimaryTextAndIconColor;
            darkTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = darkTheme.toolbarPrimaryTextAndIconColor;
            darkTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = darkTheme.colorPrimary;
            darkTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = darkTheme.backgroundColor;
            darkTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = darkTheme.bottomAppBarIconColor;
            darkTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = darkTheme.bottomAppBarIconColor;
            darkTheme.circularProgressBarBackground = context.getColor(android.R.color.system_accent1_900);
            darkTheme.dividerColor = context.getColor(android.R.color.system_neutral1_600);
            darkTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = true;
            darkTheme.name = "Material You Dark";

            amoledTheme.colorAccent = context.getColor(android.R.color.system_accent1_100);
            amoledTheme.colorPrimaryLightTheme = lightTheme.colorPrimary;
            amoledTheme.fabIconColor = context.getColor(android.R.color.system_neutral1_900);
            amoledTheme.name = "Material You Amoled";

            redditDataRoomDatabase.customThemeDao().unsetLightTheme();
            redditDataRoomDatabase.customThemeDao().unsetDarkTheme();
            redditDataRoomDatabase.customThemeDao().unsetAmoledTheme();

            redditDataRoomDatabase.customThemeDao().insert(lightTheme);
            redditDataRoomDatabase.customThemeDao().insert(darkTheme);
            redditDataRoomDatabase.customThemeDao().insert(amoledTheme);

            CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(lightTheme, lightThemeSharedPreferences);
            CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(darkTheme, darkThemeSharedPreferences);
            CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(amoledTheme, amoledThemeSharedPreferences);

            return true;
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
            WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
            WallpaperColors wallpaperColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);

            if (wallpaperColors != null) {
                int colorPrimaryInt = lightenColor(wallpaperColors.getPrimaryColor().toArgb(), 0.4);
                int colorPrimaryDarkInt = darkenColor(colorPrimaryInt, 0.3);
                int backgroundColor = lightenColor(colorPrimaryInt, 0.2);
                int cardViewBackgroundColor = lightenColor(colorPrimaryInt, 0.6);
                Color colorAccent = wallpaperColors.getSecondaryColor();
                int colorAccentInt = lightenColor(colorAccent == null ? customThemeWrapper.getColorAccent() : colorAccent.toArgb(), 0.4);

                int colorPrimaryAppropriateTextColor = getAppropriateTextColor(colorPrimaryInt);
                int backgroundColorAppropriateTextColor = getAppropriateTextColor(backgroundColor);

                CustomTheme lightTheme = CustomThemeWrapper.getIndigo(context);
                CustomTheme darkTheme = CustomThemeWrapper.getIndigoDark(context);
                CustomTheme amoledTheme = CustomThemeWrapper.getIndigoAmoled(context);

                lightTheme.colorPrimary = colorPrimaryInt;
                lightTheme.colorPrimaryDark = colorPrimaryDarkInt;
                lightTheme.colorAccent = colorAccentInt;
                lightTheme.colorPrimaryLightTheme = colorPrimaryInt;
                lightTheme.backgroundColor = backgroundColor;
                lightTheme.cardViewBackgroundColor = cardViewBackgroundColor;
                lightTheme.filledCardViewBackgroundColor = cardViewBackgroundColor;
                lightTheme.commentBackgroundColor = cardViewBackgroundColor;
                lightTheme.awardedCommentBackgroundColor = cardViewBackgroundColor;
                lightTheme.bottomAppBarBackgroundColor = colorPrimaryInt;
                lightTheme.navBarColor = colorPrimaryInt;
                lightTheme.primaryTextColor = backgroundColorAppropriateTextColor;
                lightTheme.secondaryTextColor = backgroundColorAppropriateTextColor == Color.BLACK ? Color.parseColor("#8A000000") : Color.parseColor("#B3FFFFFF");
                lightTheme.bottomAppBarIconColor = colorPrimaryAppropriateTextColor;
                lightTheme.primaryIconColor = backgroundColorAppropriateTextColor;
                lightTheme.fabIconColor = colorPrimaryAppropriateTextColor;
                lightTheme.toolbarPrimaryTextAndIconColor = colorPrimaryAppropriateTextColor;
                lightTheme.toolbarSecondaryTextColor = colorPrimaryAppropriateTextColor;
                lightTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = colorPrimaryAppropriateTextColor;
                lightTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = colorPrimaryAppropriateTextColor;
                lightTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = colorPrimaryInt;
                lightTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = backgroundColor;
                lightTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = colorPrimaryAppropriateTextColor;
                lightTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = colorPrimaryAppropriateTextColor;
                lightTheme.circularProgressBarBackground = colorPrimaryInt;
                lightTheme.dividerColor = backgroundColorAppropriateTextColor == Color.BLACK ? Color.parseColor("#E0E0E0") : Color.parseColor("69666C");
                lightTheme.isLightStatusBar = colorPrimaryAppropriateTextColor == Color.BLACK;
                lightTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface =
                        (lightTheme.isLightStatusBar && getAppropriateTextColor(cardViewBackgroundColor) == Color.WHITE)
                                || (!lightTheme.isLightStatusBar && getAppropriateTextColor(cardViewBackgroundColor) == Color.BLACK);
                lightTheme.name = "Material You";

                darkTheme.colorAccent = colorPrimaryInt;
                darkTheme.colorPrimaryLightTheme = colorPrimaryInt;
                darkTheme.name = "Material You Dark";

                amoledTheme.colorAccent = colorPrimaryInt;
                amoledTheme.colorPrimaryLightTheme = colorPrimaryInt;
                amoledTheme.name = "Material You Amoled";

                redditDataRoomDatabase.customThemeDao().unsetLightTheme();
                redditDataRoomDatabase.customThemeDao().unsetDarkTheme();
                redditDataRoomDatabase.customThemeDao().unsetAmoledTheme();

                redditDataRoomDatabase.customThemeDao().insert(lightTheme);
                redditDataRoomDatabase.customThemeDao().insert(darkTheme);
                redditDataRoomDatabase.customThemeDao().insert(amoledTheme);

                CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(lightTheme, lightThemeSharedPreferences);
                CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(darkTheme, darkThemeSharedPreferences);
                CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(amoledTheme, amoledThemeSharedPreferences);

                return true;
            }
        }

        return false;
    }

    private static int lightenColor(int color, double ratio) {
        return Color.argb(Color.alpha(color), (int) (Color.red(color) + (255 - Color.red(color)) * ratio),
                (int) (Color.green(color) + (255 - Color.green(color)) * ratio),
                (int) (Color.blue(color) + (255 - Color.blue(color)) * ratio));
    }

    private static int darkenColor(int color, double ratio) {
        return Color.argb(Color.alpha(color), (int) (Color.red(color) * (1 - ratio)),
                (int) (Color.green(color) * (1 - ratio)),
                (int) (Color.blue(color) * (1 - ratio)));

    }

    @ColorInt
    public static int getAppropriateTextColor(@ColorInt int color) {
        // Counting the perceptive luminance - human eye favors green color...
        double luminance = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255;
        return luminance < 0.5 ? Color.BLACK : Color.WHITE;
    }

    public interface MaterialYouListener {
        void applied();
    }
}
