package com.example.bem;

import android.app.AlertDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.app.AppCompatActivity;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.FirebaseFirestore;

import java.util.HashMap;
import java.util.Map;
import java.util.List;
import android.widget.LinearLayout;
import android.widget.ImageView;

public class LoginActivity extends AppCompatActivity {

    private FirebaseAuth mAuth;
    private FirebaseFirestore db;
    private SharedPreferences prefs;
    private static final String PREF_DARK_MODE = "dark_mode";

    private EditText inputEmail;
    private EditText inputPassword;
    private EditText inputName;
    private EditText inputPhone;
    private Button btnLogin;
    private TextView textLoginType;
    private TextView textSwitchMode;
    private TextView textForgotPassword;
    private TextView textSwitchToGuardian;
    private ProgressBar progressBar;

    private boolean isRegisterMode = false;
    private boolean isGuardianMode = false;

    // Saved Accounts
    private LinearLayout storedAccountsContainer;
    private TextView textStoredAccounts;
    private static final String PREF_SAVED_ACCOUNTS = "saved_accounts";
    // Format: "email|name;email2|name2"

    private static class SavedAccount {
        String email;
        String name;
        String type; // "user" or "guardian"
        String phone;

        SavedAccount(String email, String name, String type, String phone) {
            this.email = email;
            this.name = name;
            this.type = type != null ? type : "user";
            this.phone = phone != null ? phone : "";
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        prefs = getSharedPreferences("app_prefs", MODE_PRIVATE);
        applyThemeFromPrefs();

        mAuth = FirebaseAuth.getInstance();
        db = FirebaseFirestore.getInstance();

        // Auto-Login: Check if user is already signed in
        FirebaseUser currentUser = mAuth.getCurrentUser();
        if (currentUser != null) {
            checkUserTypeAndRedirect(currentUser.getUid(), false);
            return; // Don't setup the rest of UI
        }

        setContentView(R.layout.activity_login);

        inputEmail = findViewById(R.id.inputEmail);
        inputPassword = findViewById(R.id.inputPassword);
        inputName = findViewById(R.id.inputName);
        inputPhone = findViewById(R.id.inputPhone);
        btnLogin = findViewById(R.id.btnLogin);
        textLoginType = findViewById(R.id.textLoginType);
        textSwitchMode = findViewById(R.id.textSwitchMode);
        textForgotPassword = findViewById(R.id.textForgotPassword);
        textSwitchToGuardian = findViewById(R.id.textSwitchToGuardian);

        storedAccountsContainer = findViewById(R.id.storedAccountsContainer);
        textStoredAccounts = findViewById(R.id.textStoredAccounts);

        loadSavedAccounts();

        btnLogin.setOnClickListener(v -> handleLogin());
        textSwitchMode.setOnClickListener(v -> toggleMode());
        textForgotPassword.setOnClickListener(v -> showForgotPasswordDialog());
        textSwitchToGuardian.setOnClickListener(v -> switchToGuardianMode());
    }

    private void switchToGuardianMode() {
        isGuardianMode = !isGuardianMode;

        if (isGuardianMode) {
            textLoginType.setText("Login de Responsável");
            textSwitchToGuardian.setText("👤 Sou Utilizador");
            inputPhone.setVisibility(View.GONE);
        } else {
            textLoginType.setText("Login de Utilizador");
            textSwitchToGuardian.setText("🔒 Sou Responsável");
            inputPhone.setVisibility(View.GONE);
        }

        isRegisterMode = false;
        loadSavedAccounts(); // Refresh list for new mode
        updateUI();
    }

    private void toggleMode() {
        isRegisterMode = !isRegisterMode;
        updateUI();
    }

    private void updateUI() {
        if (isRegisterMode) {
            btnLogin.setText("Criar Conta");
            textSwitchMode.setText("Já tem conta? Entrar");
            inputName.setVisibility(View.VISIBLE);
            inputPhone.setVisibility(isGuardianMode ? View.GONE : View.VISIBLE);
        } else {
            btnLogin.setText("Entrar");
            textSwitchMode.setText("Não tem conta? Registar");
            inputName.setVisibility(View.GONE);
            inputPhone.setVisibility(View.GONE);
        }
    }

