import { useMemo, useState } from 'react';
import { FONT_FAMILY_SANS } from '../../../designTokens';

const WEEK_DAYS = ['Lun', 'Mar', 'Mie', 'Jue', 'Vie', 'Sab', 'Dom'];
const MONTHS_ES = [
  'Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',
  'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre',
];

const toIsoDate = (date) => {
  const y = date.getFullYear();
  const m = String(date.getMonth() + 1).padStart(2, '0');
  const d = String(date.getDate()).padStart(2, '0');
  return `${y}-${m}-${d}`;
};

const startOfMonth = (date) => new Date(date.getFullYear(), date.getMonth(), 1);

const getCalendarDays = (visibleMonth) => {
  const start = startOfMonth(visibleMonth);
  const dayIndexMonFirst = (start.getDay() + 6) % 7;
  const firstCellDate = new Date(start);
  firstCellDate.setDate(start.getDate() - dayIndexMonFirst);

  return Array.from({ length: 42 }).map((_, idx) => {
    const d = new Date(firstCellDate);
    d.setDate(firstCellDate.getDate() + idx);
    return d;
  });
};

export const Calendario = ({
  value,
  onChange,
  onClose,
  onClear,
  todayLabel = 'Hoy',
  clearLabel = 'Limpiar',
  mode = 'date',
}) => {
  const today = new Date();
  const selectedDate = useMemo(() => {
    if (!value) return null;
    if (mode === 'month' && /^\d{4}-\d{2}$/.test(value)) {
      return new Date(`${value}-01T00:00:00`);
    }
    return new Date(`${value}T00:00:00`);
  }, [mode, value]);
  const [visibleMonth, setVisibleMonth] = useState(selectedDate || today);
  const [isYearListOpen, setIsYearListOpen] = useState(false);
  const days = useMemo(() => getCalendarDays(visibleMonth), [visibleMonth]);

  const monthText = MONTHS_ES[visibleMonth.getMonth()];
  const yearText = String(visibleMonth.getFullYear());

  const isSameDay = (a, b) =>
    a &&
    b &&
    a.getFullYear() === b.getFullYear() &&
    a.getMonth() === b.getMonth() &&
    a.getDate() === b.getDate();

  const pickDate = (date) => {
    onChange?.(toIsoDate(date));
    onClose?.();
  };

  const pickMonth = (monthIndex) => {
    const periodValue = `${visibleMonth.getFullYear()}-${String(monthIndex + 1).padStart(2, '0')}`;
    onChange?.(periodValue);
    onClose?.();
  };

  const yearOptions = useMemo(() => {
    const currentYear = visibleMonth.getFullYear();
    return Array.from({ length: 31 }, (_, index) => currentYear - 15 + index);
  }, [visibleMonth]);

  return (
    <div
      style={{
        width: '320px',
        maxWidth: '100%',
        borderRadius: '12px',
        background: '#FFFFFF',
        boxShadow: '0px 8px 24px rgba(0,0,0,0.16)',
        padding: '10px',
        boxSizing: 'border-box',
        fontFamily: FONT_FAMILY_SANS,
      }}
    >
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '8px' }}>
        <button
          type="button"
          onClick={() => {
            setVisibleMonth((prev) => new Date(prev.getFullYear(), prev.getMonth() - 1, 1));
            setIsYearListOpen(false);
          }}
          style={{ border: 'none', background: 'transparent', cursor: 'pointer', color: '#2D4952', fontSize: '20px' }}
          aria-label="Mes anterior"
        >
          ←
        </button>
        <div
          style={{
            display: 'inline-flex',
            alignItems: 'center',
            gap: '6px',
            color: '#2D4952',
            fontFamily: FONT_FAMILY_SANS,
          }}
        >
          <span
            style={{
              fontWeight: 400,
              fontStyle: 'normal',
              fontSize: '14px',
              lineHeight: '21px',
              letterSpacing: '0.01em',
            }}
          >
            {monthText}
          </span>
          <span
            style={{
              fontWeight: 500,
              fontStyle: 'normal',
              fontSize: '14px',
              lineHeight: '21px',
              letterSpacing: '0.01em',
              textDecoration: 'underline',
              textDecorationStyle: 'solid',
              textDecorationSkipInk: 'auto',
              cursor: 'pointer',
            }}
            role="button"
            tabIndex={0}
            aria-label="Seleccionar año"
            onClick={() => setIsYearListOpen((prev) => !prev)}
            onKeyDown={(event) => {
              if (event.key === 'Enter' || event.key === ' ') {
                event.preventDefault();
                setIsYearListOpen((prev) => !prev);
              }
            }}
          >
            {yearText}
          </span>
        </div>
        <button
          type="button"
          onClick={() => {
            setVisibleMonth((prev) => new Date(prev.getFullYear(), prev.getMonth() + 1, 1));
            setIsYearListOpen(false);
          }}
          style={{ border: 'none', background: 'transparent', cursor: 'pointer', color: '#2D4952', fontSize: '20px' }}
          aria-label="Mes siguiente"
        >
          →
        </button>
      </div>

      {isYearListOpen ? (
        <div
          style={{
            display: 'grid',
            gridTemplateColumns: 'repeat(3, 1fr)',
            gap: '6px',
            marginBottom: '6px',
            maxHeight: '220px',
            overflowY: 'auto',
            paddingRight: '2px',
          }}
        >
          {yearOptions.map((year) => {
            const isSelectedYear = year === visibleMonth.getFullYear();
            return (
              <button
                key={year}
                type="button"
                onClick={() => {
                  setVisibleMonth((prev) => new Date(year, prev.getMonth(), 1));
                  setIsYearListOpen(false);
                }}
                style={{
                  border: 'none',
                  height: '34px',
                  borderRadius: '8px',
                  background: isSelectedYear ? '#6D3856' : '#F7F7F7',
                  color: isSelectedYear ? '#FFFFFF' : '#2D4952',
                  cursor: 'pointer',
                  fontFamily: FONT_FAMILY_SANS,
                  fontSize: '14px',
                  lineHeight: '21px',
                  fontWeight: isSelectedYear ? 600 : 400,
                }}
              >
                {year}
              </button>
            );
          })}
        </div>
      ) : mode === 'month' ? (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '8px' }}>
          {MONTHS_ES.map((month, monthIndex) => {
            const isSelected =
              selectedDate &&
              selectedDate.getFullYear() === visibleMonth.getFullYear() &&
              selectedDate.getMonth() === monthIndex;
            return (
              <button
                key={month}
                type="button"
                onClick={() => pickMonth(monthIndex)}
                style={{
                  border: 'none',
                  height: '38px',
                  borderRadius: '8px',
                  background: isSelected ? '#6D3856' : '#F7F7F7',
                  color: isSelected ? '#FFFFFF' : '#2D4952',
                  cursor: 'pointer',
                  fontFamily: FONT_FAMILY_SANS,
                  fontSize: '14px',
                  lineHeight: '21px',
                  fontWeight: isSelected ? 600 : 400,
                }}
              >
                {month.slice(0, 3)}
              </button>
            );
          })}
        </div>
      ) : (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', rowGap: '6px' }}>
          {WEEK_DAYS.map((day) => (
            <div
              key={day}
              style={{
                textAlign: 'center',
                fontSize: '14px',
                lineHeight: '21px',
                fontWeight: 600,
                color: day === 'Sab' || day === 'Dom' ? '#6D3856' : '#2D4952',
                paddingBottom: '2px',
              }}
            >
              {day}
            </div>
          ))}

          {days.map((day) => {
            const isCurrentMonth = day.getMonth() === visibleMonth.getMonth();
            const isWeekend = day.getDay() === 0 || day.getDay() === 6;
            const selected = isSameDay(day, selectedDate);
            return (
              <button
                key={day.toISOString()}
                type="button"
                onClick={() => pickDate(day)}
                style={{
                  border: 'none',
                  width: '38px',
                  height: '38px',
                  margin: '0 auto',
                  borderRadius: '8px',
                  background: selected ? '#6D3856' : 'transparent',
                  color: selected
                    ? '#FFFFFF'
                    : !isCurrentMonth
                      ? '#B9B9B9'
                      : isWeekend
                        ? '#6D3856'
                        : '#2D4952',
                  fontSize: '16px',
                  lineHeight: '24px',
                  fontWeight: 500,
                  cursor: 'pointer',
                }}
              >
                {day.getDate()}
              </button>
            );
          })}
        </div>
      )}

      <div style={{ display: 'flex', gap: '10px', marginTop: '10px' }}>
        <button
          type="button"
          onClick={() => {
            onClear?.();
            onClose?.();
          }}
          style={{
            flex: 1,
            height: '42px',
            border: '1px solid #38656D',
            borderRadius: '10px',
            background: '#FFFFFF',
            color: '#2D4952',
            fontSize: '16px',
            lineHeight: '24px',
            fontWeight: 400,
            cursor: 'pointer',
          }}
        >
          {clearLabel}
        </button>
        <button
          type="button"
          onClick={() => {
            if (mode === 'month') {
              const periodValue = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}`;
              onChange?.(periodValue);
              onClose?.();
              return;
            }
            pickDate(today);
          }}
          style={{
            flex: 1,
            height: '42px',
            border: 'none',
            borderRadius: '10px',
            background: '#3F7680',
            color: '#FFFFFF',
            fontSize: '16px',
            lineHeight: '24px',
            fontWeight: 400,
            cursor: 'pointer',
          }}
        >
          {todayLabel}
        </button>
      </div>
    </div>
  );
};

export default Calendario;
