package com.borjabolufer.elevate.ui.fragments;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.cardview.widget.CardView;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;

import com.borjabolufer.elevate.MainActivity;
import com.borjabolufer.elevate.R;
import com.borjabolufer.elevate.model.Altura;
import com.borjabolufer.elevate.model.DiasEntrenamiento;
import com.borjabolufer.elevate.model.Edad;
import com.borjabolufer.elevate.model.Intensidad;
import com.borjabolufer.elevate.model.Objetivo;
import com.borjabolufer.elevate.model.Peso;
import com.borjabolufer.elevate.model.Sexo;
import com.borjabolufer.elevate.model.Usuario;
import com.borjabolufer.elevate.model.UsuarioDbHelper;
import com.borjabolufer.elevate.model.UsuarioEntity;
import com.borjabolufer.elevate.utils.JsonUtils;
import com.borjabolufer.elevate.utils.PasswordUtils;
import com.google.android.material.navigation.NavigationView;
import com.google.android.material.snackbar.Snackbar;

import java.io.File;

public class ProfileFragment extends Fragment {

    private static final String TAG = "ProfileFragment";
    private static final String PREFS_NAME = "ElevatePrefs";
    private static final String KEY_USER_EMAIL = "user_email";

      
    private EditText editNombre;
    private EditText editEmail;
    private EditText editPassword;
    private Button btnGuardarPerfil;
    private CardView cardPerfil;

      
    private Spinner spinnerSexo;
    private EditText editEdad;
    private EditText editPeso;
    private EditText editAltura;
    private Spinner spinnerObjetivo;
    private Spinner spinnerIntensidad;
    private Spinner spinnerDias;
    private Button btnActualizarPlan;
    private CardView cardPlan;

      
    private UsuarioDbHelper dbHelper;
    private String currentUserEmail;
    private UsuarioEntity usuarioActual;

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

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        inicializarComponentes(view);
        configurarSpinners();
        cargarDatosUsuario();
        configurarListeners();
    }

    private void inicializarComponentes(View view) {
        dbHelper = new UsuarioDbHelper(getContext());

          
        SharedPreferences prefs = getActivity().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        currentUserEmail = prefs.getString(KEY_USER_EMAIL, null);

          
        cardPerfil = view.findViewById(R.id.card_perfil);
        editNombre = view.findViewById(R.id.edit_nombre);
        editEmail = view.findViewById(R.id.edit_email);
        editPassword = view.findViewById(R.id.edit_password);
        btnGuardarPerfil = view.findViewById(R.id.btn_guardar_perfil);

          
        cardPlan = view.findViewById(R.id.card_plan);
        spinnerSexo = view.findViewById(R.id.spinner_sexo);
        editEdad = view.findViewById(R.id.edit_edad);
        editPeso = view.findViewById(R.id.edit_peso);
        editAltura = view.findViewById(R.id.edit_altura);
        spinnerObjetivo = view.findViewById(R.id.spinner_objetivo);
        spinnerIntensidad = view.findViewById(R.id.spinner_intensidad);
        spinnerDias = view.findViewById(R.id.spinner_dias);
        btnActualizarPlan = view.findViewById(R.id.btn_actualizar_plan);

        Log.d(TAG, "Componentes inicializados para usuario: " + currentUserEmail);
    }

    private void configurarSpinners() {
          
        String[] sexoOpciones = {"Masculino", "Femenino" ,"Otro"};
        ArrayAdapter<String> sexoAdapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_item, sexoOpciones);
        sexoAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinnerSexo.setAdapter(sexoAdapter);

          
        String[] objetivoOpciones = {"Perder grasa", "Tonificar", "Ganar masa"};
        ArrayAdapter<String> objetivoAdapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_item, objetivoOpciones);
        objetivoAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinnerObjetivo.setAdapter(objetivoAdapter);

          
        String[] intensidadOpciones = {"Baja", "Media", "Alta"};
        ArrayAdapter<String> intensidadAdapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_item, intensidadOpciones);
        intensidadAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinnerIntensidad.setAdapter(intensidadAdapter);

          
        String[] diasOpciones = {"1","2" ,"3", "4", "5", "6", "7"};
        ArrayAdapter<String> diasAdapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_item, diasOpciones);
        diasAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinnerDias.setAdapter(diasAdapter);
    }

    private void cargarDatosUsuario() {
        if (currentUserEmail == null) {
            Toast.makeText(getContext(), "Error: Usuario no identificado", Toast.LENGTH_SHORT).show();
            return;
        }

        usuarioActual = dbHelper.getUsuarioPorEmail(currentUserEmail);
        if (usuarioActual == null) {
            Toast.makeText(getContext(), "Error al cargar datos del usuario", Toast.LENGTH_SHORT).show();
            return;
        }

          
        editNombre.setText(usuarioActual.getNombreCompleto());
        editEmail.setText(usuarioActual.getEmail());
        editPassword.setText("");   

          
        if (usuarioActual.getSexo() != null) {
            int sexoPosition = usuarioActual.getSexo().equals("Masculino") ? 0 : 1;
            spinnerSexo.setSelection(sexoPosition);
        }

        if (usuarioActual.getEdad() > 0) {
            editEdad.setText(String.valueOf(usuarioActual.getEdad()));
        }

        if (usuarioActual.getPeso() > 0) {
            editPeso.setText(String.valueOf(usuarioActual.getPeso()));
        }

        if (usuarioActual.getAltura() > 0) {
            editAltura.setText(String.valueOf(usuarioActual.getAltura()));
        }

          
        configurarSeleccionSpinner(spinnerObjetivo, usuarioActual.getObjetivo());
        configurarSeleccionSpinner(spinnerIntensidad, usuarioActual.getIntensidad());

        if (usuarioActual.getDiasEntrenamiento() > 0) {
            int diasPosition = usuarioActual.getDiasEntrenamiento()  - 1;
            if (diasPosition >= 0 && diasPosition < 4) {
                spinnerDias.setSelection(diasPosition);
            }
        }

        Log.d(TAG, "Datos cargados para usuario: " + currentUserEmail);
    }

    private void configurarSeleccionSpinner(Spinner spinner, String valor) {
        if (valor == null) return;

        ArrayAdapter adapter = (ArrayAdapter) spinner.getAdapter();
        for (int i = 0; i < adapter.getCount(); i++) {
            if (adapter.getItem(i).toString().equals(valor)) {
                spinner.setSelection(i);
                break;
            }
        }
    }

    private void configurarListeners() {
        btnGuardarPerfil.setOnClickListener(v -> guardarPerfilPersonal());
        btnActualizarPlan.setOnClickListener(v -> actualizarPlanEntrenamiento());
    }

    private void guardarPerfilPersonal() {
        String nuevoNombre = editNombre.getText().toString().trim();
        String nuevoEmail = editEmail.getText().toString().trim();
        String nuevaPassword = editPassword.getText().toString().trim();

        if (nuevoNombre.isEmpty() || nuevoEmail.isEmpty()) {
            Toast.makeText(getContext(), "Nombre y email son obligatorios", Toast.LENGTH_SHORT).show();
            return;
        }

          
        if (!android.util.Patterns.EMAIL_ADDRESS.matcher(nuevoEmail).matches()) {
            Toast.makeText(getContext(), "Formato de email inválido", Toast.LENGTH_SHORT).show();
            return;
        }

          
        if (!nuevoEmail.equals(currentUserEmail) && dbHelper.checkUserEmailExists(nuevoEmail)) {
            Toast.makeText(getContext(), "Este email ya está en uso", Toast.LENGTH_SHORT).show();
            return;
        }

          
        String emailOriginal = currentUserEmail;

          
        usuarioActual.setNombreCompleto(nuevoNombre);
        usuarioActual.setEmail(nuevoEmail);

          
        if (!nuevaPassword.isEmpty()) {
            String passwordHash = PasswordUtils.hashPassword(nuevaPassword);
            usuarioActual.setPasswordHash(passwordHash);
        }

          
        boolean actualizado = actualizarUsuarioEnBD();

        if (actualizado) {
              
            if (!nuevoEmail.equals(emailOriginal)) {
                gestionarCambioEmailArchivo(emailOriginal, nuevoEmail);

                  
                SharedPreferences prefs = getActivity().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
                prefs.edit().putString(KEY_USER_EMAIL, nuevoEmail).apply();
                currentUserEmail = nuevoEmail;
            }

              
            actualizarHeaderNavigationDrawer(nuevoNombre, nuevoEmail);

            Toast.makeText(getContext(), "Perfil actualizado correctamente", Toast.LENGTH_SHORT).show();
            editPassword.setText("");   
        } else {
            Toast.makeText(getContext(), "Error al actualizar perfil", Toast.LENGTH_SHORT).show();
        }
    }

      
    private void actualizarHeaderNavigationDrawer(String nuevoNombre, String nuevoEmail) {
        try {
            if (getActivity() instanceof MainActivity) {
                MainActivity mainActivity = (MainActivity) getActivity();

                  
                NavigationView navigationView = mainActivity.findViewById(R.id.nav_view);

                if (navigationView != null) {
                    View headerView = navigationView.getHeaderView(0);

                    TextView headerTitle = headerView.findViewById(R.id.nav_header_title);
                    TextView headerSubtitle = headerView.findViewById(R.id.nav_header_subtitle);

                    if (headerTitle != null) {
                        headerTitle.setText(nuevoNombre);
                        Log.d(TAG, "Header title actualizado: " + nuevoNombre);
                    }

                    if (headerSubtitle != null) {
                        headerSubtitle.setText(nuevoEmail);
                        Log.d(TAG, "Header subtitle actualizado: " + nuevoEmail);
                    }
                }
            }
        } catch (Exception e) {
            Log.e(TAG, "Error al actualizar header del navigation drawer", e);
        }
    }

    private void gestionarCambioEmailArchivo(String emailOriginal, String nuevoEmail) {
        new Thread(() -> {
            try {
                  
                boolean migracionBD = dbHelper.migrarPlanJson(emailOriginal, nuevoEmail);
                Log.d(TAG, "Migración en BD: " + migracionBD);

                  
                File fileOriginal = JsonUtils.obtenerArchivoPlan(getContext(), emailOriginal);
                File fileNuevo = JsonUtils.obtenerArchivoPlan(getContext(), nuevoEmail);

                if (fileOriginal.exists()) {
                    try {
                          
                        String contenidoPlan = JsonUtils.cargarPlanDelUsuario(getContext(), emailOriginal);

                        if (contenidoPlan != null && !contenidoPlan.trim().isEmpty()) {
                              
                            java.io.FileWriter writer = new java.io.FileWriter(fileNuevo);
                            writer.write(contenidoPlan);
                            writer.flush();
                            writer.close();

                              
                            boolean eliminado = fileOriginal.delete();

                            Log.d(TAG, "Migración de archivos exitosa:");
                            Log.d(TAG, "- Archivo original eliminado: " + eliminado);
                            Log.d(TAG, "- Nuevo archivo creado: " + fileNuevo.exists());
                            Log.d(TAG, "- Plan migrado de " + fileOriginal.getName() + " a " + fileNuevo.getName());

                        } else {
                            Log.w(TAG, "Archivo original vacío o no se pudo leer");
                        }

                    } catch (java.io.IOException e) {
                        Log.e(TAG, "Error de I/O al migrar archivo: " + e.getMessage());
                    }
                } else {
                    Log.w(TAG, "Archivo original no existe: " + fileOriginal.getAbsolutePath());

                      
                    if (migracionBD) {
                        boolean creado = dbHelper.guardarPlanJsonEnArchivo(getContext(), nuevoEmail);
                        Log.d(TAG, "Archivo creado desde BD: " + creado);
                    }
                }

            } catch (Exception e) {
                Log.e(TAG, "Error general al gestionar cambio de email", e);
            }
        }).start();
    }

    private void actualizarPlanEntrenamiento() {
          
        String edadStr = editEdad.getText().toString().trim();
        String pesoStr = editPeso.getText().toString().trim();
        String alturaStr = editAltura.getText().toString().trim();

        if (edadStr.isEmpty() || pesoStr.isEmpty() || alturaStr.isEmpty()) {
            Toast.makeText(getContext(), "Todos los campos del plan son obligatorios", Toast.LENGTH_SHORT).show();
            return;
        }

        try {
            int edad = Integer.parseInt(edadStr);
            double peso = Double.parseDouble(pesoStr);
            double altura = Double.parseDouble(alturaStr);

            if (edad < 16 || edad > 100) {
                Toast.makeText(getContext(), "Edad debe estar entre 16 y 100 años", Toast.LENGTH_SHORT).show();
                return;
            }

            if (peso < 30 || peso > 300) {
                Toast.makeText(getContext(), "Peso debe estar entre 30 y 300 kg", Toast.LENGTH_SHORT).show();
                return;
            }

            if (altura < 100 || altura > 250) {
                Toast.makeText(getContext(), "Altura debe estar entre 100 y 250 cm", Toast.LENGTH_SHORT).show();
                return;
            }

              
            usuarioActual.setSexo(spinnerSexo.getSelectedItem().toString());
            usuarioActual.setEdad(edad);
            usuarioActual.setPeso(peso);
            usuarioActual.setAltura(altura);
            usuarioActual.setObjetivo(spinnerObjetivo.getSelectedItem().toString());
            usuarioActual.setIntentensidad(spinnerIntensidad.getSelectedItem().toString());
            usuarioActual.setDiasEntrenamiento(Integer.parseInt(spinnerDias.getSelectedItem().toString()));

              
            boolean actualizado = actualizarUsuarioEnBD();

            if (actualizado) {
                mostrarDialogoRegenerarPlan();
            } else {
                Toast.makeText(getContext(), "Error al actualizar plan", Toast.LENGTH_SHORT).show();
            }

        } catch (NumberFormatException e) {
            Toast.makeText(getContext(), "Valores numéricos inválidos", Toast.LENGTH_SHORT).show();
        }
    }

    private boolean actualizarUsuarioEnBD() {
        try {
            return dbHelper.actualizarUsuario(usuarioActual) > 0;
        } catch (Exception e) {
            Log.e(TAG, "Error al actualizar usuario", e);
            return false;
        }
    }

    private void mostrarDialogoRegenerarPlan() {
        Snackbar.make(getView(), "¿Regenerar plan de entrenamiento con los nuevos datos?", Snackbar.LENGTH_LONG)
                .setAction("Regenerar", v -> regenerarPlan())
                .show();
    }

    private void regenerarPlan() {
          
        Usuario usuario = crearUsuarioParaRegenerar();

          
        LoadingPlanFragment loadingFragment = LoadingPlanFragment.newInstanceRegeneration(
                usuario,
                currentUserEmail
        );

        requireActivity().getSupportFragmentManager()
                .beginTransaction()
                .setCustomAnimations(
                        androidx.navigation.ui.R.anim.nav_default_enter_anim,
                        androidx.navigation.ui.R.anim.nav_default_exit_anim,
                        androidx.navigation.ui.R.anim.nav_default_pop_enter_anim,
                        androidx.navigation.ui.R.anim.nav_default_pop_exit_anim
                )
                .replace(R.id.nav_host_fragment_content_main, loadingFragment)
                .commit();
    }

    private Usuario crearUsuarioParaRegenerar() {
        Usuario usuario = new Usuario();

          
          
        usuario.setSexo(new Sexo(usuarioActual.getSexo()));
        usuario.setEdad(new Edad(usuarioActual.getEdad()));
        usuario.setPeso(new Peso((float) usuarioActual.getPeso()));
        usuario.setAltura(new Altura((int) usuarioActual.getAltura()));
        usuario.setObjetivo(new Objetivo(usuarioActual.getObjetivo()));
        usuario.setIntensidad(new Intensidad(usuarioActual.getIntensidad()));
        usuario.setDias(new DiasEntrenamiento(usuarioActual.getDiasEntrenamiento()));

        return usuario;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (dbHelper != null) {
            dbHelper.close();
        }
    }
}