    private void handleLogin() {
        String email = inputEmail.getText().toString().trim();
        String password = inputPassword.getText().toString().trim();
        String name = inputName.getText().toString().trim();
        String phone = inputPhone.getText().toString().trim();

        if (TextUtils.isEmpty(email)) {
            inputEmail.setError("Insira o email");
            return;
        }

        if (!android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
            inputEmail.setError("Email inválido");
            return;
        }

        if (TextUtils.isEmpty(password)) {
            inputPassword.setError("Insira a palavra-passe");
            return;
        }

        if (password.length() < 6) {
            inputPassword.setError("Mínimo 6 caracteres");
            return;
        }

        if (isRegisterMode && TextUtils.isEmpty(name)) {
            inputName.setError("Insira o nome");
            return;
        }

        btnLogin.setEnabled(false);

        if (isRegisterMode) {
            registerUser(email, password, name, phone);
        } else {
            loginUser(email, password);
        }
    }

    private void registerUser(String email, String password, String name, String phone) {
        mAuth.createUserWithEmailAndPassword(email, password)
                .addOnCompleteListener(task -> {
                    if (task.isSuccessful()) {
                        FirebaseUser user = mAuth.getCurrentUser();
                        if (user != null) {
                            saveUserData(user.getUid(), email, name, phone, true);
                        } else {
                            btnLogin.setEnabled(true);
                            Toast.makeText(this, "Erro ao obter utilizador. Tente entrar com o email/senha.",
                                    Toast.LENGTH_LONG).show();
                            mAuth.signOut();
                        }
                    } else {
                        btnLogin.setEnabled(true);
                        String error = task.getException() != null ? task.getException().getMessage()
                                : "Erro desconhecido";
                        Toast.makeText(this, "Erro: " + error, Toast.LENGTH_LONG).show();
                    }
                });
    }

    private void saveAccountLocally(String email, String name, String phone, String type) {
        if (email == null || name == null)
            return;

        List<SavedAccount> accounts = getSavedAccountsList();

        // Remove if exists to re-add at top (updating type/phone if needed)
        accounts.removeIf(a -> a.email.equals(email));
        accounts.add(0, new SavedAccount(email, name, type, phone));

        // Serialize
        StringBuilder sb = new StringBuilder();
        for (SavedAccount acc : accounts) {
            if (sb.length() > 0)
                sb.append(";");
            sb.append(acc.email).append("|").append(acc.name).append("|").append(acc.type).append("|")
                    .append(acc.phone);
        }

        prefs.edit().putString(PREF_SAVED_ACCOUNTS, sb.toString()).apply();
    }

    private List<SavedAccount> getSavedAccountsList() {
        List<SavedAccount> list = new java.util.ArrayList<>();
        String saved = prefs.getString(PREF_SAVED_ACCOUNTS, "");
        if (!TextUtils.isEmpty(saved)) {
            String[] pairs = saved.split(";");
            for (String pair : pairs) {
                String[] parts = pair.split("\\|");
                if (parts.length >= 2) {
                    // Backwards compatibility
                    String type = parts.length > 2 ? parts[2] : "user";
                    String phone = parts.length > 3 ? parts[3] : "";

                    // Auto-correct: If it has a phone number, it's a Guardian account
                    if ("user".equals(type) && !TextUtils.isEmpty(phone)) {
                        type = "guardian";
                    }

                    list.add(new SavedAccount(parts[0], parts[1], type, phone));
                }
            }
        }
        return list;
    }

