import { useState, useRef, useCallback } from "preact/hooks";
import type { ActualEntry, ActualKind, ActualDay, EntryWeather, WeatherCondition, CellularLevel } from "../../lib/types";

const KIND_META: Record<ActualKind, { icon: string; label: string; color: string; bg: string }> = {
  food:      { icon: "\u{1F37D}\uFE0F", label: "Food",      color: "#CCA050", bg: "rgba(204,160,80,0.12)" },
  stop:      { icon: "\u{1F4CD}",       label: "Stop",      color: "#7E98B0", bg: "rgba(126,152,176,0.12)" },
  note:      { icon: "\u{1F4DD}",       label: "Note",      color: "#6B7280", bg: "rgba(107,114,128,0.12)" },
  departure: { icon: "\u{1F697}",       label: "Departure", color: "#85A894", bg: "rgba(133,168,148,0.12)" },
  arrival:   { icon: "\u{1F3E8}",       label: "Arrival",   color: "#C9A84C", bg: "rgba(201,168,76,0.12)" },
};

const CONDITION_ICON: Record<WeatherCondition, string> = {
  "sunny": "\u2600\uFE0F",
  "mostly-clear": "\uD83C\uDF24\uFE0F",
  "partly-cloudy": "\u26C5",
  "cloudy": "\u2601\uFE0F",
  "foggy": "\uD83C\uDF2B\uFE0F",
  "rain": "\uD83C\uDF27\uFE0F",
};

function tempColor(t: number): string {
  if (t < 10) return "#60A5FA";
  if (t < 18) return "#67E8F9";
  if (t < 25) return "#6EE7A0";
  if (t < 30) return "#FBBF24";
  return "#F87171";
}

function uvColor(uv: number): string {
  if (uv <= 2) return "#6EE7A0";
  if (uv <= 5) return "#FBBF24";
  if (uv <= 7) return "#FB923C";
  if (uv <= 10) return "#F87171";
  return "#C084FC";
}

function uvLabel(uv: number): string {
  if (uv <= 2) return "Low";
  if (uv <= 5) return "Mod";
  if (uv <= 7) return "High";
  if (uv <= 10) return "V.High";
  return "Extreme";
}

const CELL_META: Record<CellularLevel, { icon: string; label: string; color: string; bg: string }> = {
  good:   { icon: "\u{1F4F6}", label: "Good",    color: "#6EE7A0", bg: "rgba(110,231,160,0.15)" },
  spotty: { icon: "\u{1F4F6}", label: "Spotty",  color: "#FBBF24", bg: "rgba(251,191,36,0.15)" },
  none:   { icon: "\u{1F4F5}", label: "None",    color: "#F87171", bg: "rgba(248,113,113,0.15)" },
};

function shortTime(iso: string): string {
  const d = new Date(iso);
  if (isNaN(d.getTime())) return "";
  const h = d.getHours();
  const ampm = h >= 12 ? "p" : "a";
  const h12 = h % 12 || 12;
  return `${h12}${ampm}`;
}

