package com.example.onetap_ssh.fragment;

import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;

import com.example.onetap_ssh.MainActivity;
import com.example.onetap_ssh.R;
import com.example.onetap_ssh.backup.BackupData;
import com.example.onetap_ssh.backup.BackupUtil;
import com.example.onetap_ssh.crypto.BiometricKey;
import com.example.onetap_ssh.crypto.Crypto;
import com.example.onetap_ssh.crypto.CryptoException;
import com.example.onetap_ssh.crypto.CryptoParameters;
import com.example.onetap_ssh.databinding.DialogManageIconPacksBinding;
import com.example.onetap_ssh.databinding.FragmentSettingsBinding;
import com.example.onetap_ssh.icon.IconPack;
import com.example.onetap_ssh.icon.IconPackListAdapter;
import com.example.onetap_ssh.icon.IconUtil;
import com.example.onetap_ssh.util.AppLocale;
import com.example.onetap_ssh.util.Appearance;
import com.example.onetap_ssh.util.BackupException;
import com.example.onetap_ssh.util.BiometricUtil;
import com.example.onetap_ssh.util.DialogUtil;

import com.example.onetap_ssh.util.SettingsUtil;
import com.example.onetap_ssh.util.StyledDialogBuilder;
import com.example.onetap_ssh.util.Theme;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.crypto.SecretKey;

public class SettingsFragment extends NamedFragment {

    private FragmentSettingsBinding binding;

