/**
 * CollectionCalendar.tsx
 *
 * Calendario mensual de recolección de la ruta ASIGNADA al usuario.
 * Respeta el principio de "visión de túnel": el ciudadano NO puede ver
 * rutas que no sean la suya.
 *
 * Reglas de color por día (solo para RUTA-40, RUTA-65 y RUTA-80):
 *   L, M, V, S → verde   (RESIDUOS ORGÁNICOS)
 *   Mi, J      → gris    (RESIDUOS SÓLIDOS URBANOS VALORABLES)
 *   Domingo    → vacío
 *
 * El patrón se aplica TODAS las semanas sin excepción. Las celdas del mes
 * anterior/siguiente que aparecen al inicio/final también se colorean
 * (en tono más claro) para que no queden huecos entre semana.
 *
 * Otras rutas: días neutros sin etiqueta.
 *
 * Si el usuario no ha validado su domicilio, se muestra un CTA.
 */

import { useMemo, useState } from "react";
import { View, Text, StyleSheet, Pressable } from "react-native";
import { Ionicons } from "@expo/vector-icons";
import { useRouter } from "expo-router";

import { useApp } from "../context/AppContext";
import { routes as routeCatalog } from "../data/mocks/routes.mock";

const MONTHS_ES = [
  "Enero",
  "Febrero",
  "Marzo",
  "Abril",
  "Mayo",
  "Junio",
  "Julio",
  "Agosto",
  "Septiembre",
  "Octubre",
  "Noviembre",
  "Diciembre",
];

const DAYS_ES = ["Lu", "Ma", "Mi", "Ju", "Vi", "Sa", "Do"];

const SPECIAL_ROUTES = new Set(["RUTA-40", "RUTA-65", "RUTA-80"]);

const COLOR_ORGANIC = "#10b981";
const COLOR_SOLID = "#9ca3af";
const COLOR_NEUTRAL = "#E5E7EB";
const COLOR_EMPTY = "transparent";

type DayInfo = { day: number; weekIndex: number; inMonth: boolean };

/** Convierte JS getDay (0=Sun..6=Sat) al índice Mon-first (0=Lun..6=Dom). */
const toMondayFirst = (jsDay: number): number => (jsDay === 0 ? 6 : jsDay - 1);

/**
 * Devuelve 42 celdas (6 semanas × 7 días). Las celdas del inicio/final
 * que caen fuera del mes actual también traen su día real del mes vecino
 * (con inMonth=false) para que el calendario no tenga huecos entre semana.
 */
function buildMonthGrid(year: number, month: number): DayInfo[] {
  const firstDay = new Date(year, month, 1);
  const firstWeekIndex = toMondayFirst(firstDay.getDay());
  const daysInMonth = new Date(year, month + 1, 0).getDate();
  const daysInPrevMonth = new Date(year, month, 0).getDate();

  const cells: DayInfo[] = [];

  // Días del mes anterior que aparecen al inicio
  for (let i = firstWeekIndex - 1; i >= 0; i--) {
    const date = new Date(year, month - 1, daysInPrevMonth - i);
    cells.push({
      day: daysInPrevMonth - i,
      weekIndex: toMondayFirst(date.getDay()),
      inMonth: false,
    });
  }

  // Días del mes actual
  for (let d = 1; d <= daysInMonth; d++) {
    const date = new Date(year, month, d);
    cells.push({
      day: d,
      weekIndex: toMondayFirst(date.getDay()),
      inMonth: true,
    });
  }

  // Días del mes siguiente para completar 42 celdas
  let next = 1;
  while (cells.length < 42) {
    const date = new Date(year, month + 1, next);
    cells.push({
      day: next,
      weekIndex: toMondayFirst(date.getDay()),
      inMonth: false,
    });
    next++;
  }

  return cells;
}

/**
 * Color de fondo según ruta + día de la semana.
 *   - SPECIAL_ROUTES (40/65/80): patrón verde/gris/vacío todas las semanas
 *   - Otras rutas: neutro (salvo domingo que va vacío)
 */
function colorForDay(routeId: string, weekIndex: number): string {
  if (!SPECIAL_ROUTES.has(routeId)) {
    return weekIndex === 6 ? COLOR_EMPTY : COLOR_NEUTRAL;
  }
  if (weekIndex === 0 || weekIndex === 1 || weekIndex === 4 || weekIndex === 5)
    return COLOR_ORGANIC; // Lun, Mar, Vie, Sáb
  if (weekIndex === 2 || weekIndex === 3) return COLOR_SOLID; // Mié, Jue
  return COLOR_EMPTY; // Domingo
}

