package com.example.bem;

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

import androidx.appcompat.app.AppCompatActivity;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.FieldValue;
import com.google.firebase.firestore.FirebaseFirestore;
import android.util.Log;
import java.util.HashMap;
import java.util.Map;

public class InviteCodeActivity extends AppCompatActivity {

    private EditText inputCode;
    private Button btnContinue;
    private ProgressBar progressBar;

    private FirebaseAuth mAuth;
    private FirebaseFirestore db;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_invite_code);

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

        inputCode = findViewById(R.id.input_invite_code);
        btnContinue = findViewById(R.id.btn_validate_code);
        progressBar = findViewById(R.id.progress_bar_invite);

        btnContinue.setOnClickListener(v -> validateInviteCode());
    }

    private void validateInviteCode() {
        String code = inputCode.getText().toString().trim();
        FirebaseUser currentUser = mAuth.getCurrentUser();

        if (TextUtils.isEmpty(code)) {
            inputCode.setError("Insira o código.");
            return;
        }

        // MASTER CODE CHECK
        if (code.equals("47281935")) {
            getSharedPreferences("app_prefs", MODE_PRIVATE)
                    .edit()
                    .putString("user_type", "guardian")
                    .apply();

            Toast.makeText(this, "Modo Responsável Ativado", Toast.LENGTH_SHORT).show();
            Intent intent = new Intent(this, MainActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            startActivity(intent);
            finish();
            return;
        }

        if (code.length() != 6) {
            inputCode.setError("O código deve ter 6 dígitos.");
            return;
        }

        if (currentUser == null) {
            Toast.makeText(this, "Erro: Sessão inválida. Faça login novamente.", Toast.LENGTH_SHORT).show();
            return;
        }

        setLoading(true);

        // 1. Encontrar o código na coleção 'inviteCodes'
        db.collection("inviteCodes").document(code).get().addOnSuccessListener(documentSnapshot -> {
            if (!documentSnapshot.exists()) {
                showError("Código inválido ou expirado.");
                return;
            }

            Long createdAt = documentSnapshot.getLong("createdAt");
            long currentTime = System.currentTimeMillis();
            
            // Code expires in 30 seconds (same as the timer in GenerateCodeActivity)
            if (createdAt == null || (currentTime - createdAt) > 30000) {
                db.collection("inviteCodes").document(code).delete();
                showError("O código expirou. Por favor, gere um novo.");
                return;
            }

            String patientId = documentSnapshot.getString("userId");
            if (patientId == null) {
                showError("Erro no código. Tente gerar um novo.");
                return;
            }

            String guardianId = currentUser.getUid();

            // 1. Atualizar o perfil do responsável PRIMEIRO (ele tem permissão para o seu
            // próprio perfil)
            db.collection("users").document(guardianId)
                    .update("managedUsers", FieldValue.arrayUnion(patientId), "type", "guardian")
                    .addOnSuccessListener(aVoid -> {

                        // 2. Tentar atualizar o perfil do paciente (pode falhar por permissões)
                        Map<String, Object> patientUpdate = new HashMap<>();
                        patientUpdate.put("guardianId", guardianId);
                        patientUpdate.put("guardians", FieldValue.arrayUnion(guardianId));

                        db.collection("users").document(patientId)
                                .update(patientUpdate)
                                .addOnSuccessListener(aVoid1 -> {
                                    completeAssociation(code);
                                })
                                .addOnFailureListener(e -> {
                                    // Se falhar o paciente mas o responsável deu certo, avisamos mas prosseguimos
                                    Log.e("InviteCode", "Falha ao atualizar paciente (provavelmente permissões): "
                                            + e.getMessage());
                                    completeAssociation(code);
                                });

                    }).addOnFailureListener(e -> {
                        showError("Falha ao atualizar o seu perfil: " + e.getMessage());
                    });

        }).addOnFailureListener(e -> showError("Erro ao validar o código: " + e.getMessage()));
    }

    private void completeAssociation(String code) {
        // 3. Apagar o código de convite
        db.collection("inviteCodes").document(code).delete();

        // Salvar estado local
        getSharedPreferences("app_prefs", MODE_PRIVATE)
                .edit()
                .putString("user_type", "guardian")
                .apply();

        Toast.makeText(this, "Utilizador associado com sucesso!", Toast.LENGTH_LONG).show();
        Intent intent = new Intent(this, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        startActivity(intent);
        finish();
    }

    private void setLoading(boolean loading) {
        progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
        btnContinue.setEnabled(!loading);
    }

    private void showError(String message) {
        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
        setLoading(false);
    }
}