    private void loadSavedAccounts() {
        List<SavedAccount> accounts = getSavedAccountsList();

        // Filter by current mode
        String currentType = isGuardianMode ? "guardian" : "user";
        accounts.removeIf(a -> !a.type.equals(currentType));

        if (accounts.isEmpty()) {
            textStoredAccounts.setVisibility(View.GONE);
            storedAccountsContainer.setVisibility(View.GONE);
            return;
        }

        textStoredAccounts.setVisibility(View.VISIBLE);
        storedAccountsContainer.setVisibility(View.VISIBLE);
        storedAccountsContainer.removeAllViews();

        android.view.LayoutInflater inflater = android.view.LayoutInflater.from(this);

        for (SavedAccount acc : accounts) {
            View itemView = inflater.inflate(R.layout.item_saved_account, storedAccountsContainer, false);
            TextView nameView = itemView.findViewById(R.id.textSavedName);
            TextView emailView = itemView.findViewById(R.id.textSavedEmail);
            ImageView avatarView = itemView.findViewById(R.id.imageViewAvatar); // Need to add ID to XML first if not
                                                                                // present, checking XML... XML didn't
                                                                                // have ID for image.
            View removeBtn = itemView.findViewById(R.id.btnRemoveAccount);

            nameView.setText(acc.name);
            emailView.setText(acc.email);
            // Future: Load custom profile image here if available in SavedAccount

            itemView.setOnClickListener(v -> {
                inputEmail.setText(acc.email);
                if (acc.phone != null && !acc.phone.isEmpty()) {
                    inputPhone.setText(acc.phone);
                }
                inputPassword.requestFocus();
            });

            removeBtn.setOnClickListener(v -> {
                removeSavedAccount(acc.email);
                loadSavedAccounts(); // Refresh
            });

            storedAccountsContainer.addView(itemView);
        }
    }

    private void removeSavedAccount(String email) {
        List<SavedAccount> accounts = getSavedAccountsList();
        accounts.removeIf(a -> a.email.equals(email));

        StringBuilder sb = new StringBuilder();
        for (SavedAccount acc : accounts) {
            if (sb.length() > 0)
                sb.append(";");
            sb.append(acc.email).append("|").append(acc.name).append("|").append(acc.type).append("|")
                    .append(acc.phone);
        }
        prefs.edit().putString(PREF_SAVED_ACCOUNTS, sb.toString()).apply();
    }

    private void saveUserData(String uid, String email, String name, String phone, boolean fromRegister) {
        String type = isGuardianMode ? "guardian" : "user";
        saveAccountLocally(email, name, phone, type); // Save locally on register success
        Map<String, Object> userData = new HashMap<>();
        userData.put("email", email);
        userData.put("name", name);
        userData.put("phone", phone != null ? phone : "");
        userData.put("type", isGuardianMode ? "guardian" : "user");
        userData.put("createdAt", System.currentTimeMillis());

        db.collection("users").document(uid)
                .set(userData)
                .addOnSuccessListener(aVoid -> {
                    if (fromRegister) {
                        Toast.makeText(this, "✓ Conta criada! Faça login para continuar.", Toast.LENGTH_LONG).show();
                        mAuth.signOut();
                        btnLogin.setEnabled(true);
                        // Reload clean screen
                        Intent intent = getIntent();
                        finish();
                        startActivity(intent);
                    } else {
                        checkUserTypeAndRedirect(uid, true);
                    }
                })
                .addOnFailureListener(e -> {
                    btnLogin.setEnabled(true);
                    Toast.makeText(this, "Erro ao salvar dados: " + e.getMessage(), Toast.LENGTH_LONG).show();
                });
    }

    private void loginUser(String email, String password) {
        mAuth.signInWithEmailAndPassword(email, password)
                .addOnCompleteListener(task -> {
                    if (task.isSuccessful()) {
                        FirebaseUser user = mAuth.getCurrentUser();
                        if (user != null) {
                            checkUserTypeAndRedirect(user.getUid(), true);
                        } else {
                            if (btnLogin != null)
                                btnLogin.setEnabled(true);
                            Toast.makeText(this, "Erro ao iniciar sessão. Tente novamente.", Toast.LENGTH_LONG).show();
                        }
                    } else {
                        if (btnLogin != null)
                            btnLogin.setEnabled(true);
                        String error = task.getException() != null ? task.getException().getMessage()
                                : "Credenciais inválidas";
                        Toast.makeText(this, "Erro: " + error, Toast.LENGTH_LONG).show();
                    }
                });
    }

