import { expect, test } from 'bun:test';

import { isSlotInPast } from '@/lib/slot-validator';

/**
 * Helper to create a bookingDate like parseIsoDate does (UTC midnight).
 */
function bookingDate(year: number, month: number, day: number): Date {
  return new Date(Date.UTC(year, month - 1, day));
}

/**
 * Helper to create a "now" date at a specific local time.
 * Using local date constructor guarantees the date parts
 * (getFullYear, getMonth, getDate) match the arguments
 * regardless of the test runner's timezone.
 */
function localDate(year: number, month: number, day: number, hours: number, minutes: number): Date {
  return new Date(year, month - 1, day, hours, minutes, 0, 0);
}

test('future date — always allowed', () => {
  const future = bookingDate(2027, 6, 10); // 2027-06-10
  const now = localDate(2026, 6, 8, 12, 0); // 2026-06-08 12:00

  expect(isSlotInPast(future, '10:00', 60, now)).toBe(false);
});

test('past date — rejected', () => {
  const past = bookingDate(2025, 6, 8); // 2025-06-08
  const now = localDate(2026, 6, 8, 12, 0); // 2026-06-08 12:00

  expect(isSlotInPast(past, '10:00', 60, now)).toBe(true);
});

test('today, slot not started yet — allowed', () => {
  const today = bookingDate(2026, 6, 8); // 2026-06-08
  const now = localDate(2026, 6, 8, 9, 0); // 09:00, slot empieza a las 10:00

  expect(isSlotInPast(today, '10:00', 60, now)).toBe(false);
});

test('today, slot in progress less than half elapsed — allowed', () => {
  const today = bookingDate(2026, 6, 8);
  const now = localDate(2026, 6, 8, 10, 10); // 10:10, slot 10:00-11:00 (60 min), 10 min elapsed

  expect(isSlotInPast(today, '10:00', 60, now)).toBe(false);
});

test('today, slot in progress more than half elapsed — rejected', () => {
  const today = bookingDate(2026, 6, 8);
  const now = localDate(2026, 6, 8, 10, 40); // 10:40, slot 10:00-11:00 (60 min), 40 min elapsed

  expect(isSlotInPast(today, '10:00', 60, now)).toBe(true);
});

test('today, slot already ended — rejected', () => {
  const today = bookingDate(2026, 6, 8);
  const now = localDate(2026, 6, 8, 11, 1); // 11:01, slot 10:00-11:00 terminó

  expect(isSlotInPast(today, '10:00', 60, now)).toBe(true);
});

test('today, exactly half elapsed — allowed (inclusive boundary)', () => {
  const today = bookingDate(2026, 6, 8);
  const now = localDate(2026, 6, 8, 10, 30); // 10:30, slot 10:00-11:00 (60 min), exactamente 30 min

  expect(isSlotInPast(today, '10:00', 60, now)).toBe(false);
});

test('today, slot starts exactly now — allowed', () => {
  const today = bookingDate(2026, 6, 8);
  const now = localDate(2026, 6, 8, 10, 0); // 10:00 exacto

  expect(isSlotInPast(today, '10:00', 60, now)).toBe(false);
});

test('90 min slot with 10 min elapsed — allowed', () => {
  const today = bookingDate(2026, 6, 8);
  const now = localDate(2026, 6, 8, 12, 10); // 12:10, slot 12:00-13:30, 10/90 elapsed

  expect(isSlotInPast(today, '12:00', 90, now)).toBe(false);
});

test('90 min slot with 50 min elapsed — rejected', () => {
  const today = bookingDate(2026, 6, 8);
  const now = localDate(2026, 6, 8, 12, 50); // 12:50, slot 12:00-13:30, 50/90 elapsed

  expect(isSlotInPast(today, '12:00', 90, now)).toBe(true);
});
