/**
 * RangeView - agenda-style list of entries between a start and end date.
 *
 * Groups entries by day, showing day headers with date + weekday.
 * Click an entry -> fires onEditEntry(entry).
 */

import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import clsx from 'clsx';
import type { CalendarEntry } from '@/api/calendar';

export interface RangeViewProps {
  rangeStart: Date;
  rangeEnd: Date;
  entries: CalendarEntry[];
  loading?: boolean;
  onEditEntry: (entry: CalendarEntry) => void;
}

function startOfDay(d: Date): Date {
  return new Date(d.getFullYear(), d.getMonth(), d.getDate());
}

function addDays(d: Date, n: number): Date {
  const out = new Date(d);
  out.setDate(out.getDate() + n);
  return out;
}

function sameDay(a: Date, b: Date): boolean {
  return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
}

function fmtTime(d: Date): string {
  const pad = (n: number) => String(n).padStart(2, '0');
  return pad(d.getHours()) + ':' + pad(d.getMinutes());
}

function fmtDayDate(d: Date): string {
  const pad = (n: number) => String(n).padStart(2, '0');
  return pad(d.getDate()) + '.' + pad(d.getMonth() + 1) + '.' + d.getFullYear();
}

export function RangeView({
  rangeStart,
  rangeEnd,
  entries,
  loading,
  onEditEntry,
}: RangeViewProps) {
  const { t } = useTranslation();

  const today = startOfDay(new Date());
  const weekdays = t('calendar.weekdays', { returnObjects: true }) as string[];

  const days = useMemo(() => {
    if (!rangeStart || !rangeEnd) return [];
    const start = startOfDay(rangeStart);
    const end = startOfDay(rangeEnd);
    if (end < start) return [start];
    const result: Date[] = [];
    let cur = start;
    while (cur <= end) {
      result.push(cur);
      cur = addDays(cur, 1);
    }
    return result;
  }, [rangeStart, rangeEnd]);

  const entriesByDay = useMemo(() => {
    const map = new Map<string, CalendarEntry[]>();
    for (const entry of entries) {
      if (!entry.start_at) continue;
      const d = new Date(entry.start_at);
      const key = d.getFullYear() + '-' + d.getMonth() + '-' + d.getDate();
      const list = map.get(key) ?? [];
      list.push(entry);
      map.set(key, list);
    }
    for (const list of map.values()) {
      list.sort((a, b) => {
        const at = a.start_at ? new Date(a.start_at).getTime() : 0;
        const bt = b.start_at ? new Date(b.start_at).getTime() : 0;
        return at - bt;
      });
    }
    return map;
  }, [entries]);

  if (loading) {
    return (
      <div className="flex items-center justify-center h-full p-6" data-testid="range-view-loading">
        <div className="text-sm text-secondary-500">{t('common.loading')}</div>
      </div>
    );
  }

  if (days.length === 0) {
    return (
      <div className="flex items-center justify-center h-full p-6" data-testid="range-view-empty">
        <div className="text-sm text-secondary-500">{t('calendar.rangeView.noEntries')}</div>
      </div>
    );
  }

  return (
    <div className="flex flex-col h-full overflow-y-auto bg-white" data-testid="range-view">
      {days.map((day) => {
        const key = day.getFullYear() + '-' + day.getMonth() + '-' + day.getDate();
        const dayEntries = entriesByDay.get(key) ?? [];
        const isToday = sameDay(day, today);
        const weekdayIdx = (day.getDay() + 6) % 7;

        return (
          <div key={key} className="border-b border-secondary-100" data-testid={'range-day-' + key}>
            <div
              className={clsx(
                'flex items-center gap-2 px-4 py-2 sticky top-0 z-10',
                isToday ? 'bg-primary-50' : 'bg-secondary-50',
              )}
            >
              <span className="text-sm font-semibold text-secondary-900">
                {weekdays[weekdayIdx]}
              </span>
              <span className="text-sm text-secondary-600">{fmtDayDate(day)}</span>
              {dayEntries.length > 0 && (
                <span className="ml-auto text-xs text-secondary-400">
                  {t('calendar.rangeView.entriesFor', { count: dayEntries.length })}
                </span>
              )}
            </div>

            {dayEntries.length === 0 ? (
              <div className="px-4 py-2 text-xs text-secondary-400 italic">
                {t('calendar.rangeView.noEntries')}
              </div>
            ) : (
              <ul className="divide-y divide-secondary-50">
                {dayEntries.map((entry) => {
                  const start = entry.start_at ? new Date(entry.start_at) : null;
                  return (
                    <li
                      key={entry.id}
                      className="flex items-center gap-3 px-4 py-2 hover:bg-secondary-50 cursor-pointer"
                      onClick={() => onEditEntry(entry)}
                      onKeyDown={(e) => {
                        if (e.key === 'Enter' || e.key === ' ') {
                          e.preventDefault();
                          onEditEntry(entry);
                        }
                      }}
                      tabIndex={0}
                      role="button"
                      data-testid={'range-entry-' + entry.id}
                    >
                      <div className="w-16 flex-shrink-0 text-xs font-mono text-secondary-600">
                        {start ? fmtTime(start) : '-'}
                      </div>

                      <span
                        className={clsx(
                          'flex-shrink-0 px-1.5 py-0.5 rounded text-xs font-medium uppercase',
                          entry.entry_type === 'task'
                            ? 'bg-warning-100 text-warning-800'
                            : 'bg-primary-100 text-primary-800',
                        )}
                      >
                        {entry.entry_type}
                      </span>

                      <div className="flex-1 min-w-0">
                        <div className="text-sm font-medium text-secondary-900 truncate">
                          {entry.title}
                        </div>
                        {entry.location && (
                          <div className="text-xs text-secondary-500 truncate">{entry.location}</div>
                        )}
                      </div>

                      <span
                        className={clsx(
                          'flex-shrink-0 px-1.5 py-0.5 rounded text-xs',
                          entry.status === 'done' && 'bg-success-100 text-success-800',
                          entry.status === 'in_progress' && 'bg-primary-100 text-primary-800',
                          entry.status === 'cancelled' && 'bg-danger-100 text-danger-800',
                          entry.status === 'open' && 'bg-secondary-100 text-secondary-700',
                        )}
                      >
                        {t('calendar.status.' + entry.status)}
                      </span>
                    </li>
                  );
                })}
              </ul>
            )}
          </div>
        );
      })}
    </div>
  );
}

export default RangeView;