    private void checkUserTypeAndRedirect(String uid, boolean isManualLogin) {
        db.collection("users").document(uid)
                .get()
                .addOnSuccessListener(document -> {
                    if (document.exists()) {
                        String type = document.getString("type");
                        if (type == null)
                            type = "user";
                        String currentMode = isGuardianMode ? "guardian" : "user";

                        if (isManualLogin && !type.equals(currentMode)) {
                            mAuth.signOut();
                            if (btnLogin != null)
                                btnLogin.setEnabled(true);
                            String modeName = isGuardianMode ? "Responsável" : "Utilizador";
                            String otherMode = isGuardianMode ? "Utilizador" : "Responsável";
                            Toast.makeText(this, "Esta conta é de " + otherMode + ". Mude para o modo " + otherMode
                                    + " para entrar.", Toast.LENGTH_LONG).show();
                            return;
                        }

                        prefs.edit()
                                .putString("user_type", type)
                                .putString("user_name", document.getString("name"))
                                .apply();

                        saveAccountLocally(document.getString("email"), document.getString("name"),
                                document.getString("phone"), type);

                        if ("guardian".equals(type)) {
                            // Check if guardian has any patient linked
                            List<String> managed = (List<String>) document.get("managedUsers");
                            if (managed == null || managed.isEmpty()) {
                                redirectToInviteCode();
                            } else {
                                redirectToApp();
                            }
                        } else {
                            redirectToApp();
                        }
                    } else {
                        // Se o perfil não existe, cria um com base no modo de login atual.
                        FirebaseUser user = mAuth.getCurrentUser();
                        String email = user != null ? user.getEmail() : "";
                        String name = (email != null && email.contains("@")) ? email.substring(0, email.indexOf("@"))
                                : "Utilizador";
                        String userType = isGuardianMode ? "guardian" : "user";

                        Map<String, Object> userData = new HashMap<>();
                        userData.put("email", email);
                        userData.put("name", name);
                        userData.put("phone", "");
                        userData.put("type", userType);
                        userData.put("createdAt", System.currentTimeMillis());

                        db.collection("users").document(uid)
                                .set(userData)
                                .addOnSuccessListener(aVoid -> {
                                    prefs.edit()
                                            .putString("user_type", userType)
                                            .putString("user_name", name)
                                            .apply();

                                    saveAccountLocally(email, name, "", userType);

                                    if ("guardian".equals(userType)) {
                                        redirectToInviteCode();
                                    } else {
                                        redirectToApp();
                                    }
                                })
                                .addOnFailureListener(e -> {
                                    Toast.makeText(this, "Erro ao criar perfil: " + e.getMessage(), Toast.LENGTH_SHORT)
                                            .show();
                                    btnLogin.setEnabled(true);
                                });
                    }
                })
                .addOnFailureListener(e -> {
                    Toast.makeText(this, "Erro ao carregar dados do utilizador: " + e.getMessage(), Toast.LENGTH_SHORT)
                            .show();
                    btnLogin.setEnabled(true);
                });
    }

    private void redirectToApp() {
        Intent intent = new Intent(this, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        startActivity(intent);
        finish();
    }

    private void redirectToInviteCode() {
        Intent intent = new Intent(this, InviteCodeActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        startActivity(intent);
        finish();
    }

    private void showForgotPasswordDialog() {
        View dialogView = getLayoutInflater().inflate(android.R.layout.simple_list_item_1, null);
        EditText emailInput = new EditText(this);
        emailInput.setHint("Email de recuperação");
        emailInput.setInputType(android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
        emailInput.setPadding(50, 40, 50, 40);

        new AlertDialog.Builder(this)
                .setTitle("Recuperar Palavra-passe")
                .setMessage("Insira o email para receber o link de recuperação:")
                .setView(emailInput)
                .setPositiveButton("Enviar", (dialog, which) -> {
                    String email = emailInput.getText().toString().trim();
                    if (TextUtils.isEmpty(email)) {
                        Toast.makeText(this, "Insira um email", Toast.LENGTH_SHORT).show();
                        return;
                    }

                    mAuth.sendPasswordResetEmail(email)
                            .addOnSuccessListener(aVoid -> {
                                Toast.makeText(this, "✓ Email enviado! Verifique a caixa de entrada.",
                                        Toast.LENGTH_LONG).show();
                            })
                            .addOnFailureListener(e -> {
                                Toast.makeText(this, "Erro: " + e.getMessage(), Toast.LENGTH_LONG).show();
                            });
                })
                .setNegativeButton("Cancelar", null)
                .show();
    }

    private void applyThemeFromPrefs() {
        boolean dark = getSharedPreferences("app_prefs", MODE_PRIVATE).getBoolean(PREF_DARK_MODE, false);
        AppCompatDelegate
                .setDefaultNightMode(dark ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO);
    }
}
