import { useEffect, useMemo, useState } from 'react';
import useAdminShiftStore from '../store/adminShiftStore';
import useAdminStore from '../store/adminStore';
import type { AdminShiftSlot } from '../api/types';
import { MonthNav } from './MonthNav';
import { MonthCalendar } from './MonthCalendar';
import { formatDateOnly } from '../lib/format';

export function ShiftPlanManager() {
  const period = useAdminShiftStore((s) => s.period);
  const slots = useAdminShiftStore((s) => s.slots);
  const busy = useAdminShiftStore((s) => s.busy);
  const error = useAdminShiftStore((s) => s.error);
  const load = useAdminShiftStore((s) => s.load);
  const prevPeriod = useAdminShiftStore((s) => s.prevPeriod);
  const nextPeriod = useAdminShiftStore((s) => s.nextPeriod);
  const createSlot = useAdminShiftStore((s) => s.createSlot);
  const updateSlot = useAdminShiftStore((s) => s.updateSlot);
  const assignEmployee = useAdminShiftStore((s) => s.assignEmployee);
  const removeEmployee = useAdminShiftStore((s) => s.removeEmployee);

  const employees = useAdminStore((s) => s.employees);
  const loadEmployees = useAdminStore((s) => s.loadEmployees);

  const [selectedDate, setSelectedDate] = useState<string | null>(null);

  useEffect(() => {
    load();
    if (!employees) loadEmployees();
  }, [load, loadEmployees, employees]);

  const slotsByDate = useMemo(() => {
    const map = new Map<string, AdminShiftSlot[]>();
    slots?.forEach((slot) => {
      const list = map.get(slot.date) ?? [];
      list.push(slot);
      map.set(slot.date, list);
    });
    return map;
  }, [slots]);

  function renderDay(dateStr: string) {
    const daySlots = slotsByDate.get(dateStr) ?? [];
    return (
      <button
        className={`month-calendar-day-btn ${selectedDate === dateStr ? 'is-selected' : ''}`}
        onClick={() => setSelectedDate(dateStr)}
      >
        {daySlots.map((slot) => (
          <span key={slot.id} className={`calendar-chip ${slot.status}`}>
            {slot.start_time}–{slot.end_time} {slot.occupied}/{slot.capacity}
          </span>
        ))}
      </button>
    );
  }

  const daySlots = selectedDate ? slotsByDate.get(selectedDate) ?? [] : [];

  return (
    <div className="panel">
      <p className="panel-title">Plán směn</p>
      <MonthNav month={period} onPrev={prevPeriod} onNext={nextPeriod} />
      {error && <div className="login-error">{error}</div>}

      {slots === null ? (
        <div className="empty-line">&gt; načítám…</div>
      ) : (
        <MonthCalendar month={period} renderDay={renderDay} />
      )}

      <div style={{ marginTop: '1rem' }}>
        <p className="panel-title">{selectedDate ? formatDateOnly(selectedDate) : 'Vyber den v kalendáři'}</p>

        {selectedDate && (
          <>
            <div className="list">
              {daySlots.length === 0 && <div className="empty-line">· žádné směny</div>}
              {daySlots.map((slot) => (
                <SlotRow
                  key={slot.id}
                  slot={slot}
                  busy={busy}
                  employees={employees ?? []}
                  onSave={(data) => updateSlot(slot.id, data)}
                  onAssign={(employeeId) => assignEmployee(slot.id, employeeId)}
                  onRemove={(employeeId) => removeEmployee(slot.id, employeeId)}
                />
              ))}
            </div>

            <div style={{ marginTop: '0.75rem' }}>
              <NewSlotForm key={selectedDate} busy={busy} defaultDate={selectedDate} onCreate={createSlot} />
            </div>
          </>
        )}
      </div>
    </div>
  );
}

