// Interactive date field: quick chips (Today / Tomorrow / Next week) plus an
// expandable month calendar. Pure RN views — identical on Android, iOS, web.
import { useMemo, useState } from "react";
import { Pressable, StyleSheet, Text, View } from "react-native";
import { haptic } from "../lib/haptics";
import { C } from "../lib/theme";

const DAY_MS = 86_400_000;
const WEEKDAYS = ["M", "T", "W", "T", "F", "S", "S"];
const MONTHS = [
  "January", "February", "March", "April", "May", "June",
  "July", "August", "September", "October", "November", "December",
];

function iso(d: Date): string {
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
}

function fromIso(s: string): Date {
  const [y, m, d] = s.split("-").map(Number);
  return new Date(y, m - 1, d);
}

function pretty(s: string): string {
  const d = fromIso(s);
  const today = new Date();
  const diff = Math.round((d.getTime() - new Date(today.getFullYear(), today.getMonth(), today.getDate()).getTime()) / DAY_MS);
  if (diff === 0) return "Today";
  if (diff === 1) return "Tomorrow";
  if (diff === -1) return "Yesterday";
  const wd = d.toLocaleDateString("en-AU", { weekday: "short" });
  return `${wd} ${d.getDate()} ${MONTHS[d.getMonth()].slice(0, 3)}${d.getFullYear() !== today.getFullYear() ? ` ${d.getFullYear()}` : ""}`;
}

function Calendar({ value, onPick }: { value: string | null; onPick: (v: string) => void }) {
  const initial = value ? fromIso(value) : new Date();
  const [year, setYear] = useState(initial.getFullYear());
  const [month, setMonth] = useState(initial.getMonth());
  const todayIso = iso(new Date());

  const weeks = useMemo(() => {
    const first = new Date(year, month, 1);
    const start = new Date(first);
    start.setDate(1 - ((first.getDay() + 6) % 7)); // back to Monday
    return Array.from({ length: 6 }, (_, w) =>
      Array.from({ length: 7 }, (_, i) => {
        const d = new Date(start);
        d.setDate(start.getDate() + w * 7 + i);
        return d;
      }),
    );
  }, [year, month]);

  const shift = (delta: number) => {
    haptic.select();
    const d = new Date(year, month + delta, 1);
    setYear(d.getFullYear());
    setMonth(d.getMonth());
  };

  return (
    <View style={s.calendar}>
      <View style={s.calHead}>
        <Pressable onPress={() => shift(-1)} hitSlop={10} style={s.arrow}>
          <Text style={s.arrowText}>‹</Text>
        </Pressable>
        <Text style={s.calTitle}>
          {MONTHS[month]} {year}
        </Text>
        <Pressable onPress={() => shift(1)} hitSlop={10} style={s.arrow}>
          <Text style={s.arrowText}>›</Text>
        </Pressable>
      </View>
      <View style={s.week}>
        {WEEKDAYS.map((w, i) => (
          <Text key={i} style={s.weekday}>
            {w}
          </Text>
        ))}
      </View>
      {weeks.map((week, wi) => (
        <View key={wi} style={s.week}>
          {week.map((d) => {
            const dIso = iso(d);
            const inMonth = d.getMonth() === month;
            const selected = dIso === value;
            const isToday = dIso === todayIso;
            return (
              <Pressable
                key={dIso}
                style={[s.day, selected && s.daySelected, !selected && isToday && s.dayToday]}
                onPress={() => {
                  haptic.select();
                  onPick(dIso);
                }}
              >
                <Text
                  style={[
                    s.dayText,
                    !inMonth && { color: C.border },
                    selected && { color: "#FFFFFF", fontWeight: "700" },
                    !selected && isToday && { color: C.accent },
                  ]}
                >
                  {d.getDate()}
                </Text>
              </Pressable>
            );
          })}
        </View>
      ))}
    </View>
  );
}

export default function DateField({
  label,
  value,
  onChange,
  clearable,
}: {
  label: string;
  value: string | null;
  onChange: (v: string | null) => void;
  clearable?: boolean;
}) {
  const [open, setOpen] = useState(false);
  const today = new Date();
  const quick = [
    { label: "Today", v: iso(today) },
    { label: "Tomorrow", v: iso(new Date(today.getTime() + DAY_MS)) },
    { label: "Next week", v: iso(new Date(today.getTime() + 7 * DAY_MS)) },
  ];

  return (
    <View style={{ marginBottom: 14 }}>
      <View style={s.labelRow}>
        <Text style={s.label}>{label}</Text>
        {value != null && <Text style={s.chosen}>{pretty(value)}</Text>}
      </View>
      <View style={s.rowWrap}>
        {quick.map((q) => (
          <Pressable
            key={q.label}
            style={[s.chip, value === q.v && s.chipActive]}
            onPress={() => {
              haptic.select();
              onChange(value === q.v && clearable ? null : q.v);
            }}
          >
            <Text style={[s.chipText, value === q.v && { color: C.text }]}>{q.label}</Text>
          </Pressable>
        ))}
        <Pressable
          style={[s.chip, open && s.chipActive]}
          onPress={() => {
            haptic.select();
            setOpen(!open);
          }}
        >
          <Text style={[s.chipText, open && { color: C.text }]}>📆 Pick…</Text>
        </Pressable>
        {clearable && value != null && (
          <Pressable
            style={s.chip}
            onPress={() => {
              haptic.tap();
              onChange(null);
            }}
          >
            <Text style={s.chipText}>Clear</Text>
          </Pressable>
        )}
      </View>
      {open && (
        <Calendar
          value={value}
          onPick={(v) => {
            onChange(v);
            setOpen(false);
          }}
        />
      )}
    </View>
  );
}

const s = StyleSheet.create({
  labelRow: { flexDirection: "row", justifyContent: "space-between", alignItems: "baseline", marginBottom: 6 },
  label: { color: C.muted, fontSize: 13, textTransform: "uppercase", letterSpacing: 0.5 },
  chosen: { color: C.accent, fontSize: 14, fontWeight: "600" },
  rowWrap: { flexDirection: "row", flexWrap: "wrap", gap: 8 },
  chip: {
    paddingVertical: 8,
    paddingHorizontal: 14,
    borderRadius: 20,
    backgroundColor: C.surface,
    borderWidth: 1,
    borderColor: C.border,
  },
  chipActive: { backgroundColor: C.surface2, borderColor: C.accent },
  chipText: { color: C.muted, fontSize: 14 },
  calendar: {
    marginTop: 10,
    backgroundColor: C.surface,
    borderRadius: 14,
    borderWidth: 1,
    borderColor: C.border,
    padding: 10,
  },
  calHead: { flexDirection: "row", justifyContent: "space-between", alignItems: "center", marginBottom: 6 },
  calTitle: { color: C.text, fontSize: 15, fontWeight: "600" },
  arrow: { paddingHorizontal: 14, paddingVertical: 4 },
  arrowText: { color: C.accent, fontSize: 22, fontWeight: "600" },
  week: { flexDirection: "row" },
  weekday: { flex: 1, textAlign: "center", color: C.muted, fontSize: 11, paddingVertical: 4 },
  day: {
    flex: 1,
    aspectRatio: 1.15,
    alignItems: "center",
    justifyContent: "center",
    borderRadius: 999,
    margin: 1,
  },
  daySelected: { backgroundColor: C.accent },
  dayToday: { borderWidth: 1, borderColor: C.accent },
  dayText: { color: C.text, fontSize: 14 },
});
