import React, { useState, useEffect, useMemo } from 'react';
import {
  format, startOfMonth, endOfMonth, eachDayOfInterval,
  getDay, addMonths, subMonths,
} from 'date-fns';
import { useNavigate } from 'react-router-dom';
import { experimentsApi } from '../api/client';

export default function ExperimentCalendar({ experimentId, template }) {
  const navigate = useNavigate();
  const [currentMonth, setCurrentMonth] = useState(() => new Date());
  const [selectedField, setSelectedField] = useState(null);
  const [calendarDays, setCalendarDays] = useState({});

  const fieldOptions = useMemo(
    () => template.filter((f) => f.active).map((f) => ({ value: f.builtin ? f.key : f.fieldId, label: f.label })),
    [template],
  );

  useEffect(() => {
    if (fieldOptions.length === 0 || selectedField) return;
    const weightField = fieldOptions.find((f) => f.label.toLowerCase().includes('weight'));
    setSelectedField(weightField ? weightField.value : fieldOptions[0]?.value ?? null);
  }, [fieldOptions]); // eslint-disable-line react-hooks/exhaustive-deps

  useEffect(() => {
    if (!selectedField) return;
    let cancelled = false;
    experimentsApi.getCalendar(experimentId, selectedField)
      .then(({ days }) => { if (!cancelled) setCalendarDays(days); })
      .catch(() => {});
    return () => { cancelled = true; };
  }, [experimentId, selectedField]);

  const monthStart = startOfMonth(currentMonth);
  const monthEnd   = endOfMonth(currentMonth);
  const days       = eachDayOfInterval({ start: monthStart, end: monthEnd });
  const leadingPad = getDay(monthStart);

  return (
    <div className="bg-white rounded-xl border border-gray-200 p-5 shadow-sm mt-6">
      <h3 className="text-base font-semibold text-gray-900 mb-4">Daily Record Calendar</h3>

      <div className="flex flex-wrap items-center gap-3 mb-5">
        <span className="text-sm text-gray-600 font-medium">Count by field:</span>
        <select
          data-testid="field-select"
          className="text-sm border border-gray-300 rounded-lg px-3 py-1.5 focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white"
          value={selectedField ?? ''}
          onChange={(e) => setSelectedField(e.target.value)}
          disabled={fieldOptions.length === 0}
        >
          {fieldOptions.map((f) => <option key={f.value} value={f.value}>{f.label}</option>)}
          {fieldOptions.length === 0 && <option value="">No fields configured</option>}
        </select>
      </div>

      <div className="flex items-center justify-between mb-4">
        <button aria-label="Previous month" onClick={() => setCurrentMonth((m) => subMonths(m, 1))}
          className="p-2 rounded-lg hover:bg-gray-100 text-gray-500 text-lg leading-none">&#8249;</button>
        <span className="font-semibold text-gray-900 text-base">{format(currentMonth, 'MMMM yyyy')}</span>
        <button aria-label="Next month" onClick={() => setCurrentMonth((m) => addMonths(m, 1))}
          className="p-2 rounded-lg hover:bg-gray-100 text-gray-500 text-lg leading-none">&#8250;</button>
      </div>

      <div className="grid grid-cols-7 mb-1">
        {['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'].map((d) => (
          <div key={d} className="text-center text-xs font-medium text-gray-400 py-1 select-none">{d}</div>
        ))}
      </div>

      <div className="grid grid-cols-7 gap-1">
        {Array.from({ length: leadingPad }).map((_, i) => <div key={`pad-${i}`} />)}
        {days.map((day) => {
          const dateStr = format(day, 'yyyy-MM-dd');
          const count   = calendarDays[dateStr] ?? 0;
          const hasData = count > 0;
          return (
            <button
              key={dateStr}
              data-testid={`day-${dateStr}`}
              disabled={!hasData}
              onClick={() => navigate(`/experiments/${experimentId}/day/${dateStr}${selectedField ? `?field=${selectedField}` : ''}`)}
              className={[
                'relative flex flex-col items-center justify-center rounded-lg py-1.5 min-h-[2.75rem] text-sm select-none transition-all',
                hasData ? 'bg-blue-50 border border-blue-200 hover:bg-blue-100 cursor-pointer' : 'text-gray-300 cursor-default',
              ].join(' ')}
            >
              <span className={hasData ? 'font-semibold text-blue-900 text-xs' : 'text-xs'}>{day.getDate()}</span>
              {hasData && (
                <span data-testid={`count-${dateStr}`} className="text-[10px] leading-none font-bold text-blue-600 mt-0.5">{count}</span>
              )}
            </button>
          );
        })}
      </div>
    </div>
  );
}
