import { toISODate } from '../utils/format';

export type PeriodMode = 'week' | 'month' | 'year' | 'custom';

export interface PeriodState {
  mode: PeriodMode;
  from: string;
  to: string;
}

interface Props {
  period: PeriodState;
  onChange: (period: PeriodState) => void;
}

const MODE_LABELS: Record<PeriodMode, string> = {
  week: 'Неделя',
  month: 'Месяц',
  year: 'Год',
  custom: 'Период',
};

export function PeriodSelector({ period, onChange }: Props) {
  const setMode = (mode: PeriodMode) => {
    const now = new Date();
    let from: Date;
    switch (mode) {
      case 'week': {
        const day = now.getDay();
        const diff = day === 0 ? 6 : day - 1;
        from = new Date(now);
        from.setDate(now.getDate() - diff);
        break;
      }
      case 'month':
        from = new Date(now.getFullYear(), now.getMonth(), 1);
        break;
      case 'year':
        from = new Date(now.getFullYear(), 0, 1);
        break;
      case 'custom':
        onChange({ mode, from: period.from, to: period.to });
        return;
    }
    onChange({ mode, from: toISODate(from), to: toISODate(now) });
  };

  const navigate = (direction: -1 | 1) => {
    const fromDate = new Date(period.from);
    let newFrom: Date;
    let newTo: Date;

    switch (period.mode) {
      case 'week':
        newFrom = new Date(fromDate);
        newFrom.setDate(fromDate.getDate() + 7 * direction);
        newTo = new Date(newFrom);
        newTo.setDate(newFrom.getDate() + 6);
        break;
      case 'month':
        newFrom = new Date(
          fromDate.getFullYear(),
          fromDate.getMonth() + direction,
          1,
        );
        newTo = new Date(
          newFrom.getFullYear(),
          newFrom.getMonth() + 1,
          0,
        );
        break;
      case 'year':
        newFrom = new Date(fromDate.getFullYear() + direction, 0, 1);
        newTo = new Date(newFrom.getFullYear(), 11, 31);
        break;
      default:
        return;
    }

    onChange({
      mode: period.mode,
      from: toISODate(newFrom),
      to: toISODate(newTo),
    });
  };

  return (
    <div className="period-picker">
      <div className="segmented-control">
        {(['week', 'month', 'year', 'custom'] as PeriodMode[]).map(
          (m) => (
            <button
              key={m}
              className={`segmented-control__button ${period.mode === m ? 'segmented-control__button--active' : ''}`}
              onClick={() => setMode(m)}
            >
              {MODE_LABELS[m]}
            </button>
          ),
        )}
      </div>

      <div className="period-picker__nav">
        {period.mode !== 'custom' && (
          <button
            className="icon-button"
            onClick={() => navigate(-1)}
            aria-label="Предыдущий период"
            title="Предыдущий период"
          >
            &larr;
          </button>
        )}
        <div className="period-picker__dates">
          <input
            type="date"
            value={period.from}
            onChange={(e) =>
              onChange({ ...period, mode: 'custom', from: e.target.value })
            }
          />
          <span className="period-picker__separator">&mdash;</span>
          <input
            type="date"
            value={period.to}
            onChange={(e) =>
              onChange({ ...period, mode: 'custom', to: e.target.value })
            }
          />
        </div>
        {period.mode !== 'custom' && (
          <button
            className="icon-button"
            onClick={() => navigate(1)}
            aria-label="Следующий период"
            title="Следующий период"
          >
            &rarr;
          </button>
        )}
      </div>
    </div>
  );
}
