package org.thoughtcrime.securesms.wallpaper;

import android.content.res.ColorStateList;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.appcompat.widget.SwitchCompat;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.core.widget.ImageViewCompat;
import androidx.core.widget.TextViewCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.Navigation;

import com.google.android.material.dialog.MaterialAlertDialogBuilder;

import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.AvatarImageView;
import org.thoughtcrime.securesms.conversation.colors.ColorizerView;
import org.thoughtcrime.securesms.util.DisplayMetricsUtil;
import org.thoughtcrime.securesms.util.Projection;
import org.thoughtcrime.securesms.util.ThemeUtil;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.navigation.SafeNavigation;

import java.util.Collections;

public class ChatWallpaperFragment extends Fragment {

  private boolean isSettingDimFromViewModel;

  private ChatWallpaperViewModel viewModel;
  private SwitchCompat           dimInNightMode;

  @Override
  public @NonNull View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    return inflater.inflate(R.layout.chat_wallpaper_fragment, container, false);
  }

  @Override
  public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    viewModel = new ViewModelProvider(requireActivity()).get(ChatWallpaperViewModel.class);

    AvatarImageView    portrait             = view.findViewById(R.id.chat_wallpaper_preview_top_bar_portrait);
    Toolbar            toolbar              = view.findViewById(R.id.toolbar);
    ImageView          chatWallpaperPreview = view.findViewById(R.id.chat_wallpaper_preview_background);
    View               setWallpaper         = view.findViewById(R.id.chat_wallpaper_set_wallpaper);
    View               chatWallpaperDim     = view.findViewById(R.id.chat_wallpaper_dim);
    TextView           setChatColor         = view.findViewById(R.id.chat_wallpaper_set_chat_color);
    TextView           resetChatColors      = view.findViewById(R.id.chat_wallpaper_reset_chat_colors);
    ImageView          sentBubble           = view.findViewById(R.id.chat_wallpaper_preview_bubble_2);
    ColorizerView      colorizerView        = view.findViewById(R.id.colorizer);
    TextView           resetAllWallpaper    = view.findViewById(R.id.chat_wallpaper_reset_all_wallpapers);
    AppCompatImageView recvBubble           = view.findViewById(R.id.chat_wallpaper_preview_bubble_1);
    View               sendButton           = view.findViewById(R.id.chat_wallpaper_preview_bottom_bar_plus);

    dimInNightMode = view.findViewById(R.id.chat_wallpaper_dark_theme_dims_wallpaper);

    toolbar.setTitle(R.string.preferences__chat_color_and_wallpaper);
    toolbar.setNavigationOnClickListener(nav -> {
      if (!Navigation.findNavController(nav).popBackStack()) {
        requireActivity().finish();
      }
    });

    forceAspectRatioToScreenByAdjustingHeight(chatWallpaperPreview);

    viewModel.getWallpaperPreviewPortrait().observe(getViewLifecycleOwner(),
                                                    wallpaperPreviewPortrait -> wallpaperPreviewPortrait.applyToAvatarImageView(portrait));

    viewModel.getCurrentWallpaper().observe(getViewLifecycleOwner(), wallpaper -> {
      if (wallpaper.isPresent()) {
        wallpaper.get().loadInto(chatWallpaperPreview);
        ImageViewCompat.setImageTintList(recvBubble, ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.conversation_item_recv_bubble_color_wallpaper)));
      } else {
        chatWallpaperPreview.setImageDrawable(null);
        ImageViewCompat.setImageTintList(recvBubble, ColorStateList.valueOf(ThemeUtil.getThemedColor(requireContext(), R.attr.signal_background_secondary)));
      }
    });

    viewModel.getDimInDarkTheme().observe(getViewLifecycleOwner(), shouldDimInNightMode -> {
      if (shouldDimInNightMode != dimInNightMode.isChecked()) {
        isSettingDimFromViewModel = true;
        dimInNightMode.setChecked(shouldDimInNightMode);
        isSettingDimFromViewModel = false;
      }

      chatWallpaperDim.setAlpha(ChatWallpaper.FIXED_DIM_LEVEL_FOR_DARK_THEME);
      chatWallpaperDim.setVisibility(shouldDimInNightMode && ThemeUtil.isDarkTheme(requireContext()) ? View.VISIBLE : View.GONE);
    });

    viewModel.getEnableWallpaperControls().observe(getViewLifecycleOwner(), this::setDimInNightModeEnabled);

    chatWallpaperPreview.setOnClickListener(unused -> setWallpaper.performClick());
    setWallpaper.setOnClickListener(unused -> SafeNavigation.safeNavigate(Navigation.findNavController(view),
                                                                          R.id.action_chatWallpaperFragment_to_chatWallpaperSelectionFragment));
    setChatColor.setOnClickListener(unused -> SafeNavigation.safeNavigate(Navigation.findNavController(view),
                                                                          ChatWallpaperFragmentDirections.actionChatWallpaperFragmentToChatColorSelectionFragment(viewModel.getRecipientId())));

    if (viewModel.isGlobal()) {
      resetAllWallpaper.setOnClickListener(unused -> {
        new MaterialAlertDialogBuilder(requireContext())
            .setTitle(R.string.ChatWallpaperFragment__reset_wallpapers)
            .setMessage(R.string.ChatWallpaperFragment__would_you_like_to_override_all_wallpapers)
            .setPositiveButton(R.string.ChatWallpaperFragment__reset_default_wallpaper, (dialog, which) -> {
              viewModel.setWallpaper(null);
              viewModel.setDimInDarkTheme(true);
              setDimInNightModeEnabled(false);
              viewModel.saveWallpaperSelection();
              dialog.dismiss();
            })
            .setNegativeButton(R.string.ChatWallpaperFragment__reset_all_wallpapers, (dialog, which) -> {
              viewModel.setWallpaper(null);
              viewModel.setDimInDarkTheme(true);
              setDimInNightModeEnabled(false);
              viewModel.resetAllWallpaper();
              dialog.dismiss();
            })
            .setNeutralButton(android.R.string.cancel, (dialog, which) -> {
              dialog.dismiss();
            })
            .show();
      });

      resetChatColors.setOnClickListener(unused -> {
        new MaterialAlertDialogBuilder(requireContext())
            .setTitle(R.string.ChatWallpaperFragment__reset_chat_colors)
            .setMessage(R.string.ChatWallpaperFragment__would_you_like_to_override_all_chat_colors)
            .setPositiveButton(R.string.ChatWallpaperFragment__reset_default_colors, (dialog, which) -> {
              viewModel.clearChatColor();
              dialog.dismiss();
            })
            .setNegativeButton(R.string.ChatWallpaperFragment__reset_all_colors, (dialog, which) -> {
              viewModel.resetAllChatColors();
              dialog.dismiss();
            })
            .setNeutralButton(android.R.string.cancel, (dialog, which) -> {
              dialog.dismiss();
            })
            .show();
      });
    } else {
      resetAllWallpaper.setText(R.string.ChatWallpaperFragment__reset_wallpaper);
      resetChatColors.setText(R.string.ChatWallpaperFragment__reset_chat_color);

      resetAllWallpaper.setOnClickListener(unused -> {
        new MaterialAlertDialogBuilder(requireContext())
            .setMessage(R.string.ChatWallpaperFragment__reset_wallpaper_question)
            .setPositiveButton(R.string.ChatWallpaperFragment__reset, (dialog, which) -> {
              viewModel.setWallpaper(null);
              viewModel.setDimInDarkTheme(true);
              viewModel.saveWallpaperSelection();
              viewModel.refreshChatColors();
            })
            .setNegativeButton(android.R.string.cancel, (dialog, which) -> dialog.dismiss())
            .show();
      });

      resetChatColors.setOnClickListener(unused -> {
        new MaterialAlertDialogBuilder(requireContext())
            .setMessage(R.string.ChatWallpaperFragment__reset_chat_color_question)
            .setPositiveButton(R.string.ChatWallpaperFragment__reset, (dialog, which) -> viewModel.clearChatColor())
            .setNegativeButton(android.R.string.cancel, (dialog, which) -> dialog.dismiss())
            .show();
      });
    }

    viewModel.getCurrentChatColors().observe(getViewLifecycleOwner(), chatColors -> {
      sentBubble.getDrawable().setColorFilter(chatColors.getChatBubbleColorFilter());
      colorizerView.setBackground(chatColors.getChatBubbleMask());
      Projection projection = Projection.relativeToViewWithCommonRoot(sentBubble, colorizerView, new Projection.Corners(ViewUtil.dpToPx(10)));
      colorizerView.setProjections(Collections.singletonList(projection));

      Drawable colorCircle = chatColors.asCircle();
      colorCircle.setBounds(0, 0, ViewUtil.dpToPx(16), ViewUtil.dpToPx(16));
      TextViewCompat.setCompoundDrawablesRelative(setChatColor, null, null, colorCircle, null);

      sendButton.getBackground().setColorFilter(chatColors.asSingleColor(), PorterDuff.Mode.MULTIPLY);
      sendButton.getBackground().invalidateSelf();
    });

    sentBubble.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> viewModel.refreshChatColors());
  }

  @Override
  public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
    super.onViewStateRestored(savedInstanceState);

    dimInNightMode.setOnCheckedChangeListener((buttonView, isChecked) -> {
      if (!isSettingDimFromViewModel) {
        viewModel.setDimInDarkTheme(isChecked);
      }
    });
  }

  @Override
  public void onResume() {
    super.onResume();
    viewModel.refreshChatColors();
  }

  private void setDimInNightModeEnabled(boolean enabled) {
    dimInNightMode.setEnabled(enabled);
    dimInNightMode.setAlpha(enabled ? 1 : 0.5f);
  }

  private void forceAspectRatioToScreenByAdjustingHeight(@NonNull View view) {
    DisplayMetrics displayMetrics = new DisplayMetrics();
    requireActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
    DisplayMetricsUtil.forceAspectRatioToScreenByAdjustingHeight(displayMetrics, view);
  }
}
