'use client';

import { useState, useEffect, useCallback } from 'react';
import { Verfuegbarkeit } from '@/types';

interface BookingCalendarProps {
  onDateSelect: (date: string | null) => void;
  selectedDate: string | null;
}

const WEEKDAYS = ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'];
const MONTH_NAMES = [
  'Jänner', 'Februar', 'März', 'April', 'Mai', 'Juni',
  'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember',
];

function getSaisonRange(year: number) {
  return {
    start: new Date(year, 2, 15),
    end: new Date(year, 5, 30),
  };
}

function formatDate(d: Date): string {
  return d.toISOString().split('T')[0];
}

export default function BookingCalendar({ onDateSelect, selectedDate }: BookingCalendarProps) {
  const today = new Date();
  const currentYear = today.getFullYear();
  const saison = getSaisonRange(currentYear);

  const initialMonth = today > saison.start ? today.getMonth() : saison.start.getMonth();
  const [viewMonth, setViewMonth] = useState(initialMonth);
  const [viewYear] = useState(currentYear);
  const [auslastung, setAuslastung] = useState<Record<string, number>>({});
  const [maxPerDay, setMaxPerDay] = useState(5);
  const [loading, setLoading] = useState(true);

  const loadVerfuegbarkeit = useCallback(async () => {
    try {
      const res = await fetch(`/api/pool/verfuegbarkeit?year=${currentYear}`);
      const data = await res.json();
      if (data.verfuegbarkeit) {
        const map: Record<string, number> = {};
        data.verfuegbarkeit.forEach((v: Verfuegbarkeit) => {
          map[v.datum] = v.anzahl_buchungen;
        });
        setAuslastung(map);
      }
      if (data.max_per_day) {
        setMaxPerDay(data.max_per_day);
      }
    } catch {
      // silent
    } finally {
      setLoading(false);
    }
  }, [currentYear]);

  useEffect(() => {
    loadVerfuegbarkeit();
  }, [loadVerfuegbarkeit]);

  const firstDayOfMonth = new Date(viewYear, viewMonth, 1);
  let startDow = firstDayOfMonth.getDay() - 1;
  if (startDow < 0) startDow = 6;

  const daysInMonth = new Date(viewYear, viewMonth + 1, 0).getDate();

  const days: (Date | null)[] = [];
  for (let i = 0; i < startDow; i++) days.push(null);
  for (let d = 1; d <= daysInMonth; d++) {
    days.push(new Date(viewYear, viewMonth, d));
  }

  const canGoBack = viewMonth > saison.start.getMonth();
  const canGoForward = viewMonth < saison.end.getMonth();

  // Count available days this month
  let availableDays = 0;
  for (let d = 1; d <= daysInMonth; d++) {
    const day = new Date(viewYear, viewMonth, d);
    const tomorrow = new Date(today);
    tomorrow.setDate(tomorrow.getDate() + 1);
    tomorrow.setHours(0, 0, 0, 0);
    if (day >= saison.start && day <= saison.end && day >= tomorrow) {
      const dateStr = formatDate(day);
      const count = auslastung[dateStr] || 0;
      if (count < maxPerDay) availableDays++;
    }
  }

  function getDayStatus(day: Date): 'disabled' | 'full' | 'available' | 'partial' {
    if (day < saison.start || day > saison.end) return 'disabled';
    const tomorrow = new Date(today);
    tomorrow.setDate(tomorrow.getDate() + 1);
    tomorrow.setHours(0, 0, 0, 0);
    if (day < tomorrow) return 'disabled';

    const dateStr = formatDate(day);
    const count = auslastung[dateStr] || 0;
    if (count >= maxPerDay) return 'full';
    if (count >= maxPerDay - 2) return 'partial';
    return 'available';
  }

  return (
    <div className="bg-white rounded-2xl border border-border overflow-hidden">
      {/* Sticky availability header */}
      {!loading && (
        <div className="px-4 py-2.5 bg-bg border-b border-border/50">
          <p className="text-xs text-text-muted text-center">
            <span className="font-semibold text-success">{availableDays}</span> {availableDays === 1 ? 'Tag' : 'Tage'} verfügbar im {MONTH_NAMES[viewMonth]}
          </p>
        </div>
      )}

      <div className="p-4">
        {/* Month navigation */}
        <div className="flex items-center justify-between mb-4">
          <button
            onClick={() => canGoBack && setViewMonth(viewMonth - 1)}
            disabled={!canGoBack}
            className="w-10 h-10 rounded-xl flex items-center justify-center hover:bg-bg disabled:opacity-20 disabled:cursor-not-allowed transition-colors"
            aria-label="Vorheriger Monat"
          >
            <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
            </svg>
          </button>
          <h3 className="font-bold text-primary text-base">
            {MONTH_NAMES[viewMonth]} {viewYear}
          </h3>
          <button
            onClick={() => canGoForward && setViewMonth(viewMonth + 1)}
            disabled={!canGoForward}
            className="w-10 h-10 rounded-xl flex items-center justify-center hover:bg-bg disabled:opacity-20 disabled:cursor-not-allowed transition-colors"
            aria-label="Nächster Monat"
          >
            <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
            </svg>
          </button>
        </div>

        {/* Weekday headers */}
        <div className="grid grid-cols-7 gap-1 mb-1">
          {WEEKDAYS.map((d) => (
            <div key={d} className="text-center text-[11px] font-semibold text-text-muted/60 py-1 uppercase">
              {d}
            </div>
          ))}
        </div>

        {/* Days grid */}
        {loading ? (
          <div className="grid grid-cols-7 gap-1">
            {Array.from({ length: 35 }).map((_, i) => (
              <div key={i} className="skeleton w-11 h-11 mx-auto" />
            ))}
          </div>
        ) : (
          <div className="grid grid-cols-7 gap-1">
            {days.map((day, i) => {
              if (!day) return <div key={`empty-${i}`} className="w-11 h-11" />;

              const status = getDayStatus(day);
              const dateStr = formatDate(day);
              const isSelected = selectedDate === dateStr;
              const count = auslastung[dateStr] || 0;
              const freeSlots = maxPerDay - count;

              return (
                <button
                  key={dateStr}
                  onClick={() => {
                    if (status === 'disabled' || status === 'full') return;
                    onDateSelect(isSelected ? null : dateStr);
                  }}
                  disabled={status === 'disabled' || status === 'full'}
                  className={`cal-day relative ${isSelected ? 'cal-selected' : ''} ${status === 'full' ? 'cal-full' : ''} ${status === 'disabled' ? 'cal-disabled' : ''} ${status === 'available' && !isSelected ? 'cal-available' : ''} ${status === 'partial' && !isSelected ? 'cal-partial' : ''}`}
                  aria-label={`${day.getDate()}. ${MONTH_NAMES[viewMonth]}, ${status === 'full' ? 'ausgebucht' : freeSlots + ' Plätze frei'}`}
                >
                  {day.getDate()}
                  {/* Small dot indicator for partial */}
                  {status === 'partial' && !isSelected && (
                    <span className="absolute bottom-1 left-1/2 -translate-x-1/2 w-1 h-1 rounded-full bg-warning" />
                  )}
                </button>
              );
            })}
          </div>
        )}

        {/* Legend */}
        <div className="flex items-center justify-center gap-5 mt-4 pt-3 border-t border-border/50 text-[11px] text-text-muted">
          <div className="flex items-center gap-1.5">
            <span className="w-2.5 h-2.5 rounded-sm bg-success/20 border border-success/30" />
            Frei
          </div>
          <div className="flex items-center gap-1.5">
            <span className="w-2.5 h-2.5 rounded-sm bg-warning/20 border border-warning/30" />
            Fast voll
          </div>
          <div className="flex items-center gap-1.5">
            <span className="w-2.5 h-2.5 rounded-sm bg-danger/15 border border-danger/20" />
            Voll
          </div>
        </div>
      </div>
    </div>
  );
}