function NewSlotForm({
  busy,
  defaultDate,
  onCreate,
}: {
  busy: boolean;
  defaultDate: string;
  onCreate: (data: { date: string; start_time: string; end_time: string; capacity: number; note?: string }) => Promise<void>;
}) {
  const [date, setDate] = useState(defaultDate);
  const [startTime, setStartTime] = useState('');
  const [endTime, setEndTime] = useState('');
  const [capacity, setCapacity] = useState('1');
  const [note, setNote] = useState('');

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (!date || !startTime || !endTime) return;
    await onCreate({ date, start_time: startTime, end_time: endTime, capacity: Number(capacity), note: note || undefined });
    setStartTime('');
    setEndTime('');
    setCapacity('1');
    setNote('');
  }

  return (
    <form onSubmit={handleSubmit} style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap', alignItems: 'center' }}>
      <input type="date" value={date} onChange={(e) => setDate(e.target.value)} disabled={busy} required />
      <input
        type="time"
        value={startTime}
        onChange={(e) => setStartTime(e.target.value)}
        disabled={busy}
        required
        style={{ width: '6rem' }}
      />
      <input
        type="time"
        value={endTime}
        onChange={(e) => setEndTime(e.target.value)}
        disabled={busy}
        required
        style={{ width: '6rem' }}
      />
      <input
        type="number"
        min={1}
        value={capacity}
        onChange={(e) => setCapacity(e.target.value)}
        disabled={busy}
        style={{ width: '4rem' }}
      />
      <input
        type="text"
        placeholder="poznámka"
        value={note}
        onChange={(e) => setNote(e.target.value)}
        disabled={busy}
        style={{ flex: 1, minWidth: '8rem' }}
      />
      <button className="btn" type="submit" disabled={busy}>
        Přidat mimořádnou směnu
      </button>
    </form>
  );
}

function SlotRow({
  slot,
  busy,
  employees,
  onSave,
  onAssign,
  onRemove,
}: {
  slot: AdminShiftSlot;
  busy: boolean;
  employees: { id: number; email: string; name: string | null; active: 0 | 1 }[];
  onSave: (data: { date: string; start_time: string; end_time: string; capacity: number; note?: string }) => Promise<void>;
  onAssign: (employeeId: number) => Promise<void>;
  onRemove: (employeeId: number) => Promise<void>;
}) {
  const [capacity, setCapacity] = useState(String(slot.capacity));
  const [note, setNote] = useState(slot.note);
  const [pick, setPick] = useState('');

  const dirty = Number(capacity) !== slot.capacity || note !== slot.note;
  const assignedIds = new Set(slot.employees.map((e) => e.employee_id));
  const candidates = employees.filter((e) => e.active === 1 && !assignedIds.has(e.id));

  return (
    <div className="row" style={{ flexWrap: 'wrap' }}>
      <div className="row-main">
        <div className="row-title">
          {slot.start_time}–{slot.end_time}{' '}
          <span className={`badge ${slot.status === 'open' ? 'badge-dashed' : 'badge-solid'}`}>
            {slot.status === 'open' ? 'volno' : slot.status === 'full' ? 'obsazeno' : 'uzavřeno'}
          </span>
        </div>
        <div className="row-meta">
          {slot.employees.length === 0 ? '· nikdo přihlášen' : slot.employees.map((e) => e.name).join(', ')}
        </div>
        <div style={{ display: 'flex', gap: '0.5rem', marginTop: '0.4rem', flexWrap: 'wrap', alignItems: 'center' }}>
          <input
            type="number"
            min={0}
            value={capacity}
            onChange={(e) => setCapacity(e.target.value)}
            disabled={busy}
            style={{ width: '3.5rem' }}
          />
          <input
            type="text"
            placeholder="poznámka"
            value={note}
            onChange={(e) => setNote(e.target.value)}
            disabled={busy}
            style={{ width: '10rem' }}
          />
          {dirty && (
            <button
              className="btn"
              disabled={busy}
              onClick={() =>
                onSave({
                  date: slot.date,
                  start_time: slot.start_time,
                  end_time: slot.end_time,
                  capacity: Number(capacity),
                  note: note || undefined,
                })
              }
            >
              Uložit
            </button>
          )}

          {slot.employees.map((e) => (
            <span key={e.employee_id} className="badge">
              {e.name}{' '}
              <button className="btn-ghost" disabled={busy} onClick={() => onRemove(e.employee_id)}>
                x
              </button>
            </span>
          ))}

          {candidates.length > 0 && (
            <>
              <select value={pick} onChange={(e) => setPick(e.target.value)} disabled={busy}>
                <option value="">přiřadit…</option>
                {candidates.map((e) => (
                  <option key={e.id} value={e.id}>
                    {e.name ?? e.email}
                  </option>
                ))}
              </select>
              <button
                className="btn"
                disabled={busy || !pick}
                onClick={() => {
                  onAssign(Number(pick));
                  setPick('');
                }}
              >
                Přiřadit
              </button>
            </>
          )}
        </div>
      </div>
    </div>
  );
}