    @Override
    public String getName() {
        return requireActivity().getString(R.string.fragment_settings);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        binding = FragmentSettingsBinding.inflate(inflater);


        String[] localeNames = new String[AppLocale.values().length];
        for(int i = 0; i < localeNames.length;  i++) {
            localeNames[i] = AppLocale.values()[i].getName(requireContext());
        }

        binding.settingsLanguage.setAdapter(new ArrayAdapter<>(requireContext(), android.R.layout.simple_list_item_1, localeNames));
        binding.settingsLanguage.setSelection(Arrays.asList(AppLocale.values()).indexOf(SettingsUtil.getLocale(requireContext())));
        binding.settingsLanguage.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                AppLocale locale = AppLocale.values()[position];
                if(locale.equals(SettingsUtil.getLocale(requireContext()))) return;

                SettingsUtil.setLocale(requireContext(), locale);
                requireActivity().recreate();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

        binding.settingsEnableEncryption.setChecked(SettingsUtil.isDatabaseEncrypted(requireContext()));
        binding.settingsEnableEncryption.setOnCheckedChangeListener((view, checked) -> {
            if(checked) {
                if(SettingsUtil.isDatabaseEncrypted(requireContext())) return;

                DialogUtil.showSetPasswordDialog(requireContext(), password -> {
                    CryptoParameters params = CryptoParameters.createNew();
                    Log.d("Crypto", "Created new crypto params");


                }, () -> view.setChecked(false));
            }else {
                if(!SettingsUtil.isDatabaseEncrypted(requireContext())) return;

                DialogUtil.showYesNo(requireContext(), R.string.disable_encryption_title, R.string.disable_encryption_message, () -> {

                }, () -> view.setChecked(true));
            }
        });

        boolean biometricSupported = BiometricUtil.isSupported(requireContext());
        binding.settingsBiometricLock.setEnabled(SettingsUtil.isDatabaseEncrypted(requireContext()) && biometricSupported);
        binding.settingsBiometricLock.setChecked(SettingsUtil.isBiometricEncryption(requireContext()));

        if(!biometricSupported) {
            binding.settingsBiometricLockInfo.setVisibility(View.VISIBLE);
            binding.settingsBiometricLockInfo.setText(R.string.biometric_encryption_unavailable);
        }

        if(biometricSupported) {
            binding.settingsBiometricLock.setOnCheckedChangeListener((view, checked) -> {
                if(checked) {

                }else {

                    SettingsUtil.disableBiometricEncryption(requireContext());
                }
            });
        }

        binding.settingsScreenSecurity.setChecked(SettingsUtil.isScreenSecurity(requireContext()));
        binding.settingsScreenSecurity.setOnCheckedChangeListener((view, checked) -> {
            SettingsUtil.setScreenSecurity(requireContext(), checked);
            requireActivity().recreate();
        });

        binding.settingsHideCodes.setChecked(SettingsUtil.isHideCodes(requireContext()));
        binding.settingsHideCodes.setOnCheckedChangeListener((view, checked) -> SettingsUtil.setHideCodes(requireContext(), checked));

        binding.settingsShowImages.setChecked(SettingsUtil.isShowImages(requireContext()));
        binding.settingsShowImages.setOnCheckedChangeListener((view, checked) -> SettingsUtil.setShowImages(requireContext(), checked));

        String[] themeNames = new String[Theme.values().length];
        for(int i = 0; i < Theme.values().length; i++) {
            themeNames[i] = getResources().getString(Theme.values()[i].getName());
        }

        binding.settingsEnableIntroVideo.setChecked(SettingsUtil.isIntroVideoEnabled(requireContext()));
        binding.settingsEnableIntroVideo.setOnCheckedChangeListener((view, checked) -> SettingsUtil.setEnableIntroVideo(requireContext(), checked));

        binding.settingsEnableThemedBackground.setChecked(SettingsUtil.isThemedBackgroundEnabled(requireContext()));
        binding.settingsEnableThemedBackground.setOnCheckedChangeListener((view, checked) -> {
            SettingsUtil.setEnableThemedBackground(requireContext(), checked);
            requireActivity().recreate();
        });

        binding.settingsTheme.setAdapter(new ArrayAdapter<>(requireContext(), android.R.layout.simple_list_item_1, themeNames));
        binding.settingsTheme.setSelection(SettingsUtil.getTheme(requireContext()).ordinal());
        binding.settingsTheme.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                Theme theme = Theme.values()[position];
                if(theme == SettingsUtil.getTheme(requireContext())) return;

                SettingsUtil.setTheme(requireContext(), theme);
                requireActivity().recreate();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {}
        });

        binding.settingsEnableMinimalistTheme.setChecked(SettingsUtil.isMinimalistThemeEnabled(requireContext()));
        binding.settingsEnableMinimalistTheme.setOnCheckedChangeListener((view, checked) -> {
            SettingsUtil.setEnableMinimalistTheme(requireContext(), checked);
            requireActivity().recreate();
        });

        String[] appearanceNames = new String[Appearance.values().length];
        for(int i = 0; i < Appearance.values().length; i++) {
            appearanceNames[i] = getResources().getString(Appearance.values()[i].getName());
        }

        binding.settingsAppearance.setAdapter(new ArrayAdapter<>(requireContext(), android.R.layout.simple_list_item_1, appearanceNames));
        binding.settingsAppearance.setSelection(SettingsUtil.getAppearance(requireContext()).ordinal());
        binding.settingsAppearance.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                Appearance appearance = Appearance.values()[position];
                if(appearance == SettingsUtil.getAppearance(requireContext())) return;

                SettingsUtil.setAppearance(requireContext(), appearance);
                requireActivity().recreate();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {}
        });

        binding.settingsCreateBackup.setOnClickListener(view -> {
            new StyledDialogBuilder(requireContext())
                    .setTitle(R.string.create_backup)
                    .setItems(R.array.backup_create, (d, which) -> {
                        switch(which) {
                            case 0:
                                break;
                            case 1:
                                break;
                        }
                    })
                    .setNegativeButton(R.string.cancel, (d, which) -> {})
                    .show();
        });

        binding.settingsManageIconPacks.setOnClickListener(v -> {
            List<String> brokenPacks = new ArrayList<>();
            List<IconPack> packs = IconUtil.loadAllIconPacks(requireContext(), brokenPacks::add);

            if(!brokenPacks.isEmpty()) {
                DialogUtil.showYesNo(requireContext(), R.string.broken_icon_packs_title, R.string.broken_icon_packs_message, () -> {
                    for(String pack : brokenPacks) {
                        IconUtil.removeIconPack(requireContext(), pack);
                    }
                }, null);
            }

            if(packs.isEmpty()) {
                Toast.makeText(requireContext(), R.string.no_icon_packs_installed, Toast.LENGTH_LONG).show();
                return;
            }

            DialogManageIconPacksBinding binding = DialogManageIconPacksBinding.inflate(getLayoutInflater());

            binding.manageIconPacksList.setLayoutManager(new LinearLayoutManager(requireContext()));
            binding.manageIconPacksList.setAdapter(new IconPackListAdapter(requireContext(), IconUtil.loadAllIconPacks(requireContext())));

            new StyledDialogBuilder(requireContext())
                    .setTitle(R.string.manage_icon_packs_title)
                    .setView(binding.getRoot())
                    .setPositiveButton(R.string.ok, (d, which) -> {})
                    .show();
        });

        return binding.getRoot();
    }

    private void createBackup(SecretKey key, CryptoParameters parameters) {}

    private void loadBackup(Uri uri) {

    }

    private void loadBackup(Uri uri, SecretKey key, CryptoParameters parameters) throws BackupException, CryptoException {}

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        this.binding = null;
    }

}
