"use client";

import { useState } from "react";

type Slot = { id: number; inicio: string; fin: string; funcionario: string | null };

type Props = {
  entity: string;
  service: string;
  date: string;
  today: string;
  busy: boolean;
  slots: Slot[];
  selectedSlot: Slot | null;
  onDateChange: (date: string) => void;
  onSlotChange: (slot: Slot | null) => void;
  onBack: () => void;
  onContinue: () => void;
};

const zone = "America/Santiago";
const dayMs = 86_400_000;
const weekdays = ["LUN", "MAR", "MIÉ", "JUE", "VIE", "SÁB", "DOM"];

function isoDay(date: Date) {
  return date.toISOString().slice(0, 10);
}

function utcDay(iso: string) {
  const [year, month, day] = iso.split("-").map(Number);
  return new Date(Date.UTC(year, month - 1, day, 12));
}

function prettyDay(iso: string) {
  return new Intl.DateTimeFormat("es-CL", {
    timeZone: "UTC", weekday: "long", day: "numeric", month: "long", year: "numeric",
  }).format(utcDay(iso));
}

function timeOf(slot: Slot) {
  return new Intl.DateTimeFormat("es-CL", {
    timeZone: zone, hour: "2-digit", minute: "2-digit", hour12: false,
  }).format(new Date(slot.inicio));
}

function hourOf(slot: Slot) {
  return Number(new Intl.DateTimeFormat("en-GB", {
    timeZone: zone, hour: "2-digit", hour12: false,
  }).format(new Date(slot.inicio)));
}

function CalendarIcon({ small = false }: { small?: boolean }) {
  return <svg width={small ? 18 : 22} height={small ? 18 : 22} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
    <rect x="3" y="5" width="18" height="16" rx="2"/><path d="M7 3v4M17 3v4M3 10h18"/>
  </svg>;
}

function PeriodIcon({ afternoon }: { afternoon: boolean }) {
  return afternoon
    ? <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M20 15.2A8.7 8.7 0 0 1 8.8 4 8.8 8.8 0 1 0 20 15.2Z"/></svg>
    : <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" aria-hidden="true"><circle cx="12" cy="12" r="4"/><path d="M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32 1.41 1.41M2 12h2m16 0h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/></svg>;
}

export default function AppointmentPicker({
  entity, service, date, today, busy, slots, selectedSlot,
  onDateChange, onSlotChange, onBack, onContinue,
}: Props) {
  const [month, setMonth] = useState(date.slice(0, 7));
  const [year, monthNumber] = month.split("-").map(Number);
  const first = new Date(Date.UTC(year, monthNumber - 1, 1, 12));
  const dayCount = new Date(Date.UTC(year, monthNumber, 0, 12)).getUTCDate();
  const offset = (first.getUTCDay() + 6) % 7;
  const maxDay = isoDay(new Date(utcDay(today).getTime() + 60 * dayMs));
  const previousMonth = new Date(Date.UTC(year, monthNumber - 2, 1, 12)).toISOString().slice(0, 7);
  const nextMonth = new Date(Date.UTC(year, monthNumber, 1, 12)).toISOString().slice(0, 7);
  const canGoBack = previousMonth >= today.slice(0, 7);
  const canGoForward = nextMonth <= maxDay.slice(0, 7);
  const monthLabel = new Intl.DateTimeFormat("es-CL", {
    timeZone: "UTC", month: "long", year: "numeric",
  }).format(first);
  const morning = slots.filter((slot) => hourOf(slot) < 12);
  const afternoon = slots.filter((slot) => hourOf(slot) >= 12);

  function chooseDate(value: string) {
    onSlotChange(null);
    onDateChange(value);
  }

  function slotGroup(title: string, afternoonPeriod: boolean, items: Slot[]) {
    if (!items.length) return null;
    return <div className="booking-picker__period">
      <h4><span className="booking-picker__period-icon"><PeriodIcon afternoon={afternoonPeriod} /></span>{title}</h4>
      <div className="booking-picker__times" role="group" aria-label={`Horarios de ${title.toLowerCase()}`}>
        {items.map((slot) => <button key={slot.id} type="button"
          className="booking-picker__time" aria-pressed={selectedSlot?.id === slot.id}
          aria-label={`${timeOf(slot)}${slot.funcionario ? `, ${slot.funcionario}` : ""}`}
          onClick={() => onSlotChange(slot)}>{timeOf(slot)}</button>)}
      </div>
    </div>;
  }

  return <section className="procedure-card booking-picker">
    <header className="booking-picker__heading">
      <span className="section-kicker">DESPUÉS DE TUS DATOS Y ANTES DEL PAGO</span>
      <h2>Elige fecha y hora</h2>
      <p>{entity} <span aria-hidden="true">·</span> {service}</p>
    </header>

    <div className="booking-picker__layout">
      <div className="booking-picker__calendar" aria-label="Calendario de atención">
        <div className="booking-picker__month">
          <button type="button" className="booking-picker__arrow" aria-label="Mes anterior"
            disabled={!canGoBack} onClick={() => setMonth(previousMonth)}>‹</button>
          <h3>{monthLabel}</h3>
          <button type="button" className="booking-picker__arrow" aria-label="Mes siguiente"
            disabled={!canGoForward} onClick={() => setMonth(nextMonth)}>›</button>
        </div>
        <div className="booking-picker__days" role="group" aria-label={monthLabel}>
          {weekdays.map((name) => <span key={name} className="booking-picker__weekday">{name}</span>)}
          {Array.from({ length: offset }, (_, index) => <span key={`blank-${index}`} aria-hidden="true" />)}
          {Array.from({ length: dayCount }, (_, index) => {
            const value = `${year}-${String(monthNumber).padStart(2, "0")}-${String(index + 1).padStart(2, "0")}`;
            return <button key={value} type="button" className="booking-picker__day"
              disabled={value < today || value > maxDay} aria-pressed={value === date}
              aria-label={prettyDay(value)} onClick={() => chooseDate(value)}>{index + 1}</button>;
          })}
        </div>
      </div>

      <div className="booking-picker__availability" aria-live="polite">
        <h3><span className="booking-picker__date-icon"><CalendarIcon /></span>{prettyDay(date)}</h3>
        {busy ? <p className="booking-picker__status" role="status">Consultando horarios disponibles…</p>
          : slots.length ? <>
            {slotGroup("Mañana", false, morning)}
            {slotGroup("Tarde", true, afternoon)}
          </> : <div className="booking-picker__empty">
            <CalendarIcon small />
            <div><strong>No hay horas disponibles ese día</strong><p>Selecciona otra fecha en el calendario.</p></div>
          </div>}
      </div>
    </div>

    <p className="booking-picker__note"><span aria-hidden="true">ⓘ</span> La hora se retiene temporalmente al iniciar el pago y se confirma únicamente cuando el pago sea aprobado.</p>
    <div className="procedure-actions booking-picker__actions">
      <button type="button" className="button button-secondary" onClick={onBack}>Volver a mis datos</button>
      <button type="button" className="button button-primary" disabled={!selectedSlot || busy}
        onClick={onContinue}>Revisar y continuar →</button>
    </div>
  </section>;
}
