import React, { useState, useEffect } from 'react';
import './custom-toolbar.css';
import { Button } from '@/components/ui/button';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import { NavigateAction } from 'react-big-calendar';

interface CustomToolbarProps {
  //Aktuell angezeigtes Datum
  date: Date;
  //Aktuelle Ansicht
  view: 'month' | 'week' | 'day' | 'agenda' | 'work_week';

  onNavigate: (action: NavigateAction, newDate?: Date) => void;
  //Ansichtwechsel
  onView: (newView: 'month' | 'week' | 'day' | 'agenda' | 'work_week') => void;
}

const CustomToolbar: React.FC<CustomToolbarProps> = ({
  date,
  view,
  onNavigate,
  onView,
}) => {
  //ISO-Wochennummer eines Datums ermitteln
  const getISOWeek = (date: Date): number => {
    const tmp = new Date(date.getTime());
    //Datum so verschieben, dass der nächste Donnerstag erreicht wird (ISO: Woche beginnt am Montag)
    tmp.setDate(tmp.getDate() + 4 - (tmp.getDay() || 7));
    const yearStart = new Date(tmp.getFullYear(), 0, 1);
    const weekNo = Math.ceil(
      ((tmp.getTime() - yearStart.getTime()) / 86400000 + 1) / 7,
    );
    return weekNo;
  };

  //ISO-Wochenjahr eines Datums ermitteln
  const getISOWeekYear = (date: Date): number => {
    const tmp = new Date(date.getTime());
    tmp.setDate(tmp.getDate() + 4 - (tmp.getDay() || 7));
    return tmp.getFullYear();
  };

  //Ermittlung der Anzahl der Wochen im Jahr
  const getISOWeeksInYear = (year: number): number => {
    const d = new Date(year, 11, 31);
    const week = getISOWeek(d);
    return week === 1 ? getISOWeek(new Date(year, 11, 24)) : week;
  };

  const getDateOfISOWeek = (week: number, year: number): Date => {
    const jan1 = new Date(year, 0, 1);
    const dayOfWeek = jan1.getDay();
    const isoDayOfWeek = dayOfWeek === 0 ? 7 : dayOfWeek;
    let firstMonday: Date;
    if (isoDayOfWeek <= 4) {
      //1. Januar gehört zur ersten ISO-Woche (Montag dieser Woche bestimmen)
      firstMonday = new Date(year, 0, 1 - isoDayOfWeek + 1);
    } else {
      //Ansonsten liegt der erste Montag in der darauffolgenden Woche
      firstMonday = new Date(year, 0, 1 + (8 - isoDayOfWeek));
    }
    firstMonday.setDate(firstMonday.getDate() + (week - 1) * 7);
    return firstMonday;
  };

  //Lokaler State für Woche und ISO-Wochenjahr (statt des reinen Kalenderjahrs)
  const [selectedWeek, setSelectedWeek] = useState<number>(getISOWeek(date));
  const [selectedYear, setSelectedYear] = useState<number>(
    getISOWeekYear(date),
  );

  //Auswahl aktualisieren, wenn sich die Prop "date" ändert
  useEffect(() => {
    setSelectedWeek(getISOWeek(date));
    setSelectedYear(getISOWeekYear(date));
  }, [date]);

  //Start (Montag) und Ende (Sonntag) der aktuell angezeigten Woche berechnen
  const weekStartDate = getDateOfISOWeek(selectedWeek, selectedYear);
  const weekEndDate = new Date(weekStartDate);
  weekEndDate.setDate(weekStartDate.getDate() + 6);

  //Ansichtwechsel
  const handleViewChange = (newView: 'month' | 'week' | 'day' | 'agenda') => {
    onView(newView);
  };

  //Today-Button aktualisiert das Datum im DatePicker auf das heutige
  const handleToday = () => {
    const today = new Date();
    setSelectedDate(today);
    setSelectedWeek(getISOWeek(today));
    setSelectedYear(getISOWeekYear(today));
    onNavigate('TODAY', today);
  };

  //Pfeiltaste nach Vorne
  const handleNext = () => {
    let newDate: Date;
    if (view === 'day' || view === 'agenda') {
      newDate = new Date(date);
      newDate.setDate(newDate.getDate() + 1);
    } else if (view === 'week') {
      let newWeek = selectedWeek + 1;
      let newYear = selectedYear;
      if (newWeek > getISOWeeksInYear(selectedYear)) {
        newYear = selectedYear + 1;
        newWeek = 1;
      }
      setSelectedWeek(newWeek);
      setSelectedYear(newYear);
      newDate = getDateOfISOWeek(newWeek, newYear);
    } else if (view === 'month') {
      newDate = new Date(date.getFullYear(), date.getMonth() + 1, 1);
    } else {
      newDate = new Date(date);
    }
    //Datum im DatePicker aktualisieren
    setSelectedDate(newDate);
    onNavigate('DATE', newDate);
  };

  //Pfeiltaste nach Hinten
  const handlePrev = () => {
    let newDate: Date;
    if (view === 'day' || view === 'agenda') {
      newDate = new Date(date);
      newDate.setDate(newDate.getDate() - 1);
    } else if (view === 'week') {
      let newWeek = selectedWeek - 1;
      let newYear = selectedYear;
      if (newWeek < 1) {
        newYear = selectedYear - 1;
        newWeek = getISOWeeksInYear(newYear);
      }
      setSelectedWeek(newWeek);
      setSelectedYear(newYear);
      newDate = getDateOfISOWeek(newWeek, newYear);
    } else if (view === 'month') {
      newDate = new Date(date.getFullYear(), date.getMonth() - 1, 1);
    } else {
      newDate = new Date(date);
    }
    //Datum im DatePicker aktualisieren
    setSelectedDate(newDate);
    onNavigate('DATE', newDate);
  };

  const [selectedDate, setSelectedDate] = useState<Date | null>(new Date());

  const handleDateChange = (date: Date | null) => {
    setSelectedDate(date);
    if (date) {
      if (view === 'week') {
        const newWeek = getISOWeek(date);
        const newYear = getISOWeekYear(date);
        setSelectedWeek(newWeek);
        setSelectedYear(newYear);
        const newDate = getDateOfISOWeek(newWeek, newYear);
        onNavigate('DATE', newDate);
      } else if (view === 'day') {
        onNavigate('DATE', date);
      } else if (view === 'month') {
        const newDate = new Date(date.getFullYear(), date.getMonth(), 1);
        onNavigate('DATE', newDate);
      } else if (view === 'agenda') {
        onNavigate('DATE', date);
      }
    }
  };

  return (
    <div
      className='custom-toolbar'
      style={{ display: 'flex', flexDirection: 'initial', gap: '8px' }}
    >
      <div className='view-change'>
        <div className='view-switcher' style={{ display: 'flex', gap: '8px' }}>
          <Button
            //className='hover:bg-orange-600 hover:text-white'
            type='submit'
            variant='primary'
            onClick={() => handleViewChange('month')}
            size={'default'}
          >
            Month
          </Button>
          <Button
            //className='hover:bg-orange-600 hover:text-white'
            type='submit'
            variant='primary'
            onClick={() => handleViewChange('week')}
            size={'default'}
          >
            Week
          </Button>
          <Button
            //className='hover:bg-orange-600 hover:text-white'
            type='submit'
            variant='primary'
            onClick={() => handleViewChange('day')}
            size={'default'}
          >
            Day
          </Button>
          <Button
            //className='hover:bg-orange-600 hover:text-white'
            type='submit'
            variant='primary'
            onClick={() => handleViewChange('agenda')}
            size={'default'}
          >
            Agenda
          </Button>
        </div>
      </div>

      <div
        className='right-section'
        style={{ display: 'flex', flexDirection: 'initial', gap: '8px' }}
      >
        <div
          className='navigation-controls'
          style={{ display: 'flex', gap: '8px' }}
        >
          <div className='handleWeek'>
            <button onClick={handlePrev}>&lt;</button>
            <button onClick={handleNext}>&gt;</button>
          </div>
          <div className='today'>
            <Button
              //className='hover:bg-orange-600 hover:text-white'
              type='submit'
              variant='secondary'
              onClick={() => handleToday()}
              size={'default'}
            >
              Today
            </Button>
          </div>
        </div>

        <div className='datepicker-box'>
          <DatePicker
            className='datepicker'
            selected={selectedDate}
            onChange={handleDateChange}
            calendarStartDay={1}
            locale='de-DE'
            dateFormat='dd.MM.yyyy'
            showWeekNumbers={true}
          />
        </div>
      </div>
    </div>
  );
};

export default CustomToolbar;
