import type { ScheduleWeek, Shift, StoreMember } from '@alqove/api-client';
import { addDays, instantToLocal } from './schedule-time';

export function ShiftSummary({ shift, timezone, showDate = false }: { shift: Shift; timezone: string; showDate?: boolean }) {
  const start = instantToLocal(shift.starts_at, timezone);
  const end = instantToLocal(shift.ends_at, timezone);
  return <>{showDate && <span className="block text-xs">{start.slice(0, 10)}</span>}<span className="block font-medium">{start.slice(11)} – {start.slice(0, 10) !== end.slice(0, 10) ? `${end.slice(0, 10)} ` : ''}{end.slice(11)}</span>
    {shift.position_name && <span className="block">{shift.position_name}</span>}
    <span className="block text-xs">{shift.published_at ? 'Published' : 'Draft'}</span>
    {shift.notes && <span className="block break-words text-xs">{shift.notes}</span>}</>;
}

/** CSS grid with table semantics; narrow screens scroll inside this region only. */
export function WeekGrid({ week, members = [], onEdit }: { week: ScheduleWeek; members?: StoreMember[]; onEdit?: (shift: Shift) => void }) {
  const days = Array.from({ length: 7 }, (_, i) => addDays(week.week_start, i));
  const rows = new Map<string, string>([['open', 'Open shifts']]);
  members.filter(m => m.status === 'active').forEach(m => rows.set(m.id, m.name ?? 'Team member'));
  week.shifts.forEach(s => rows.set(s.store_membership_id ?? 'open', s.member_name ?? 'Open shifts'));
  // A shift before the work-week cutoff on the final calendar day belongs to
  // the last column, not an invisible eighth day. Its full date stays visible.
  const cellDay = (shift: Shift) => {
    const date = instantToLocal(shift.starts_at, week.timezone).slice(0, 10);
    return date < days[0] ? days[0] : date > days[6] ? days[6] : date;
  };
  return <div className="overflow-x-auto rounded-lg border" tabIndex={0} aria-label="Weekly schedule scroll area">
    <div role="table" aria-label="Weekly schedule" className="min-w-[960px] text-sm">
      <div role="row" className="grid grid-cols-[150px_repeat(7,minmax(110px,1fr))] bg-[hsl(var(--muted))]">
        <div role="columnheader" className="p-3 font-semibold">Employee</div>
        {days.map(day => <div role="columnheader" className="border-l p-3 font-semibold" key={day}>{new Intl.DateTimeFormat('en-US', { timeZone: 'UTC', weekday: 'short', month: 'short', day: 'numeric' }).format(new Date(`${day}T12:00:00Z`))}</div>)}
      </div>
      {[...rows].map(([id, name]) => <div role="row" key={id} className="grid grid-cols-[150px_repeat(7,minmax(110px,1fr))] border-t">
        <div role="rowheader" className="p-3 font-medium">{name}</div>
        {days.map(day => <div role="cell" key={day} className="min-h-24 space-y-2 border-l p-2" aria-label={`${name}, ${day}`}>
          {week.shifts.filter(s => (s.store_membership_id ?? 'open') === id && cellDay(s) === day).map(s => onEdit
            ? <button key={s.id} type="button" aria-label={`Edit ${name} ${instantToLocal(s.starts_at, week.timezone)} to ${instantToLocal(s.ends_at, week.timezone)}`} onClick={() => onEdit(s)} className="w-full rounded border border-blue-200 bg-blue-50 p-2 text-left text-slate-900 hover:bg-blue-100 focus-visible:outline-2"><ShiftSummary shift={s} timezone={week.timezone} showDate={instantToLocal(s.starts_at, week.timezone).slice(0, 10) !== day} /></button>
            : <div key={s.id} className="rounded border p-2"><ShiftSummary shift={s} timezone={week.timezone} showDate={instantToLocal(s.starts_at, week.timezone).slice(0, 10) !== day} /></div>)}
        </div>)}
      </div>)}
    </div>
    {!week.shifts.length && <p className="p-4">No shifts this week.</p>}
  </div>;
}
