import React, { useMemo, useState } from "react";
import { Pressable, ScrollView, StyleSheet, Text, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import type { MobileIntervention } from "../../types/intervention";
import { detailValue, getStatusStyle, isTodoStatus } from "../../shared/interventionUtils";

type Props = {
  interventions: MobileIntervention[];
  brandColor: string;
  onOpenDetail: (id: number) => void;
  // Jour a preselectionner a l'ouverture (deep-link notification "resume
  // quotidien"). "today" / "tomorrow" / absent => aujourd'hui.
  initialDay?: "today" | "tomorrow";
};

const WEEKDAYS = ["Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"];
const MONTHS = [
  "Janvier", "Fevrier", "Mars", "Avril", "Mai", "Juin",
  "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Decembre",
];

function parseDate(value: string | undefined): Date | null {
  if (!value) {
    return null;
  }
  const parsed = new Date(value.replace(" ", "T"));
  return Number.isNaN(parsed.getTime()) ? null : parsed;
}

function dayKey(y: number, m: number, d: number): string {
  return `${y}-${String(m + 1).padStart(2, "0")}-${String(d).padStart(2, "0")}`;
}

function keyOf(d: Date): string {
  return dayKey(d.getFullYear(), d.getMonth(), d.getDate());
}

function timeLabel(d: Date): string {
  return `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
}

type Entry = { it: MobileIntervention; date: Date };

export default function PlanningScreen({ interventions, brandColor, onOpenDetail, initialDay }: Readonly<Props>) {
  const insets = useSafeAreaInsets();
  const now = useMemo(() => new Date(), []);
  const todayKey = keyOf(now);

  // Cible initiale : aujourd'hui par defaut, demain si le deep-link l'indique.
  // `now`/`todayKey` restent la vraie date du jour (surlignage "aujourd'hui").
  const initialTarget = useMemo(() => {
    const t = new Date();
    if (initialDay === "tomorrow") {
      t.setDate(t.getDate() + 1);
    }
    return t;
  }, [initialDay]);

  const [viewYear, setViewYear] = useState(initialTarget.getFullYear());
  const [viewMonth, setViewMonth] = useState(initialTarget.getMonth());
  const [selectedKey, setSelectedKey] = useState(keyOf(initialTarget));

  // Index des interventions planifiees par jour (toutes dates confondues).
  const byDay = useMemo(() => {
    const map = new Map<string, Entry[]>();
    for (const it of interventions) {
      // Calendrier : on n'affiche que les missions "a faire / en cours"
      // (miroir de planning.php qui ne montre que planifiee + en_cours).
      if (!isTodoStatus(it.statut)) {
        continue;
      }
      const date = parseDate(it.date_prevue);
      if (!date) {
        continue;
      }
      const key = keyOf(date);
      const list = map.get(key) ?? [];
      list.push({ it, date });
      map.set(key, list);
    }
    for (const list of map.values()) {
      list.sort((a, b) => a.date.getTime() - b.date.getTime());
    }
    return map;
  }, [interventions]);

  // Construction de la grille du mois (semaines Lundi -> Dimanche).
  const weeks = useMemo(() => {
    const firstDay = new Date(viewYear, viewMonth, 1);
    const offset = (firstDay.getDay() + 6) % 7; // 0 = lundi
    const daysInMonth = new Date(viewYear, viewMonth + 1, 0).getDate();

    const cells: (number | null)[] = [];
    for (let i = 0; i < offset; i += 1) {
      cells.push(null);
    }
    for (let d = 1; d <= daysInMonth; d += 1) {
      cells.push(d);
    }
    while (cells.length % 7 !== 0) {
      cells.push(null);
    }
    const rows: (number | null)[][] = [];
    for (let i = 0; i < cells.length; i += 7) {
      rows.push(cells.slice(i, i + 7));
    }
    return rows;
  }, [viewYear, viewMonth]);

  const changeMonth = (delta: number) => {
    const base = new Date(viewYear, viewMonth + delta, 1);
    setViewYear(base.getFullYear());
    setViewMonth(base.getMonth());
  };

  const selectedEntries = byDay.get(selectedKey) ?? [];
  const monthCount = useMemo(() => {
    let n = 0;
    for (const [key, list] of byDay.entries()) {
      if (key.startsWith(`${viewYear}-${String(viewMonth + 1).padStart(2, "0")}-`)) {
        n += list.length;
      }
    }
    return n;
  }, [byDay, viewYear, viewMonth]);

  return (
    <ScrollView
      style={styles.screen}
      contentContainerStyle={[styles.content, { paddingBottom: insets.bottom + 24 }]}
      showsVerticalScrollIndicator={false}
    >
      {/* En-tete mois */}
      <View style={styles.monthHeader}>
        <Pressable style={styles.navBtn} onPress={() => changeMonth(-1)} hitSlop={8}>
          <Text style={[styles.navArrow, { color: brandColor }]}>‹</Text>
        </Pressable>
        <View style={styles.monthTitleBlock}>
          <Text style={styles.monthTitle}>
            {MONTHS[viewMonth]} {viewYear}
          </Text>
          <Text style={styles.monthCount}>
            {monthCount} intervention{monthCount > 1 ? "s" : ""}
          </Text>
        </View>
        <Pressable style={styles.navBtn} onPress={() => changeMonth(1)} hitSlop={8}>
          <Text style={[styles.navArrow, { color: brandColor }]}>›</Text>
        </Pressable>
      </View>

      {/* Jours de la semaine */}
      <View style={styles.weekRow}>
        {WEEKDAYS.map((w) => (
          <Text key={w} style={styles.weekday}>
            {w}
          </Text>
        ))}
      </View>

      {/* Grille */}
      <View style={styles.calendar}>
        {weeks.map((week, wi) => (
          <View key={`w${wi}`} style={styles.weekLine}>
            {week.map((day, di) => {
              if (day === null) {
                return <View key={`e${wi}-${di}`} style={styles.cell} />;
              }
              const key = dayKey(viewYear, viewMonth, day);
              const count = byDay.get(key)?.length ?? 0;
              const isToday = key === todayKey;
              const isSelected = key === selectedKey;
              return (
                <Pressable
                  key={key}
                  style={styles.cell}
                  onPress={() => setSelectedKey(key)}
                >
                  <View
                    style={[
                      styles.dayInner,
                      isToday && styles.dayToday,
                      isSelected && { backgroundColor: brandColor },
                    ]}
                  >
                    <Text
                      style={[
                        styles.dayNumber,
                        isSelected && styles.dayNumberSelected,
                      ]}
                    >
                      {day}
                    </Text>
                  </View>
                  {count > 0 ? (
                    <View
                      style={[
                        styles.dot,
                        { backgroundColor: isSelected ? brandColor : "#1e56a8" },
                      ]}
                    />
                  ) : (
                    <View style={styles.dotPlaceholder} />
                  )}
                </Pressable>
              );
            })}
          </View>
        ))}
      </View>

      {/* Liste du jour selectionne */}
      <Text style={styles.dayHeader}>
        {(() => {
          const [yy, mm, dd] = selectedKey.split("-").map(Number);
          const d = new Date(yy, mm - 1, dd);
          return `${WEEKDAYS[(d.getDay() + 6) % 7]} ${dd} ${MONTHS[mm - 1]}`;
        })()}
      </Text>

      {selectedEntries.length === 0 ? (
        <Text style={styles.muted}>Aucune intervention ce jour-la.</Text>
      ) : (
        selectedEntries.map(({ it, date }) => {
          const status = getStatusStyle(it.statut);
          return (
            <Pressable key={it.id} style={styles.row} onPress={() => onOpenDetail(it.id)}>
              <View style={[styles.timeBadge, { borderColor: brandColor }]}>
                <Text style={[styles.timeText, { color: brandColor }]}>{timeLabel(date)}</Text>
              </View>
              <View style={styles.rowBody}>
                <Text style={styles.rowTitle}>{detailValue(it.site_nom)}</Text>
                <Text style={styles.rowSub}>{detailValue(it.machine_nom)}</Text>
              </View>
              <View
                style={[
                  styles.chip,
                  { backgroundColor: status.backgroundColor, borderColor: status.borderColor },
                ]}
              >
                <Text style={[styles.chipText, { color: status.color }]}>{status.label}</Text>
              </View>
            </Pressable>
          );
        })
      )}
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  screen: {
    flex: 1,
    backgroundColor: "#edf2f8",
  },
  content: {
    padding: 16,
    gap: 12,
  },
  monthHeader: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
  },
  navBtn: {
    width: 40,
    height: 40,
    alignItems: "center",
    justifyContent: "center",
    borderRadius: 10,
    backgroundColor: "#ffffff",
    borderWidth: 1,
    borderColor: "#d8e4f6",
  },
  navArrow: {
    fontSize: 24,
    fontWeight: "800",
    lineHeight: 26,
  },
  monthTitleBlock: {
    alignItems: "center",
  },
  monthTitle: {
    fontSize: 17,
    fontWeight: "800",
    color: "#16325c",
  },
  monthCount: {
    fontSize: 12,
    color: "#6a7a96",
    fontWeight: "600",
  },
  weekRow: {
    flexDirection: "row",
  },
  weekday: {
    flex: 1,
    textAlign: "center",
    fontSize: 11,
    fontWeight: "700",
    color: "#66748f",
  },
  calendar: {
    backgroundColor: "#ffffff",
    borderWidth: 1,
    borderColor: "#d8e4f6",
    borderRadius: 14,
    padding: 6,
    gap: 2,
  },
  weekLine: {
    flexDirection: "row",
  },
  cell: {
    flex: 1,
    aspectRatio: 1,
    alignItems: "center",
    justifyContent: "center",
    gap: 2,
  },
  dayInner: {
    width: 34,
    height: 34,
    borderRadius: 17,
    alignItems: "center",
    justifyContent: "center",
  },
  dayToday: {
    borderWidth: 1.5,
    borderColor: "#9db8e6",
  },
  dayNumber: {
    fontSize: 14,
    fontWeight: "700",
    color: "#1f2f4f",
  },
  dayNumberSelected: {
    color: "#ffffff",
  },
  dot: {
    width: 6,
    height: 6,
    borderRadius: 3,
  },
  dotPlaceholder: {
    width: 6,
    height: 6,
  },
  dayHeader: {
    fontSize: 15,
    fontWeight: "800",
    color: "#16325c",
    marginTop: 4,
    textTransform: "capitalize",
  },
  muted: {
    color: "#6a7a96",
  },
  row: {
    flexDirection: "row",
    alignItems: "center",
    gap: 10,
    backgroundColor: "#ffffff",
    borderWidth: 1,
    borderColor: "#d8e4f6",
    borderRadius: 12,
    padding: 12,
  },
  timeBadge: {
    borderWidth: 1,
    borderRadius: 8,
    paddingVertical: 4,
    paddingHorizontal: 6,
    minWidth: 52,
    alignItems: "center",
  },
  timeText: {
    fontSize: 13,
    fontWeight: "800",
  },
  rowBody: {
    flex: 1,
    gap: 2,
  },
  rowTitle: {
    fontSize: 14,
    fontWeight: "700",
    color: "#16325c",
  },
  rowSub: {
    fontSize: 12,
    color: "#6a7a96",
  },
  chip: {
    borderWidth: 1,
    borderRadius: 999,
    paddingVertical: 3,
    paddingHorizontal: 8,
  },
  chipText: {
    fontSize: 11,
    fontWeight: "700",
  },
});
