package com.example.vdcscore.ui.definicoes;

import android.Manifest;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.activity.EdgeToEdge;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import com.bumptech.glide.Glide;
import com.example.vdcscore.LoginActivity;
import com.example.vdcscore.R;
import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.textfield.TextInputEditText;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.UserProfileChangeRequest;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;

public class ContaActivity extends AppCompatActivity {

    private ImageView imageProfile;
    private TextInputEditText editName;
    private TextView textEmail;
    private Button btnSaveAll;
    private Button btnChangeEmail;
    private Button btnChangePassword;
    private Button btnLogout;
    private View btnChangePhoto;
    private View cardImageContainer;

    private FirebaseAuth mAuth;
    private FirebaseStorage mStorage;
    private StorageReference storageRef;
    private ProgressDialog progressDialog;

    private ActivityResultLauncher<Intent> imagePickerLauncher;
    private ActivityResultLauncher<String> permissionLauncher;
    private Uri selectedImageUri;

    private static final String PREFS_NAME = "LoginPrefs";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_conta);

        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        // Inicializar componentes
        initViews();
        initFirebase();
        setupImagePicker();
        setupPermissionLauncher();
        loadUserData();
        setupListeners();
    }

    private void initViews() {
        MaterialToolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        if (toolbar != null) {
            toolbar.setNavigationOnClickListener(v -> finish());
        }

        imageProfile = findViewById(R.id.imageProfile);
        editName = findViewById(R.id.editName);
        // In XML it is present as @+id/textEmail inside cardSecurity.
        textEmail = findViewById(R.id.textEmail);

        btnSaveAll = findViewById(R.id.btnSaveAll);
        btnChangeEmail = findViewById(R.id.btnChangeEmail);
        btnChangePassword = findViewById(R.id.btnChangePassword);
        btnLogout = findViewById(R.id.btnLogout);

        // New FAB for editing photo
        btnChangePhoto = findViewById(R.id.fabEditPhoto);
        // Also allow clicking the text
        View btnChangePhotoText = findViewById(R.id.btnChangePhoto);

        cardImageContainer = findViewById(R.id.cardImageContainer);

        progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("A processar...");
        progressDialog.setCancelable(false);

        // Setup listeners here or in setupListeners()
        if (btnChangePhotoText != null) {
            btnChangePhotoText.setOnClickListener(v -> openImagePicker());
        }
    }

    private void initFirebase() {
        mAuth = FirebaseAuth.getInstance();
        mStorage = FirebaseStorage.getInstance();
        storageRef = mStorage.getReference();
    }

    private void setupImagePicker() {
        imagePickerLauncher = registerForActivityResult(
                new ActivityResultContracts.StartActivityForResult(),
                result -> {
                    if (result.getResultCode() == RESULT_OK && result.getData() != null) {
                        selectedImageUri = result.getData().getData();
                        if (selectedImageUri != null) {
                            if (imageProfile != null) {
                                imageProfile.setImageTintList(null);
                                Glide.with(this)
                                     .load(selectedImageUri)
                                     .circleCrop()
                                     .into(imageProfile);
                            }
                        }
                    }
                });
    }

    private void setupPermissionLauncher() {
        permissionLauncher = registerForActivityResult(
                new ActivityResultContracts.RequestPermission(),
                isGranted -> {
                    if (isGranted) {
                        openImagePicker();
                    } else {
                        Toast.makeText(this, "Permissão necessária para selecionar imagem", Toast.LENGTH_SHORT).show();
                    }
                });
    }

    private void loadUserData() {
        FirebaseUser user = mAuth.getCurrentUser();
        if (user != null) {
            // Carregar email
            if (textEmail != null) {
                textEmail.setText(user.getEmail() != null ? user.getEmail() : "");
            }

            // Carregar nome
            if (editName != null && user.getDisplayName() != null && !user.getDisplayName().isEmpty()) {
                editName.setText(user.getDisplayName());
            }

            // Carregar foto de perfil
            if (user.getPhotoUrl() != null) {
                loadProfileImage(user.getPhotoUrl().toString());
            } else {
                // Tentar carregar do Storage
                loadProfileImageFromStorage();
            }
        } else {
            Toast.makeText(this, "Utilizador não autenticado", Toast.LENGTH_SHORT).show();
            finish();
        }
    }

    private void loadProfileImage(String imageUrl) {
        if (imageUrl == null || imageProfile == null) return;
        imageProfile.setImageTintList(null);
        Glide.with(this)
             .load(imageUrl)
             .placeholder(R.mipmap.ic_launcher_round)
             .error(R.mipmap.ic_launcher)
             .circleCrop()
             .into(imageProfile);
    }

    private void loadProfileImageFromStorage() {
        FirebaseUser user = mAuth.getCurrentUser();
        if (user == null)
            return;

        StorageReference profileImageRef = storageRef.child("profile_images/" + user.getUid() + ".jpg");
        profileImageRef.getDownloadUrl().addOnSuccessListener(uri -> {
            loadProfileImage(uri.toString());
        }).addOnFailureListener(e -> {
            // Foto não encontrada, manter imagem padrão
        });
    }

    private void setupListeners() {
        if (btnChangePhoto != null) {
            btnChangePhoto.setOnClickListener(v -> openImagePicker());
        }
        if (cardImageContainer != null) {
            cardImageContainer.setOnClickListener(v -> openImagePicker());
        }
        if (btnSaveAll != null) {
            btnSaveAll.setOnClickListener(v -> saveAllChanges());
        }
        if (btnChangeEmail != null) {
            btnChangeEmail.setOnClickListener(v -> showChangeEmailDialog());
        }
        if (btnChangePassword != null) {
            btnChangePassword.setOnClickListener(v -> sendPasswordResetEmail());
        }
        if (btnLogout != null) {
            btnLogout.setOnClickListener(v -> showLogoutConfirmation());
        }
    }

    private void openImagePicker() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            imagePickerLauncher.launch(intent);
        } else {
            String permission = Manifest.permission.READ_EXTERNAL_STORAGE;
            if (ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED) {
                Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                imagePickerLauncher.launch(intent);
            } else {
                permissionLauncher.launch(permission);
            }
        }
    }

    private void saveAllChanges() {
        if (editName == null)
            return;

        String newName = editName.getText().toString().trim();

        if (newName.isEmpty() && selectedImageUri == null) {
            Toast.makeText(this, "Nenhuma alteração a guardar", Toast.LENGTH_SHORT).show();
            return;
        }

        FirebaseUser user = mAuth.getCurrentUser();
        if (user == null) {
            Toast.makeText(this, "Utilizador não autenticado", Toast.LENGTH_SHORT).show();
            return;
        }

        progressDialog.show();

        // Se tiver foto nova, primeiro faz upload
        if (selectedImageUri != null) {
            uploadNewProfileImageAndSaveName(user, newName);
        } else {
            // Só muda o nome
            saveNameOnly(user, newName);
        }
    }

    private void saveNameOnly(FirebaseUser user, String newName) {
        if (newName.isEmpty()) {
            progressDialog.dismiss();
            return; // Se não houver nome para trocar nem imagem, já barrámos em saveAllChanges.
        }

        UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
                .setDisplayName(newName)
                .build();

        user.updateProfile(profileUpdates).addOnCompleteListener(task -> {
            progressDialog.dismiss();
            if (task.isSuccessful()) {
                Toast.makeText(this, "Alterações guardadas com sucesso!", Toast.LENGTH_SHORT).show();
            } else {
                String error = com.example.vdcscore.utils.FirebaseErrorUtils.getErrorMessagePt(task.getException());
                Toast.makeText(this, "Erro ao guardar alterações: " + error, Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void uploadNewProfileImageAndSaveName(FirebaseUser user, String newName) {
        InputStream inputStream = null;
        try {
            inputStream = getContentResolver().openInputStream(selectedImageUri);
            if (inputStream == null) {
                progressDialog.dismiss();
                Toast.makeText(this, "Erro ao abrir imagem", Toast.LENGTH_SHORT).show();
                return;
            }

            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
            if (bitmap == null) {
                progressDialog.dismiss();
                Toast.makeText(this, "Erro ao processar imagem", Toast.LENGTH_SHORT).show();
                return;
            }

            // Redimensionar
            int maxSize = 1024;
            if (bitmap.getWidth() > maxSize || bitmap.getHeight() > maxSize) {
                float scale = Math.min((float) maxSize / bitmap.getWidth(), (float) maxSize / bitmap.getHeight());
                int newWidth = Math.round(bitmap.getWidth() * scale);
                int newHeight = Math.round(bitmap.getHeight() * scale);
                bitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
            }

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos);
            byte[] imageData = baos.toByteArray();

            StorageReference profileImageRef = storageRef.child("profile_images/" + user.getUid() + ".jpg");
            UploadTask uploadTask = profileImageRef.putBytes(imageData);

            uploadTask.addOnSuccessListener(taskSnapshot -> {
                profileImageRef.getDownloadUrl().addOnSuccessListener(uri -> {

                    UserProfileChangeRequest.Builder builder = new UserProfileChangeRequest.Builder();
                    builder.setPhotoUri(uri);
                    if (!newName.isEmpty()) {
                        builder.setDisplayName(newName);
                    }
                    UserProfileChangeRequest profileUpdates = builder.build();

                    user.updateProfile(profileUpdates).addOnCompleteListener(task -> {
                        progressDialog.dismiss();
                        if (task.isSuccessful()) {
                            Toast.makeText(this, "As definições foram guardadas!", Toast.LENGTH_SHORT).show();
                            loadProfileImage(uri.toString());
                            selectedImageUri = null; // reset
                        } else {
                            Toast.makeText(this, "Erro ao atualizar perfil", Toast.LENGTH_SHORT).show();
                        }
                    });
                }).addOnFailureListener(e -> {
                    progressDialog.dismiss();
                    Toast.makeText(this, "Erro ao obter URL: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                });
            }).addOnFailureListener(e -> {
                progressDialog.dismiss();
                Toast.makeText(this, "Erro ao fazer upload: " + e.getMessage(), Toast.LENGTH_SHORT).show();
            });

        } catch (Exception e) {
            progressDialog.dismiss();
            Toast.makeText(this, "Erro: " + e.getMessage(), Toast.LENGTH_SHORT).show();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Exception e) {
                }
            }
        }
    }

    private void sendPasswordResetEmail() {
        FirebaseUser user = mAuth.getCurrentUser();
        if (user == null || user.getEmail() == null) {
            Toast.makeText(this, "Utilizador não autenticado", Toast.LENGTH_SHORT).show();
            return;
        }

        progressDialog.show();

        mAuth.sendPasswordResetEmail(user.getEmail())
                .addOnCompleteListener(task -> {
                    progressDialog.dismiss();
                    if (task.isSuccessful()) {
                        Toast.makeText(this,
                                "Email de alteração de password enviado! Verifique a sua caixa de entrada.",
                                Toast.LENGTH_LONG).show();
                    } else {
                        String errorMessage = com.example.vdcscore.utils.FirebaseErrorUtils.getErrorMessagePt(task.getException());
                        Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
                    }
                });
    }

    private void showChangeEmailDialog() {
        FirebaseUser user = mAuth.getCurrentUser();
        if (user == null) {
            Toast.makeText(this, "Utilizador não autenticado", Toast.LENGTH_SHORT).show();
            return;
        }

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Alterar Email");

        final TextInputEditText input = new TextInputEditText(this);
        input.setInputType(android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
        input.setHint("Novo email");
        if (user.getEmail() != null) {
            input.setText(user.getEmail());
        }

        android.widget.FrameLayout container = new android.widget.FrameLayout(this);
        android.widget.FrameLayout.LayoutParams params = new android.widget.FrameLayout.LayoutParams(
                android.view.ViewGroup.LayoutParams.MATCH_PARENT,
                android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
        int marginPx = (int) (20 * getResources().getDisplayMetrics().density);
        params.leftMargin = marginPx;
        params.rightMargin = marginPx;
        params.topMargin = marginPx;
        params.bottomMargin = marginPx;
        input.setLayoutParams(params);
        container.addView(input);
        builder.setView(container);

        builder.setPositiveButton("Alterar", (dialog, which) -> {
            String newEmail = input.getText().toString().trim();
            if (newEmail.isEmpty()) {
                Toast.makeText(this, "O email não pode estar vazio", Toast.LENGTH_SHORT).show();
                return;
            }
            if (!android.util.Patterns.EMAIL_ADDRESS.matcher(newEmail).matches()) {
                Toast.makeText(this, "Email inválido", Toast.LENGTH_SHORT).show();
                return;
            }
            if (newEmail.equalsIgnoreCase(user.getEmail())) {
                Toast.makeText(this, "O novo email é igual ao atual", Toast.LENGTH_SHORT).show();
                return;
            }
            performEmailChange(newEmail);
        });
        builder.setNegativeButton("Cancelar", (dialog, which) -> dialog.cancel());
        builder.show();
    }

    private void performEmailChange(String newEmail) {
        FirebaseUser user = mAuth.getCurrentUser();
        if (user == null) return;

        progressDialog.show();
        user.verifyBeforeUpdateEmail(newEmail)
                .addOnCompleteListener(task -> {
                    progressDialog.dismiss();
                    if (task.isSuccessful()) {
                        Toast.makeText(this,
                                "Email de verificação enviado para o novo endereço! Por favor verifique.",
                                Toast.LENGTH_LONG).show();
                        if (textEmail != null) {
                            textEmail.setText(newEmail);
                        }
                    } else {
                        if (task.getException() instanceof com.google.firebase.auth.FirebaseAuthRecentLoginRequiredException) {
                            Toast.makeText(this,
                                    "Por segurança, precisa de terminar sessão e voltar a entrar antes de mudar o email.",
                                    Toast.LENGTH_LONG).show();
                        } else {
                            String error = com.example.vdcscore.utils.FirebaseErrorUtils.getErrorMessagePt(task.getException());
                            Toast.makeText(this, "Erro ao alterar email: " + error, Toast.LENGTH_LONG).show();
                        }
                    }
                });
    }

    private void showLogoutConfirmation() {
        new AlertDialog.Builder(this)
                .setTitle("Terminar Sessão")
                .setMessage("Tem a certeza que deseja terminar a sessão?")
                .setPositiveButton("Sim", (dialog, which) -> logoutUser())
                .setNegativeButton("Cancelar", null)
                .show();
    }

    private void logoutUser() {
        // Limpar credenciais guardadas
        SharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();
        editor.clear();
        editor.apply();

        // Fazer logout do Firebase
        mAuth.signOut();

        Toast.makeText(this, "Sessão terminada", Toast.LENGTH_SHORT).show();

        // Voltar para o login
        Intent intent = new Intent(ContaActivity.this, LoginActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        startActivity(intent);
        finish();
    }
}
