import { useRef, useEffect, useState, useCallback } from "preact/hooks";
import type { Trip, Day } from "../../lib/types";
import type { TripTimeState } from "../../lib/use-trip-time";
import { slugify } from "../../lib/categories";

function DayCard({ day, time, dayIdx }: {
  day: Day;
  time: TripTimeState;
  dayIdx: number;
}) {
  const currentRef = useRef<HTMLDivElement>(null);
  const isToday = dayIdx === time.todayIdx;
  const isPast = time.tripStarted && dayIdx < time.todayIdx;

  useEffect(() => {
    if (isToday && currentRef.current) {
      currentRef.current.scrollIntoView({ behavior: "smooth", block: "center" });
    }
  }, [isToday, time.currentStopIdx]);

  const dateStr = new Date(day.date + "T12:00:00").toLocaleDateString("en-US", {
    weekday: "long",
    month: "long",
    day: "numeric",
  });

  return (
    <div class={`day-card ${isToday ? "day-today" : ""} ${isPast ? "day-past" : ""}`}>
      <div class="day-card-header">
        <div class="day-card-label">
          {isToday && <span class="day-today-dot" />}
          {day.label}
        </div>
        <div class="day-card-date">{dateStr}</div>
      </div>

      <div class="day-card-summary">{day.summary}</div>

      <div class="day-timeline">
        {day.stops.map((stop, i) => {
          const isCurrent = isToday && i === time.currentStopIdx;
          const isNext = isToday && i === time.nextStopIdx;
          const isDone = isToday && time.currentStopIdx >= 0 && i < time.currentStopIdx;
          const isPastDay = isPast;

          return (
            <div
              key={i}
              ref={isCurrent ? currentRef : undefined}
              class={`tl-item ${isCurrent ? "tl-current" : ""} ${isNext ? "tl-next" : ""} ${isDone || isPastDay ? "tl-done" : ""}`}
            >
              {isCurrent && <span class="tl-now-badge">NOW</span>}
              {isNext && <span class="tl-next-badge">NEXT</span>}
              {stop.arrival && <span class="tl-time">{stop.arrival}</span>}
              <div class="tl-body">
                <span class="tl-name">{stop.name}</span>
                {stop.purpose && <span class="tl-purpose">{stop.purpose}</span>}
              </div>
            </div>
          );
        })}
      </div>

      {day.drives.length > 0 && (
        <div class="day-drives">
          {day.drives.map((d, i) => (
            <div key={i} class="drive-row">
              <span class="drive-route">{d.from} <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" style="flex-shrink:0;vertical-align:middle"><path d="M5 12h14M12 5l7 7-7 7"/></svg> {d.to}</span>
              <span class="drive-info">
                {d.distance && <span>{d.distance}</span>}
                {d.duration && <span> · {d.duration}</span>}
              </span>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function PackCard({ items, initialState, tripId }: {
  items: string[];
  initialState: Record<string, boolean>;
  tripId: string;
}) {
  const [checked, setChecked] = useState<Record<string, boolean>>(() => {
    const state: Record<string, boolean> = {};
    items.forEach(item => {
      const key = slugify(item);
      state[key] = initialState[key] ?? false;
    });
    return state;
  });

  const saveTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);

  const persist = useCallback((newState: Record<string, boolean>) => {
    if (saveTimeout.current) clearTimeout(saveTimeout.current);
    saveTimeout.current = setTimeout(() => {
      fetch(`/travel/api/pack-state?tripId=${tripId}`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(newState),
      }).catch(() => {});
    }, 500);
  }, [tripId]);

  const toggle = useCallback((item: string) => {
    const key = slugify(item);
    setChecked(prev => {
      const next = { ...prev, [key]: !prev[key] };
      persist(next);
      return next;
    });
  }, [persist]);

  const total = items.length;
  const done = Object.values(checked).filter(Boolean).length;
  const pct = total > 0 ? Math.round((done / total) * 100) : 0;

  if (items.length === 0) return null;

  return (
    <div class="day-card pack-card">
      <div class="day-card-header">
        <div class="day-card-label">Packing List</div>
        <div class="day-card-date">{done}/{total} packed</div>
      </div>

      <div class="pack-progress">
        <div class="pack-progress-bar" style={{ width: `${pct}%` }} />
      </div>

      <div class="pack-items">
        {items.map(item => {
          const key = slugify(item);
          const isChecked = checked[key] ?? false;
          return (
            <div
              key={key}
              class={`pack-item ${isChecked ? "checked" : ""}`}
              onClick={() => toggle(item)}
            >
              <div class="pack-check">
                <span class="pack-check-mark">{isChecked ? "\u2713" : ""}</span>
              </div>
              <span class="pack-label">{item}</span>
            </div>
          );
        })}
      </div>
    </div>
  );
}

export function ItineraryTab({ trip, time, packItems, packState }: {
  trip: Trip;
  time: TripTimeState;
  packItems: string[];
  packState: Record<string, boolean>;
}) {
  return (
    <div class="itinerary-tab">
      <div class="itin-section">
        <div class="itin-section-label">Day by Day</div>
        {trip.days.map((day, i) => (
          <DayCard
            key={i}
            day={day}
            time={time}
            dayIdx={i}
          />
        ))}
        <PackCard items={packItems} initialState={packState} tripId={trip.id} />
      </div>
    </div>
  );
}