function DayStrips({ entries }: { entries: ActualEntry[] }) {
  const withWeather = entries.filter(e => e.weather);
  const withCell = entries.filter(e => e.cellular && e.cellular !== "good");
  if (withWeather.length === 0 && withCell.length === 0) return null;

  const temps = withWeather.map(e => ({ time: e.time, temp: e.weather!.temp }));
  const uvs = withWeather.filter(e => e.weather!.uv != null).map(e => ({ time: e.time, uv: e.weather!.uv!, title: e.title }));

  type CellSegment = { start: string; end: string; level: CellularLevel; titles: string[] };
  const cellSegments: CellSegment[] = [];
  for (const e of entries) {
    const level = e.cellular || "good";
    if (level === "good") continue;
    const last = cellSegments[cellSegments.length - 1];
    if (last && last.level === level) {
      last.end = e.time;
      last.titles.push(e.title.split("—")[0].trim());
    } else {
      cellSegments.push({ start: e.time, end: e.time, level, titles: [e.title.split("—")[0].trim()] });
    }
  }

  return (
    <div class="day-strips">
      {temps.length > 0 && (
        <div class="strip-row">
          <div class="strip-label">Temp</div>
          <div class="strip-bar">
            {temps.map((t, i) => (
              <div key={i} class="strip-segment" style={{ flex: 1, background: tempColor(t.temp) }}>
                <span class="strip-segment-text">{t.temp}°</span>
                <span class="strip-segment-time">{shortTime(t.time)}</span>
              </div>
            ))}
          </div>
        </div>
      )}
      {uvs.length > 0 && (
        <div class="strip-row">
          <div class="strip-label">UV</div>
          <div class="strip-uv-chips">
            {uvs.map((u, i) => (
              <div key={i} class="strip-uv-chip" style={{ background: uvColor(u.uv) }}>
                <span class="strip-segment-text">{u.uv}</span>
                <span class="strip-segment-time">{shortTime(u.time)}</span>
              </div>
            ))}
          </div>
        </div>
      )}
      {cellSegments.length > 0 && (
        <div class="strip-row">
          <div class="strip-label">Signal</div>
          <div class="strip-bar strip-bar-cell">
            {cellSegments.map((seg, i) => {
              const meta = CELL_META[seg.level];
              return (
                <div key={i} class="strip-cell-segment" style={{ background: meta.bg, borderColor: meta.color }}>
                  <span style={{ color: meta.color }}>{meta.icon} {meta.label}</span>
                  <span class="strip-cell-range">
                    {shortTime(seg.start)}{seg.end !== seg.start ? `–${shortTime(seg.end)}` : ""}
                  </span>
                  <span class="strip-cell-places">{seg.titles.join(", ")}</span>
                </div>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );
}

function WeatherDetails({ w }: { w: EntryWeather }) {
  const hasDetails = w.wind || w.humidity != null || w.uv != null || w.sunrise || w.sunset || w.note;
  if (!hasDetails) return null;
  return (
    <div class="entry-weather-row">
      {w.wind && (
        <span class="entry-weather-detail">{w.wind.dir} {w.wind.speed} km/h</span>
      )}
      {w.humidity != null && (
        <span class="entry-weather-detail">{w.humidity}%</span>
      )}
      {w.uv != null && (
        <span class="entry-weather-detail entry-weather-uv" data-level={w.uv >= 6 ? "high" : "mod"}>UV {w.uv}</span>
      )}
      {(w.sunrise || w.sunset) && (
        <span class="entry-weather-detail">
          {w.sunrise && <>{"\u2191"}{w.sunrise}</>}
          {w.sunrise && w.sunset && " "}
          {w.sunset && <>{"\u2193"}{w.sunset}</>}
        </span>
      )}
      {w.note && <span class="entry-weather-note">{w.note}</span>}
    </div>
  );
}

function formatTime(iso: string): string {
  const d = new Date(iso);
  if (isNaN(d.getTime())) return "";
  const h = d.getHours();
  const m = d.getMinutes();
  const ampm = h >= 12 ? "PM" : "AM";
  const h12 = h % 12 || 12;
  return `${h12}:${m.toString().padStart(2, "0")} ${ampm}`;
}

function totalEntries(days: ActualDay[]): number {
  return days.reduce((sum, d) => sum + d.entries.length, 0);
}

export function ActualTab({ actuals, tripId }: { actuals: ActualDay[]; tripId: string }) {
  const [days, setDays] = useState<ActualDay[]>(actuals);
  const [noteText, setNoteText] = useState("");
  const saveTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);

  const persist = useCallback((dayIndex: number, entry: ActualEntry) => {
    fetch(`/travel/api/actuals?tripId=${tripId}`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ dayIndex, entry }),
    }).catch(() => {});
  }, [tripId]);

  const addNote = () => {
    const text = noteText.trim();
    if (!text) return;
    const entry: ActualEntry = {
      time: new Date().toISOString().slice(0, 19),
      kind: "note",
      title: text.length > 60 ? text.slice(0, 57) + "..." : text,
      body: text.length > 60 ? text : undefined,
      tags: ["quick-note"],
    };
    const updated = [...days];
    let dayIndex: number;
    if (updated.length === 0) {
      updated.push({ label: "Journal", entries: [entry] });
      dayIndex = 0;
    } else {
      dayIndex = updated.length - 1;
      const last = { ...updated[dayIndex] };
      last.entries = [...last.entries, entry];
      updated[dayIndex] = last;
    }
    setDays(updated);
    setNoteText("");
    persist(dayIndex, entry);
  };

  return (
    <div class="actual-tab">
      <div class="actual-tab-header">
        <div class="itin-section-label">Journal</div>
        <div class="actual-count">{totalEntries(days)} entries</div>
      </div>

      {days.map((day, dayIdx) => (
        <div key={dayIdx} class="actual-day-section">
          <div class="actual-day-header">
            <div class="actual-day-title">{day.label}</div>
            <div class="actual-day-date">{day.entries.length} entries</div>
          </div>
          <DayStrips entries={day.entries} />
          <div class="actual-timeline">
            {day.entries.map((entry, i) => {
              const uid = dayIdx + "-" + i;
              const meta = KIND_META[entry.kind] || KIND_META.note;
              const w = entry.weather;
              const hasWeatherDetails = w && (w.wind || w.humidity != null || w.uv != null || w.sunrise || w.sunset || w.note);
              const hasDetail = entry.body || entry.items?.length || entry.rating || entry.mood || entry.placeName || hasWeatherDetails;
              const cell = entry.cellular ? CELL_META[entry.cellular] : null;
              const showCell = cell && entry.cellular !== "good";
              return (
                <div key={uid} class="actual-entry" style={w ? { borderLeftColor: tempColor(w.temp) } : undefined}>
                  <div class="actual-entry-top">
                    <span class="actual-entry-time">{formatTime(entry.time)}</span>
                    <span class="actual-entry-title">{entry.title}</span>
                    {showCell && (
                      <span class="actual-cell-badge" style={{ color: cell!.color }}>
                        {cell!.icon}
                      </span>
                    )}
                    <span
                      class="actual-kind-badge"
                      style={{ color: meta.color, background: meta.bg }}
                    >
                      {meta.icon} {meta.label}
                    </span>
                  </div>

                  {hasDetail && (
                    <div class="actual-entry-detail">
                      {entry.placeName && (
                        <div class="actual-place-name">{"\uD83D\uDCCD"} {entry.placeName}</div>
                      )}
                      {entry.body && <div class="actual-entry-body">{entry.body}</div>}
                      {entry.items && entry.items.length > 0 && (
                        <div class="actual-items">
                          {(entry.suggestedOrder
                            ? entry.suggestedOrder.map((id: string) => entry.items!.find((i: any) => i.id === id)).filter(Boolean)
                            : entry.items
                          ).map((item: any, idx: number) =>
                            typeof item === "string" ? (
                              <span key={item} class="actual-item-chip">{item}</span>
                            ) : (
                              <div key={item.id || idx} class="actual-structured-item">
                                <div class="actual-item-header">
                                  <strong>{item.name}</strong>
                                  {item.duration && <span class="actual-item-duration">{item.duration}</span>}
                                  {item.free && <span class="actual-item-free">free</span>}
                                </div>
                                {item.where && <div class="actual-item-where">{item.where}</div>}
                                {item.note && <div class="actual-item-note">{item.note}</div>}
                              </div>
                            )
                          )}
                        </div>
                      )}
                      {entry.rating != null && (
                        <div class="actual-rating">{entry.rating}/10</div>
                      )}
                      {entry.mood && (
                        <div class="actual-mood">{entry.mood}</div>
                      )}
                      {w && <WeatherDetails w={w} />}
                      {entry.tags && entry.tags.length > 0 && (
                        <div class="place-tags">
                          {entry.tags.map(t => (
                            <span key={t} class="place-tag">{t}</span>
                          ))}
                        </div>
                      )}
                    </div>
                  )}
                </div>
              );
            })}
          </div>
        </div>
      ))}

      {totalEntries(days) === 0 && (
        <div class="empty-state">No journal entries yet.</div>
      )}

      <div class="actual-quick-note">
        <div class="actual-quick-label">Quick Note</div>
        <textarea
          class="actual-quick-input"
          placeholder="Jot something down..."
          value={noteText}
          onInput={(e) => setNoteText((e.target as HTMLTextAreaElement).value)}
          onKeyDown={(e) => {
            if (e.key === "Enter" && !e.shiftKey) {
              e.preventDefault();
              addNote();
            }
          }}
        />
        <button
          class="actual-quick-submit"
          onClick={addNote}
          disabled={!noteText.trim()}
        >
          Add Note
        </button>
      </div>
    </div>
  );
}
