import { useState } from 'react';
import { useCalendar, useCalendarDate } from '../hooks/useCalendar';
import { useQuery } from '@tanstack/react-query';
import { api } from '../api';
import MoonPhaseIcon from '../components/sky/MoonPhaseIcon';
import { format, startOfMonth, endOfMonth, eachDayOfInterval } from 'date-fns';

const FILTER_LABELS: Record<string, string> = {
  sv220: 'HaOIII', c2: 'SII/OIII', sv260: 'LP', uvir: 'UV/IR',
};

function fmtTime(utc?: string): string {
  if (!utc) return '—';
  return new Date(utc).toLocaleTimeString('fr-FR', {
    hour: '2-digit', minute: '2-digit', timeZone: 'Europe/Paris',
  });
}

type CalDay = {
  date: string;
  moon_illumination?: number;
  max_usable_min?: number;
  avg_max_alt?: number;
};

/** 12-month horizontal lunar cycle timeline */
function NewMoonTimeline({ days }: { days: CalDay[] }) {
  const { data: nmData } = useQuery({
    queryKey: ['new-moon-windows'],
    queryFn: () => api.calendar.getNewMoonWindows(),
    staleTime: 24 * 60 * 60_000,
  });

  // Build a map of new moon date → top targets
  const nmTargetMap = new Map<string, { id: string; name: string; common_name?: string; max_alt_deg?: number; recommended_filter?: string }[]>();
  for (const w of nmData?.windows ?? []) {
    nmTargetMap.set(w.date, w.top_targets);
  }

  if (days.length === 0) {
    return <div style={{ color: 'var(--text-lo)', fontFamily: 'var(--font-mono)', fontSize: 12 }}>Loading…</div>;
  }

  // Chunk into lunar cycles: whenever illumination crosses a local minimum (new moon ≈ < 5%)
  // For display, just show month-by-month rows with a continuous illumination bar.
  const today = format(new Date(), 'yyyy-MM-dd');

  // Group days into months
  const monthMap = new Map<string, CalDay[]>();
  for (const d of days) {
    const month = d.date.slice(0, 7); // "2026-04"
    if (!monthMap.has(month)) monthMap.set(month, []);
    monthMap.get(month)!.push(d);
  }

  return (
    <div>
      <div style={{ display: 'flex', gap: 8, alignItems: 'center', marginBottom: 16 }}>
        <div style={{ display: 'flex', gap: 12, fontSize: 10, fontFamily: 'var(--font-mono)', color: 'var(--text-lo)' }}>
          <span><span style={{ display: 'inline-block', width: 12, height: 8, background: 'rgba(61,186,114,0.35)', borderRadius: 2, marginRight: 4 }} />{'< 20% moon — prime narrowband'}</span>
          <span><span style={{ display: 'inline-block', width: 12, height: 8, background: 'rgba(232,131,42,0.3)', borderRadius: 2, marginRight: 4 }} />{'20–50% — broadband OK'}</span>
          <span><span style={{ display: 'inline-block', width: 12, height: 8, background: 'rgba(224,82,82,0.25)', borderRadius: 2, marginRight: 4 }} />{'> 50% — challenging'}</span>
        </div>
      </div>

      {Array.from(monthMap.entries()).map(([month, mDays]) => {
        // Find new moon dates in this month (local illumination minimum, < 5%)
        const newMoonDates = mDays.filter((d, i) => {
          const illum = d.moon_illumination ?? 0.5;
          const prev = mDays[i - 1]?.moon_illumination ?? illum;
          const next = mDays[i + 1]?.moon_illumination ?? illum;
          return illum < 0.05 && illum <= prev && illum <= next;
        });

        // Days in this month ordered
        const sorted = [...mDays].sort((a, b) => a.date.localeCompare(b.date));
        const daysInMonth = sorted.length;

        return (
          <div key={month} style={{ marginBottom: 12 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
              <span style={{
                fontFamily: 'var(--font-mono)',
                fontSize: 11,
                color: 'var(--text-mid)',
                width: 80,
                flexShrink: 0,
              }}>
                {format(new Date(month + '-01'), 'MMM yyyy')}
              </span>

              {/* Moon illumination bar */}
              <div style={{ flex: 1, position: 'relative', height: 28, display: 'flex' }}>
                {sorted.map(d => {
                  const illum = d.moon_illumination ?? 0;
                  const isToday = d.date === today;
                  const isNewMoon = newMoonDates.some(nm => nm.date === d.date);
                  let bg: string;
                  if (illum < 0.2) bg = 'rgba(61,186,114,0.35)';
                  else if (illum < 0.5) bg = 'rgba(232,131,42,0.30)';
                  else bg = 'rgba(224,82,82,0.25)';

                  return (
                    <div key={d.date} title={`${d.date} — ${Math.round(illum * 100)}%`}
                      style={{
                        flex: 1,
                        background: bg,
                        borderLeft: isToday ? '2px solid var(--amber)' : '1px solid transparent',
                        position: 'relative',
                        display: 'flex',
                        alignItems: 'center',
                        justifyContent: 'center',
                      }}>
                      {/* New moon marker */}
                      {isNewMoon && (
                        <div style={{
                          width: 4, height: 4,
                          borderRadius: '50%',
                          background: 'var(--text-hi)',
                          position: 'absolute',
                          top: 2,
                        }} />
                      )}
                      {/* Full moon marker */}
                      {illum > 0.95 && (
                        <div style={{
                          width: 4, height: 4,
                          borderRadius: '50%',
                          background: 'rgba(255,255,255,0.5)',
                          border: '1px solid rgba(255,255,255,0.7)',
                          position: 'absolute',
                          top: 2,
                        }} />
                      )}
                      {/* Illumination curve as height */}
                      <div style={{
                        position: 'absolute',
                        bottom: 0, left: 0, right: 0,
                        height: `${illum * 100}%`,
                        background: 'rgba(255,255,255,0.08)',
                      }} />
                    </div>
                  );
                })}

                {/* Day count axis: show 1, 8, 15, 22, 28 */}
                {sorted.filter((_, i) => [0, 7, 14, 21, 27].includes(i)).map(d => {
                  const idx = sorted.indexOf(d);
                  const pct = (idx / daysInMonth) * 100;
                  return (
                    <div key={`lbl-${d.date}`} style={{
                      position: 'absolute',
                      left: `${pct}%`,
                      bottom: -13,
                      fontFamily: 'var(--font-mono)',
                      fontSize: 8,
                      color: 'var(--text-lo)',
                      transform: 'translateX(-50%)',
                    }}>
                      {parseInt(d.date.slice(8))}
                    </div>
                  );
                })}
              </div>

              {/* New moon windows: date + top 3 emission targets */}
              <div style={{ width: 200, flexShrink: 0 }}>
                {newMoonDates.map(d => {
                  const targets = nmTargetMap.get(d.date) ?? [];
                  return (
                    <div key={d.date} style={{ marginBottom: 4 }}>
                      <div style={{ fontFamily: 'var(--font-mono)', fontSize: 9, color: 'var(--amber)', marginBottom: 2 }}>
                        ● {d.date.slice(5)}
                      </div>
                      {targets.map(t => (
                        <div key={t.id} style={{ fontFamily: 'var(--font-mono)', fontSize: 9, color: 'var(--text-lo)', paddingLeft: 8 }}>
                          {t.common_name ?? t.name}
                          {t.max_alt_deg != null && (
                            <span style={{ color: 'var(--text-lo)', marginLeft: 4 }}>{t.max_alt_deg.toFixed(0)}°</span>
                          )}
                        </div>
                      ))}
                    </div>
                  );
                })}
              </div>
            </div>
          </div>
        );
      })}

      <div style={{ marginTop: 12, fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--text-lo)' }}>
        ● = new moon &nbsp;·&nbsp; vertical line = today &nbsp;·&nbsp; hover a day for date + illumination %
      </div>
    </div>
  );
}

export default function Calendar() {
  const [selectedDate, setSelectedDate] = useState<string | null>(null);
  const [newMoonView, setNewMoonView] = useState(false);
  const { data: calData3 } = useCalendar(3);
  const { data: calData12 } = useCalendar(12);
  const { data: dateData } = useCalendarDate(selectedDate ?? '');

  const calData = newMoonView ? calData12 : calData3;

  const today = new Date();

  const dayMap = new Map<string, CalDay>(
    (calData?.days ?? []).map(d => [d.date, d])
  );

  const months = [today, new Date(today.getFullYear(), today.getMonth() + 1), new Date(today.getFullYear(), today.getMonth() + 2)];

  return (
    <div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 14, marginBottom: 20 }}>
        <h1 style={{ fontFamily: 'var(--font-display)', fontSize: 22 }}>Calendar</h1>
        <button
          onClick={() => { setNewMoonView(v => !v); setSelectedDate(null); }}
          style={{
            padding: '4px 12px',
            borderRadius: 10,
            border: `1px solid ${newMoonView ? 'var(--amber)' : 'var(--border)'}`,
            background: newMoonView ? 'var(--amber-glow)' : 'var(--bg-panel)',
            color: newMoonView ? 'var(--amber)' : 'var(--text-mid)',
            fontFamily: 'var(--font-mono)',
            fontSize: 11,
            cursor: 'pointer',
          }}
        >
          ● New Moon View
        </button>
      </div>

      {newMoonView ? (
        <NewMoonTimeline days={calData12?.days ?? []} />
      ) : (
        <div style={{ display: 'grid', gridTemplateColumns: selectedDate ? '2fr 1fr' : '1fr', gap: 20 }}>
          <div>
            {months.map(month => {
              const monthStart = startOfMonth(month);
              const monthEnd = endOfMonth(month);
              const days = eachDayOfInterval({ start: monthStart, end: monthEnd });
              const firstDow = monthStart.getDay();

              return (
                <div key={month.toISOString()} style={{ marginBottom: 28 }}>
                  <div style={{ fontFamily: 'var(--font-display)', fontSize: 16, fontWeight: 700, marginBottom: 10, color: 'var(--text-hi)' }}>
                    {format(month, 'MMMM yyyy')}
                  </div>
                  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 3 }}>
                    {['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'].map(d => (
                      <div key={d} style={{ textAlign: 'center', fontFamily: 'var(--font-mono)', fontSize: 9, color: 'var(--text-lo)', paddingBottom: 4 }}>
                        {d}
                      </div>
                    ))}
                    {Array.from({ length: (firstDow + 6) % 7 }).map((_, i) => (
                      <div key={`e${i}`} />
                    ))}
                    {days.map(day => {
                      const dateStr = format(day, 'yyyy-MM-dd');
                      const info = dayMap.get(dateStr);
                      const usable = info?.max_usable_min ?? 0;
                      const moonIllum = info?.moon_illumination;
                      const isSelected = selectedDate === dateStr;
                      const isToday = dateStr === format(today, 'yyyy-MM-dd');
                      const isNarrowbandNight = moonIllum != null && moonIllum < 0.2;

                      let bg = 'var(--bg-panel)';
                      if (usable > 240) bg = 'rgba(42,184,160,0.2)';
                      else if (usable > 60) bg = 'rgba(232,131,42,0.15)';

                      return (
                        <div
                          key={dateStr}
                          onClick={() => setSelectedDate(isSelected ? null : dateStr)}
                          style={{
                            background: isSelected ? 'var(--amber-glow)' : bg,
                            border: `1px solid ${isSelected ? 'var(--amber)' : isNarrowbandNight ? 'var(--amber)' : isToday ? 'var(--text-lo)' : 'var(--border)'}`,
                            borderRadius: 3,
                            padding: '4px',
                            cursor: 'pointer',
                            minHeight: 56,
                            position: 'relative',
                          }}
                        >
                          <div style={{
                            fontFamily: 'var(--font-mono)',
                            fontSize: 11,
                            color: isToday ? 'var(--amber)' : 'var(--text-mid)',
                            marginBottom: 2,
                            fontWeight: isToday ? 700 : 400,
                            display: 'flex',
                            alignItems: 'center',
                            justifyContent: 'space-between',
                          }}>
                            <span>{format(day, 'd')}</span>
                            {moonIllum != null && (
                              <MoonPhaseIcon illumination={moonIllum} size={12} />
                            )}
                          </div>
                          {usable > 0 && (
                            <div style={{
                              height: 3,
                              background: usable > 240 ? 'var(--teal)' : 'var(--amber)',
                              borderRadius: 2,
                              width: `${Math.min(100, (usable / 480) * 100)}%`,
                              marginBottom: 2,
                            }} />
                          )}
                          {moonIllum != null && (
                            <div style={{
                              fontFamily: 'var(--font-mono)',
                              fontSize: 9,
                              color: isNarrowbandNight ? 'var(--amber)' : 'var(--text-lo)',
                            }}>
                              {Math.round(moonIllum * 100)}%
                            </div>
                          )}
                        </div>
                      );
                    })}
                  </div>
                </div>
              );
            })}
          </div>

          {/* Side panel for selected date */}
          {selectedDate && (
            <div style={{ background: 'var(--bg-panel)', border: '1px solid var(--border)', borderRadius: 6, padding: 16, height: 'fit-content', position: 'sticky', top: 8 }}>
              <div style={{ fontFamily: 'var(--font-display)', fontSize: 16, fontWeight: 700, marginBottom: 12 }}>
                {selectedDate}
              </div>

              {/* Moon + dark window */}
              {(() => {
                const illum = dateData?.moon_illumination ?? dayMap.get(selectedDate)?.moon_illumination;
                const info = dayMap.get(selectedDate);
                return illum != null ? (
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>
                    <MoonPhaseIcon illumination={illum} size={28} />
                    <div>
                      <div style={{ fontFamily: 'var(--font-mono)', fontSize: 13, color: 'var(--text-hi)', fontWeight: 700 }}>
                        {Math.round(illum * 100)}%
                      </div>
                      {illum < 0.2 && (
                        <div style={{ fontSize: 10, color: 'var(--amber)', fontFamily: 'var(--font-mono)' }}>
                          ★ Prime narrowband night
                        </div>
                      )}
                    </div>
                    {info?.max_usable_min ? (
                      <div style={{ marginLeft: 'auto', fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--teal)' }}>
                        {Math.floor(info.max_usable_min / 60)}h {info.max_usable_min % 60}m dark
                      </div>
                    ) : null}
                  </div>
                ) : null;
              })()}

              {/* Tonight summary */}
              {dateData?.tonight && (
                <div style={{ background: 'var(--bg-deep)', border: '1px solid var(--border)', borderRadius: 4, padding: '8px 10px', marginBottom: 10 }}>
                  <table style={{ borderCollapse: 'collapse', width: '100%' }}>
                    <tbody>
                      {[
                        ['Dusk', dateData.tonight.astro_dusk_utc ? fmtTime(dateData.tonight.astro_dusk_utc) : '—'],
                        ['Dawn', dateData.tonight.astro_dawn_utc ? fmtTime(dateData.tonight.astro_dawn_utc) : '—'],
                        ['True dark', dateData.tonight.true_dark_start_utc && dateData.tonight.true_dark_end_utc
                          ? `${fmtTime(dateData.tonight.true_dark_start_utc)} – ${fmtTime(dateData.tonight.true_dark_end_utc)}`
                          : '—'],
                        ['Moon', dateData.tonight.moon_phase_name ?? '—'],
                      ].map(([label, val]) => (
                        <tr key={label}>
                          <td style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--text-lo)', paddingBottom: 3, width: 70 }}>{label}</td>
                          <td style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text-hi)' }}>{val}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              )}

              {/* Weather */}
              {dateData?.weather && (
                <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 10, padding: '6px 10px', background: 'var(--bg-deep)', border: '1px solid var(--border)', borderRadius: 4 }}>
                  {dateData.weather.go_nogo && (
                    <span style={{
                      fontFamily: 'var(--font-mono)',
                      fontSize: 11,
                      fontWeight: 700,
                      color: dateData.weather.go_nogo === 'go' ? 'var(--good)' : dateData.weather.go_nogo === 'marginal' ? 'var(--warn)' : 'var(--danger)',
                    }}>
                      {dateData.weather.go_nogo.toUpperCase()}
                    </span>
                  )}
                  {dateData.weather.temp_c != null && (
                    <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--text-mid)' }}>
                      {dateData.weather.temp_c.toFixed(0)}°C
                    </span>
                  )}
                  {dateData.weather.cloudcover != null && (
                    <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--text-lo)' }}>
                      Cloud {dateData.weather.cloudcover}/9
                    </span>
                  )}
                  {dateData.weather.seeing != null && (
                    <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--text-lo)' }}>
                      Seeing {dateData.weather.seeing}/8
                    </span>
                  )}
                </div>
              )}

              <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text-lo)', marginBottom: 8, letterSpacing: '0.06em', textTransform: 'uppercase' }}>
                Top Targets
              </div>
              {!dateData && (
                <div style={{ color: 'var(--text-lo)', fontSize: 12 }}>No precomputed data for this date.</div>
              )}
              {dateData?.top_targets?.length === 0 && (
                <div style={{ color: 'var(--text-lo)', fontSize: 12 }}>No visible targets.</div>
              )}
              {dateData?.top_targets?.map((t, i) => (
                <div key={t.id} style={{
                  display: 'flex',
                  gap: 8,
                  alignItems: 'center',
                  padding: '5px 0',
                  borderBottom: '1px solid var(--border)',
                }}>
                  <span style={{ color: 'var(--text-lo)', fontFamily: 'var(--font-mono)', fontSize: 10, width: 16 }}>{i + 1}</span>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text-hi)' }}>
                      {t.common_name ?? t.name}
                    </div>
                    <div style={{ fontSize: 10, color: 'var(--text-lo)' }}>{t.name}</div>
                  </div>
                  {t.recommended_filter && (
                    <span className={`filter-pill ${t.recommended_filter}`} style={{ fontSize: 9 }}>
                      {FILTER_LABELS[t.recommended_filter] ?? ''}
                    </span>
                  )}
                  <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--good)' }}>
                    {t.max_alt_deg?.toFixed(0)}°
                  </span>
                </div>
              ))}
            </div>
          )}
        </div>
      )}
    </div>
  );
}
