import type { CreateCourtInput, DayOfWeek } from '@repo/api-contract';
import { DAY_LABEL_BY_VALUE, DAY_ORDER } from './court.constants';

function formatTimeCompact(value: string): string {
  const [rawHours = '00', rawMinutes = '00'] = value.split(':');
  const hours = Number(rawHours);
  return `${hours}:${rawMinutes}`;
}

function formatDayRange(dayIndexes: number[]): string {
  if (dayIndexes.length === 0) return '';

  const sorted = [...dayIndexes].sort((a, b) => a - b);
  const chunks: Array<{ start: number; end: number }> = [];
  let start = sorted[0];
  let previous = sorted[0];

  for (let index = 1; index < sorted.length; index += 1) {
    const current = sorted[index];

    if (current === previous + 1) {
      previous = current;
      continue;
    }

    chunks.push({ start, end: previous });
    start = current;
    previous = current;
  }

  chunks.push({ start, end: previous });

  return chunks
    .map((chunk) => {
      const startDay = DAY_ORDER[chunk.start];
      const endDay = DAY_ORDER[chunk.end];
      const startLabel = startDay ? DAY_LABEL_BY_VALUE.get(startDay) : undefined;
      const endLabel = endDay ? DAY_LABEL_BY_VALUE.get(endDay) : undefined;

      if (!startLabel || !endLabel) return '';
      if (chunk.start === chunk.end) return startLabel;
      return `${startLabel} a ${endLabel}`;
    })
    .filter(Boolean)
    .join(', ');
}

export function summarizeAvailability(
  availability: Array<{
    dayOfWeek: DayOfWeek;
    startTime: string;
    endTime: string;
  }>
) {
  const grouped = new Map<string, number[]>();

  for (const slot of availability) {
    const dayIndex = DAY_ORDER.indexOf(slot.dayOfWeek);
    if (dayIndex < 0) continue;

    const key = `${slot.startTime}-${slot.endTime}`;
    const current = grouped.get(key) ?? [];
    current.push(dayIndex);
    grouped.set(key, current);
  }

  return [...grouped.entries()]
    .map(([timeRange, dayIndexes]) => {
      const [startTime = '00:00', endTime = '00:00'] = timeRange.split('-');
      const dayLabel = formatDayRange(dayIndexes);
      return `${dayLabel} · ${formatTimeCompact(startTime)} a ${formatTimeCompact(endTime)}`;
    })
    .filter(Boolean);
}

export function formatCurrency(amount: number): string {
  return new Intl.NumberFormat('es-AR', {
    style: 'currency',
    currency: 'ARS',
    maximumFractionDigits: 2,
  }).format(amount);
}

export function createDefaultCourtValues(): CreateCourtInput {
  return {
    name: '',
    sportId: '',
    slotDurationMinutes: 60,
    basePrice: 0,
    availability: [
      {
        dayOfWeek: 'MONDAY',
        startTime: '08:00',
        endTime: '22:00',
      },
    ],
  };
}
