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.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.recyclerview.widget.LinearLayoutManager;

import com.borjabolufer.elevate.MainActivity;
import com.borjabolufer.elevate.R;
import com.borjabolufer.elevate.adapters.EjercicioAdapter;
import com.borjabolufer.elevate.databinding.FragmentHomeBinding;
import com.borjabolufer.elevate.model.DiasEntrenamiento;
import com.borjabolufer.elevate.model.Entrenamiento;
import com.borjabolufer.elevate.model.Ejercicio;
import com.borjabolufer.elevate.model.Semana;
import com.borjabolufer.elevate.ui.fragments.DetalleEjercicioFragment;
import com.borjabolufer.elevate.utils.JsonParser;
import com.borjabolufer.elevate.utils.JsonUtils;
import com.google.android.material.chip.Chip;

import org.json.JSONObject;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

public class HomeFragment extends Fragment implements EjercicioAdapter.OnItemClickListener {

    private static final String TAG = "HomeFragment";

    private FragmentHomeBinding binding;
    private JsonParser jsonParser;
    private Semana semanaActual;
    private EjercicioAdapter ejercicioAdapter;
    private List<EjercicioItem> ejerciciosList;
    private String diaSeleccionado = obtenerDiaActual();

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

        Log.d(TAG, "HomeFragment creado");

        inicializarComponentes();
        configurarRecyclerView();
        configurarChipsDias();
        cargarDatos();