export default function CollectionCalendar() {
  const { route } = useApp();
  const router = useRouter();
  const today = new Date();
  const [year, setYear] = useState(today.getFullYear());
  const [month, setMonth] = useState(today.getMonth());

  const myRouteId = route?.routeId ?? null;
  const myRouteName = useMemo(
    () => routeCatalog.find((r) => r.routeId === myRouteId)?.name ?? "",
    [myRouteId],
  );
  const isSpecial = myRouteId ? SPECIAL_ROUTES.has(myRouteId) : false;

  const grid = useMemo(() => buildMonthGrid(year, month), [year, month]);

  const handlePrev = () => {
    if (month === 0) {
      setMonth(11);
      setYear((y) => y - 1);
    } else {
      setMonth((m) => m - 1);
    }
  };

  const handleNext = () => {
    if (month === 11) {
      setMonth(0);
      setYear((y) => y + 1);
    } else {
      setMonth((m) => m + 1);
    }
  };

  // CTA: sin ruta asignada
  if (!myRouteId) {
    return (
      <View style={styles.container}>
        <View style={styles.headerRow}>
          <Ionicons name="calendar-outline" size={22} color="#0E8A61" />
          <Text style={styles.title}>Calendario de recolección</Text>
        </View>
        <View style={styles.ctaBox}>
          <Ionicons name="lock-closed-outline" size={28} color="#9CA3AF" />
          <Text style={styles.ctaText}>
            Necesitas validar tu domicilio para ver el calendario de tu ruta.
          </Text>
          <Pressable
            style={styles.ctaBtn}
            onPress={() => router.push("/addresses")}
          >
            <Text style={styles.ctaBtnText}>Validar domicilio</Text>
          </Pressable>
        </View>
      </View>
    );
  }

  return (
    <View style={styles.container}>
      <View style={styles.headerRow}>
        <Ionicons name="calendar-outline" size={22} color="#0E8A61" />
        <Text style={styles.title}>Calendario de recolección</Text>
      </View>

      <View style={styles.routeBadge}>
        <Ionicons name="bus-outline" size={14} color="#0E8A61" />
        <Text style={styles.routeBadgeText}>
          Tu ruta: <Text style={styles.routeBadgeBold}>{myRouteId}</Text>
          {myRouteName ? ` · ${myRouteName}` : ""}
        </Text>
      </View>

      {/* Navegador de mes */}
      <View style={styles.monthRow}>
        <Pressable onPress={handlePrev} style={styles.navBtn} hitSlop={10}>
          <Ionicons name="chevron-back" size={20} color="#0E8A61" />
        </Pressable>
        <Text style={styles.monthLabel}>
          {MONTHS_ES[month]} {year}
        </Text>
        <Pressable onPress={handleNext} style={styles.navBtn} hitSlop={10}>
          <Ionicons name="chevron-forward" size={20} color="#0E8A61" />
        </Pressable>
      </View>

      {/* Encabezado días de la semana */}
      <View style={styles.weekHeader}>
        {DAYS_ES.map((d) => (
          <View key={d} style={styles.weekCell}>
            <Text style={styles.weekText}>{d}</Text>
          </View>
        ))}
      </View>

      {/* Grid de días — 6 filas explícitas para evitar el problema de
          alineación que ocurre con flexWrap + porcentajes en React Native. */}
      <View>
        {Array.from({ length: 6 }).map((_, rowIdx) => (
          <View key={rowIdx} style={styles.gridRow}>
            {grid.slice(rowIdx * 7, (rowIdx + 1) * 7).map((cell, colIdx) => {
              const bg = colorForDay(myRouteId, cell.weekIndex);
              const isToday =
                cell.inMonth &&
                cell.day === today.getDate() &&
                month === today.getMonth() &&
                year === today.getFullYear();
              const isColored =
                bg === COLOR_ORGANIC || bg === COLOR_SOLID;
              const textColor = isColored ? "#FFFFFF" : "#0F172A";

              return (
                <View key={colIdx} style={styles.dayCell}>
                  <View
                    style={[
                      styles.dayInner,
                      { backgroundColor: bg },
                      !cell.inMonth && { opacity: 0.4 },
                      isToday && styles.todayBorder,
                    ]}
                  >
                    <Text style={[styles.dayText, { color: textColor }]}>
                      {cell.day}
                    </Text>
                  </View>
                </View>
              );
            })}
          </View>
        ))}
      </View>

      {/* Leyenda */}
      {isSpecial ? (
        <View style={styles.legend}>
          <View style={styles.legendRow}>
            <View
              style={[styles.legendSwatch, { backgroundColor: COLOR_ORGANIC }]}
            />
            <Text style={styles.legendText}>RESIDUOS ORGÁNICOS</Text>
          </View>
          <View style={styles.legendRow}>
            <View
              style={[styles.legendSwatch, { backgroundColor: COLOR_SOLID }]}
            />
            <Text style={styles.legendText}>
              RESIDUOS SÓLIDOS URBANOS VALORABLES
            </Text>
          </View>
        </View>
      ) : (
        <View style={styles.legendNeutral}>
          <Ionicons
            name="information-circle-outline"
            size={16}
            color="#6B7280"
          />
          <Text style={styles.legendNeutralText}>
            Tu ruta aún no tiene un calendario de separación específico. Te
            avisaremos cuando se publique.
          </Text>
        </View>
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: "#FFFFFF",
    borderRadius: 18,
    padding: 16,
    marginBottom: 18,
    shadowColor: "#000",
    shadowOffset: { width: 0, height: 4 },
    shadowOpacity: 0.06,
    shadowRadius: 8,
    elevation: 3,
  },
  headerRow: {
    flexDirection: "row",
    alignItems: "center",
    marginBottom: 12,
  },
  title: {
    fontSize: 18,
    fontWeight: "800",
    color: "#0F172A",
    marginLeft: 8,
  },
  routeBadge: {
    flexDirection: "row",
    alignItems: "center",
    alignSelf: "flex-start",
    backgroundColor: "#ECFDF5",
    paddingVertical: 6,
    paddingHorizontal: 10,
    borderRadius: 999,
    marginBottom: 8,
  },
  routeBadgeText: {
    fontSize: 12,
    color: "#065F46",
    marginLeft: 6,
  },
  routeBadgeBold: {
    fontWeight: "800",
    color: "#0E8A61",
  },
  monthRow: {
    flexDirection: "row",
    justifyContent: "space-between",
    alignItems: "center",
    marginTop: 8,
    marginBottom: 10,
  },
  navBtn: {
    width: 32,
    height: 32,
    borderRadius: 16,
    backgroundColor: "#ECFDF5",
    justifyContent: "center",
    alignItems: "center",
  },
  monthLabel: {
    fontSize: 16,
    fontWeight: "700",
    color: "#0F172A",
  },
  weekHeader: {
    flexDirection: "row",
    marginBottom: 6,
  },
  weekCell: {
    flex: 1,
    alignItems: "center",
    paddingVertical: 4,
    paddingHorizontal: 2,
  },
  weekText: {
    fontSize: 11,
    fontWeight: "700",
    color: "#9CA3AF",
  },
  gridRow: {
    flexDirection: "row",
  },
  dayCell: {
    flex: 1,
    padding: 2,
    aspectRatio: 1,
  },
  dayInner: {
    flex: 1,
    borderRadius: 8,
    justifyContent: "center",
    alignItems: "center",
  },
  dayText: {
    fontSize: 13,
    fontWeight: "600",
  },
  todayBorder: {
    borderWidth: 2,
    borderColor: "#0E8A61",
  },
  legend: {
    marginTop: 12,
    paddingTop: 12,
    borderTopWidth: 1,
    borderTopColor: "#F3F4F6",
  },
  legendRow: {
    flexDirection: "row",
    alignItems: "center",
    marginBottom: 6,
  },
  legendSwatch: {
    width: 14,
    height: 14,
    borderRadius: 4,
    marginRight: 8,
  },
  legendText: {
    fontSize: 11,
    fontWeight: "700",
    color: "#374151",
    letterSpacing: 0.3,
  },
  legendNeutral: {
    flexDirection: "row",
    alignItems: "center",
    marginTop: 12,
    paddingTop: 12,
    borderTopWidth: 1,
    borderTopColor: "#F3F4F6",
  },
  legendNeutralText: {
    fontSize: 11,
    color: "#6B7280",
    marginLeft: 6,
    flex: 1,
  },
  ctaBox: {
    alignItems: "center",
    padding: 20,
  },
  ctaText: {
    fontSize: 13,
    color: "#6B7280",
    textAlign: "center",
    marginTop: 10,
    marginBottom: 14,
  },
  ctaBtn: {
    backgroundColor: "#0E8A61",
    paddingHorizontal: 18,
    paddingVertical: 10,
    borderRadius: 10,
  },
  ctaBtnText: {
    color: "#FFFFFF",
    fontWeight: "700",
    fontSize: 13,
  },
});