        return root;
    }

    private void inicializarComponentes() {
        jsonParser = new JsonParser(getContext());
        ejerciciosList = new ArrayList<>();

        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("EEEE, dd MMM yyyy", new Locale("es", "ES"));
        sdf.setTimeZone(calendar.getTimeZone());
        binding.textFechaActual.setText(sdf.format(calendar.getTime()));

        Log.d(TAG, "Componentes inicializados, día seleccionado: " + diaSeleccionado);
    }

    private void cargarDatos() {
        String email = obtenerEmailUsuarioActual();
        if (email == null) {
            mostrarError("Usuario no identificado");
            return;
        }

        Log.d(TAG, "Cargando datos para usuario: " + email);

        String contenidoJson = JsonUtils.cargarPlanDelUsuario(getContext(), email);
        if (contenidoJson == null) {
            mostrarError("No se encontró el plan del usuario");
            return;
        }

        JSONObject rawJson;
        try {
            rawJson = new JSONObject(contenidoJson);
        } catch (Exception e) {
            Log.e(TAG, "Error al procesar JSON", e);
            mostrarError("Error al procesar el JSON");
            return;
        }

        semanaActual = jsonParser.convertirJsonASemana(rawJson);

        if (jsonParser.validarSemana(semanaActual)) {
            Log.d(TAG, "Semana validada correctamente");
            cargarEjerciciosDelDia(diaSeleccionado);
        } else {
            Log.e(TAG, "Error validando semana");
            mostrarError("Error al cargar los datos");
        }
    }

    private void configurarRecyclerView() {
        ejercicioAdapter = new EjercicioAdapter(ejerciciosList, this);
        binding.recyclerEjercicios.setLayoutManager(new LinearLayoutManager(getContext()));
        binding.recyclerEjercicios.setAdapter(ejercicioAdapter);
    }

    private void configurarChipsDias() {
        String[] diasSemana = {"Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado", "Domingo"};

        for (String dia : diasSemana) {
            Chip chip = new Chip(getContext());
            chip.setText(dia);
            chip.setCheckable(true);
            chip.setChecked(dia.equals(diaSeleccionado));

            chip.setOnCheckedChangeListener((compoundButton, isChecked) -> {
                if (isChecked) {
                    diaSeleccionado = dia;
                    Log.d(TAG, "Día seleccionado cambiado a: " + dia);
                    cargarEjerciciosDelDia(dia);

                      
                    for (int i = 0; i < binding.chipGroupDias.getChildCount(); i++) {
                        Chip otherChip = (Chip) binding.chipGroupDias.getChildAt(i);
                        if (!otherChip.getText().equals(dia)) {
                            otherChip.setChecked(false);
                        }
                    }
                }
            });

            binding.chipGroupDias.addView(chip);
        }
    }

    private void cargarEjerciciosDelDia(String dia) {
        if (semanaActual == null) {
            Log.w(TAG, "semanaActual es null, no se pueden cargar ejercicios");
            return;
        }

        DiasEntrenamiento diaEntrenamiento = jsonParser.obtenerDia(semanaActual, dia);

        if (diaEntrenamiento == null || diaEntrenamiento.getEntrenamiento() == null) {
            Log.d(TAG, "Día de descanso: " + dia);
            mostrarDiaDescanso(dia);
            return;
        }

        Entrenamiento entrenamiento = diaEntrenamiento.getEntrenamiento();
        mostrarDiaEntrenamiento(dia, entrenamiento);
    }

    private void mostrarDiaDescanso(String dia) {
        binding.textDiaActual.setText("Día de descanso");
        binding.textDescripcionDia.setText("Hoy es tu día de recuperación. ¡Disfrútalo!");
        ejerciciosList.clear();

        if (ejercicioAdapter != null) {
            ejercicioAdapter.notifyDataSetChanged();
        }
    }

    private void mostrarDiaEntrenamiento(String dia, Entrenamiento entrenamiento) {
        binding.textDiaActual.setText(dia);
        binding.textDescripcionDia.setText("Entrenamiento de " + dia.toLowerCase());

        ejerciciosList.clear();

          
        if (entrenamiento.getCalentamiento() != null && !entrenamiento.getCalentamiento().isEmpty()) {
            ejerciciosList.add(new EjercicioItem("CALENTAMIENTO", 0, 0, "calentamiento", true));
            for (Ejercicio ejercicio : entrenamiento.getCalentamiento()) {
                ejerciciosList.add(new EjercicioItem(
                        ejercicio.getNombre(),
                        ejercicio.getSeries(),
                        ejercicio.getDescripcion(),
                        ejercicio.getRepeticiones(),
                        ejercicio.getDescanso(),
                        ejercicio.getVideoUrl(),
                        "calentamiento"
                ));
            }
        }

          
        if (entrenamiento.getEjercicios_principales() != null && !entrenamiento.getEjercicios_principales().isEmpty()) {
            ejerciciosList.add(new EjercicioItem("EJERCICIOS PRINCIPALES", 0, 0, "principal", true));
            for (Ejercicio ejercicio : entrenamiento.getEjercicios_principales()) {
                ejerciciosList.add(new EjercicioItem(
                        ejercicio.getNombre(),
                        ejercicio.getSeries(),
                        ejercicio.getDescripcion(),
                        ejercicio.getRepeticiones(),
                        ejercicio.getDescanso(),
                        ejercicio.getVideoUrl(),
                        "principal"
                ));
            }
        }

          
        if (entrenamiento.getEnfriamiento() != null && !entrenamiento.getEnfriamiento().isEmpty()) {
            ejerciciosList.add(new EjercicioItem("ENFRIAMIENTO", 0, 0, "enfriamiento", true));
            for (Ejercicio ejercicio : entrenamiento.getEnfriamiento()) {
                ejerciciosList.add(new EjercicioItem(
                        ejercicio.getNombre(),
                        ejercicio.getSeries(),
                        ejercicio.getDescripcion(),
                        ejercicio.getRepeticiones(),
                        ejercicio.getDescanso(),
                        ejercicio.getVideoUrl(),
                        "enfriamiento"
                ));
            }
        }

        if (ejercicioAdapter != null) {
            ejercicioAdapter.notifyDataSetChanged();
        }

        Log.d(TAG, "Ejercicios cargados para " + dia + ": " + ejerciciosList.size() + " items");
    }

    private String obtenerEmailUsuarioActual() {
        try {
            SharedPreferences prefs = getActivity().getSharedPreferences("ElevatePrefs", Context.MODE_PRIVATE);
            String email = prefs.getString("user_email", null);
            Log.d(TAG, "Email cargado: " + email);
            return email;
        } catch (Exception e) {
            Log.e(TAG, "Error obteniendo email usuario", e);
            return null;
        }
    }

    private String obtenerDiaActual() {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("EEEE", new Locale("es", "ES"));
            Calendar calendar = Calendar.getInstance();
            String diaFormateado = sdf.format(calendar.getTime());

              
            return diaFormateado.substring(0, 1).toUpperCase() + diaFormateado.substring(1).toLowerCase();
        } catch (Exception e) {
            Log.e(TAG, "Error obteniendo día actual", e);
            return "Lunes";   
        }
    }

    private void mostrarError(String mensaje) {
        Log.e(TAG, "Error: " + mensaje);
        if (getContext() != null) {
            Toast.makeText(getContext(), mensaje, Toast.LENGTH_SHORT).show();
        }
    }

      
    @Override
    public void onItemClick(EjercicioItem item) {
        if (item.isEsHeader()) {
            Log.d(TAG, "Click en header ignorado: " + item.getNombre());
            return;
        }

        Log.d(TAG, "Click en ejercicio: " + item.getNombre());

        try {
              
            if (item.getNombre() == null || item.getTipo() == null) {
                mostrarError("Datos del ejercicio incompletos");
                return;
            }

              
            Ejercicio ejercicio = new Ejercicio(
                    item.getNombre(),
                    item.getDescripcion() != null ? item.getDescripcion() : "",
                    item.getSeries(),
                    item.getRepeticiones(),
                    item.getDescanso() != null ? item.getDescanso() : "",
                    item.getVideoURL() != null ? item.getVideoURL() : ""
            );

              
            if (!isNavigationSafe()) {
                Log.w(TAG, "Navegación no segura, reintentando...");
                mostrarError("Espera un momento e inténtalo de nuevo");
                return;
            }

              
            Bundle args = new Bundle();
            args.putSerializable("ejercicio", ejercicio);
            args.putString("tipo_ejercicio", item.getTipo());

              
            navegarConNavController(args);

        } catch (Exception e) {
            Log.e(TAG, "Error navegando a detalle ejercicio", e);
            mostrarError("Error al abrir detalle del ejercicio");
        }
    }

      
    private boolean isNavigationSafe() {
        try {
            return isAdded() &&
                    getContext() != null &&
                    getActivity() != null &&
                    !getActivity().isFinishing() &&
                    !getActivity().isDestroyed() &&
                    getView() != null;
        } catch (Exception e) {
            Log.e(TAG, "Error verificando seguridad navegación", e);
            return false;
        }
    }

      
    private void navegarConNavController(Bundle args) {
        try {
            NavController navController = Navigation.findNavController(requireView());

              
            if (navController.getCurrentDestination() != null) {
                int currentDestId = navController.getCurrentDestination().getId();

                if (currentDestId == R.id.nav_home) {
                      
                    navController.navigate(R.id.action_home_to_detalle_ejercicio, args);
                    Log.d(TAG, "Navegación exitosa con NavController");
                } else {
                    Log.w(TAG, "No estamos en home fragment, usando fallback");
                    navegarConFragmentManager(args);
                }
            } else {
                Log.w(TAG, "Destino actual es null, usando fallback");
                navegarConFragmentManager(args);
            }

        } catch (Exception navException) {
            Log.w(TAG, "NavController falló, usando FragmentManager", navException);
            navegarConFragmentManager(args);
        }
    }

      
    private void navegarConFragmentManager(Bundle args) {
        try {
            Ejercicio ejercicio = (Ejercicio) args.getSerializable("ejercicio");
            String tipo = args.getString("tipo_ejercicio");

            if (ejercicio == null || tipo == null) {
                mostrarError("Error en datos del ejercicio");
                return;
            }

            DetalleEjercicioFragment detalleFragment = DetalleEjercicioFragment.newInstance(ejercicio, tipo);

            requireActivity().getSupportFragmentManager()
                    .beginTransaction()
                    .replace(R.id.nav_host_fragment_content_main, detalleFragment)
                    .addToBackStack("detalle_ejercicio")
                    .commitAllowingStateLoss();   

            Log.d(TAG, "Navegación exitosa con FragmentManager");

        } catch (Exception e) {
            Log.e(TAG, "Error en navegación con FragmentManager", e);
            mostrarError("No se pudo abrir el detalle");
        }
    }

      
    @Override
    public void onResume() {
        super.onResume();

        Log.d(TAG, "HomeFragment onResume");

          
        verificarEstadoFragment();

          
        if (semanaActual == null) {
            Log.d(TAG, "Recargando datos en onResume");
            cargarDatos();
        }
    }

    private void verificarEstadoFragment() {
        try {
            if (getActivity() != null) {
                FragmentManager fm = getActivity().getSupportFragmentManager();

                  
                if (fm.getBackStackEntryCount() > 5) {
                    Log.w(TAG, "Demasiados fragments en back stack: " + fm.getBackStackEntryCount());

                      
                    if (getActivity() instanceof MainActivity) {
                        ((MainActivity) getActivity()).resetNavigation();
                    }
                }
            }
        } catch (Exception e) {
            Log.e(TAG, "Error verificando estado fragment", e);
        }
    }

      
    public void refrescarDatos() {
        Log.d(TAG, "Refrescando datos del HomeFragment");

        if (isAdded() && getContext() != null) {
            cargarDatos();
        }
    }

      
    public void navegarADia(String dia) {
        Log.d(TAG, "Navegando a día: " + dia);

        if (dia != null && !dia.isEmpty()) {
            diaSeleccionado = dia;

              
            for (int i = 0; i < binding.chipGroupDias.getChildCount(); i++) {
                Chip chip = (Chip) binding.chipGroupDias.getChildAt(i);
                chip.setChecked(chip.getText().equals(dia));
            }

              
            cargarEjerciciosDelDia(dia);
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();

        Log.d(TAG, "HomeFragment onDestroyView");

          
        ejercicioAdapter = null;
        ejerciciosList = null;
        semanaActual = null;
        binding = null;
    }

      
    public static class EjercicioItem implements Serializable {
        private String nombre;
        private String descripcion;
        private int series;
        private int repeticiones;
        private String descanso;
        private String tipo;
        private String videoURL;
        private boolean esHeader;

          
        public EjercicioItem(String nombre, int series, int repeticiones, String tipo, boolean esHeader) {
            this.nombre = nombre != null ? nombre : "";
            this.series = series;
            this.repeticiones = repeticiones;
            this.tipo = tipo != null ? tipo : "";
            this.esHeader = esHeader;
        }

          
        public EjercicioItem(String nombre, int series, String descripcion, int repeticiones, String descanso, String videoURL, String tipo) {
            this.nombre = nombre != null ? nombre : "";
            this.series = series;
            this.descripcion = descripcion != null ? descripcion : "";
            this.repeticiones = repeticiones;
            this.descanso = descanso != null ? descanso : "";
            this.videoURL = videoURL != null ? videoURL : "";
            this.tipo = tipo != null ? tipo : "";
            this.esHeader = false;
        }

          
        public String getNombre() { return nombre != null ? nombre : ""; }
        public void setNombre(String nombre) { this.nombre = nombre != null ? nombre : ""; }

        public String getDescripcion() { return descripcion != null ? descripcion : ""; }
        public void setDescripcion(String descripcion) { this.descripcion = descripcion != null ? descripcion : ""; }

        public int getSeries() { return series; }
        public void setSeries(int series) { this.series = series; }

        public int getRepeticiones() { return repeticiones; }
        public void setRepeticiones(int repeticiones) { this.repeticiones = repeticiones; }

        public String getDescanso() { return descanso != null ? descanso : ""; }
        public void setDescanso(String descanso) { this.descanso = descanso != null ? descanso : ""; }

        public String getTipo() { return tipo != null ? tipo : ""; }
        public void setTipo(String tipo) { this.tipo = tipo != null ? tipo : ""; }

        public String getVideoURL() { return videoURL != null ? videoURL : ""; }
        public void setVideoURL(String videoURL) { this.videoURL = videoURL != null ? videoURL : ""; }

        public boolean isEsHeader() { return esHeader; }
        public void setEsHeader(boolean esHeader) { this.esHeader = esHeader; }
    }
}