import React, { useEffect, useState, FormEvent } from 'react';
import { api, ApiError, TimeOffRequest, ConflictingShift, Volunteer } from '../api';
import { useAuth } from '../auth';

export default function TimeOff() {
  const { role, volunteerID } = useAuth();
  const [requests, setRequests] = useState<TimeOffRequest[]>([]);
  const [volunteers, setVolunteers] = useState<Volunteer[]>([]);
  const [error, setError] = useState('');
  const [showForm, setShowForm] = useState(false);
  const [form, setForm] = useState({ starts_at: '', ends_at: '', reason: '', volunteer_id: 0 });
  const [editingId, setEditingId] = useState<number | null>(null);
  const [conflicts, setConflicts] = useState<ConflictingShift[] | null>(null);
  const [deletePreview, setDeletePreview] = useState<{ id: number; shifts: ConflictingShift[] } | null>(null);

  useEffect(() => {
    api.listTimeOff().then(setRequests).catch(() => setError('Could not load requests.'));
    if (role === 'admin') {
      api.listVolunteers().then(vols => setVolunteers(vols as Volunteer[]));
    }
  }, [role]);

  async function handleCreate(e: FormEvent) {
    e.preventDefault();
    setError('');
    try {
      const payload: any = { starts_at: form.starts_at, ends_at: form.ends_at, reason: form.reason };
      if (role === 'admin' && form.volunteer_id > 0) {
        payload.volunteer_id = form.volunteer_id;
      }
      if (conflicts) {
        payload.confirm_conflicts = true;
      }
      const result = await api.createTimeOff(payload);
      setRequests(prev => [result as TimeOffRequest, ...prev]);
      resetForm();
    } catch (err: any) {
      if (err instanceof ApiError && err.status === 409 && err.data?.conflicts) {
        setConflicts(err.data.conflicts);
        return;
      }
      setError(err.message);
    }
  }

  async function handleUpdate(e: FormEvent) {
    e.preventDefault();
    if (!editingId) return;
    setError('');
    try {
      const req = await api.updateTimeOff(editingId, {
        starts_at: form.starts_at,
        ends_at: form.ends_at,
        reason: form.reason,
      });
      setRequests(prev => prev.map(r => r.id === editingId ? req : r));
      resetForm();
    } catch (err: any) {
      setError(err.message);
    }
  }

  async function handleDelete(id: number) {
    setError('');
    try {
      const result = await api.deleteTimeOff(id);
      setRequests(prev => prev.filter(r => r.id !== id));
      setDeletePreview(null);
      if (result.restored_shifts?.length > 0) {
        setError(`Restored volunteer to ${result.restored_shifts.length} shift(s).`);
      }
    } catch (err: any) {
      setError(err.message);
    }
  }

  async function handleDeleteClick(id: number) {
    if (role === 'admin') {
      try {
        const shifts = await api.getRemovedShifts(id);
        if (shifts.length > 0) {
          setDeletePreview({ id, shifts });
          return;
        }
      } catch {
        // If we can't fetch preview, proceed with confirm
      }
    }
    if (window.confirm('Delete this time off request?')) {
      handleDelete(id);
    }
  }

  async function handleReview(id: number, status: 'approved' | 'rejected') {
    try {
      const req = await api.reviewTimeOff(id, status);
      setRequests(prev => prev.map(r => r.id === id ? req : r));
    } catch (err: any) {
      setError(err.message);
    }
  }

  function startEdit(r: TimeOffRequest) {
    setEditingId(r.id);
    setForm({
      starts_at: r.starts_at.split('T')[0],
      ends_at: r.ends_at.split('T')[0],
      reason: r.reason ?? '',
      volunteer_id: 0,
    });
    setShowForm(true);
    setConflicts(null);
  }

  function resetForm() {
    setForm({ starts_at: '', ends_at: '', reason: '', volunteer_id: 0 });
    setShowForm(false);
    setEditingId(null);
    setConflicts(null);
  }

  function canEditOrDelete(r: TimeOffRequest): boolean {
    if (role === 'admin') return true;
    if (r.volunteer_id !== volunteerID) return false;
    return new Date(r.starts_at) > new Date();
  }

  const statusClass = (status: string) => {
    if (status === 'approved') return 'status-approved';
    if (status === 'rejected') return 'status-rejected';
    return 'status-pending';
  };

  const volunteerName = (vid: number) => {
    const v = volunteers.find(v => v.id === vid);
    return v ? v.name : `#${vid}`;
  };

  return (
    <div className="page">
      <div className="page-header">
        <h2>Time Off Requests</h2>
        <button onClick={() => { if (showForm) resetForm(); else setShowForm(true); }}>
          {showForm ? 'Cancel' : 'Request Time Off'}
        </button>
      </div>
      {error && <p className="error">{error}</p>}

      {showForm && (
        <form className="card" onSubmit={editingId ? handleUpdate : handleCreate}>
          <h3>{editingId ? 'Edit Request' : 'New Request'}</h3>
          {role === 'admin' && !editingId && (
            <label>
              Volunteer
              <select
                value={form.volunteer_id}
                onChange={e => setForm(f => ({ ...f, volunteer_id: Number(e.target.value) }))}
              >
                <option value={0}>Myself</option>
                {volunteers.filter(v => v.id !== volunteerID).map(v => (
                  <option key={v.id} value={v.id}>{v.name}</option>
                ))}
              </select>
            </label>
          )}
          <label>
            From
            <input type="date" value={form.starts_at} onChange={e => { setForm(f => ({ ...f, starts_at: e.target.value })); setConflicts(null); }} required />
          </label>
          <label>
            To
            <input type="date" value={form.ends_at} onChange={e => { setForm(f => ({ ...f, ends_at: e.target.value })); setConflicts(null); }} required />
          </label>
          <label>
            Reason
            <textarea value={form.reason} onChange={e => setForm(f => ({ ...f, reason: e.target.value }))} />
          </label>

          {conflicts && (
            <div className="card" style={{ background: '#fff3cd', border: '1px solid #ffc107', marginBottom: '1rem' }}>
              <p><strong>Warning:</strong> This time off conflicts with {conflicts.length} assigned shift(s):</p>
              <ul>
                {conflicts.map(c => (
                  <li key={c.instance_id}>{c.name} on {c.date} ({c.start_time}–{c.end_time})</li>
                ))}
              </ul>
              <p>You will be removed from these shifts. Continue?</p>
            </div>
          )}

          <button type="submit">
            {conflicts ? 'Confirm & Submit' : editingId ? 'Save Changes' : 'Submit'}
          </button>
        </form>
      )}

      {deletePreview && (
        <div className="card" style={{ background: '#d4edda', border: '1px solid #28a745', marginBottom: '1rem' }}>
          <h3>Delete Time Off — Shift Restoration Preview</h3>
          <p>Deleting this time off will restore the volunteer to {deletePreview.shifts.length} shift(s):</p>
          <ul>
            {deletePreview.shifts.map(s => (
              <li key={s.instance_id}>{s.name} on {s.date} ({s.start_time}–{s.end_time})</li>
            ))}
          </ul>
          <button onClick={() => handleDelete(deletePreview.id)}>Confirm Delete &amp; Restore</button>
          <button onClick={() => setDeletePreview(null)} style={{ marginLeft: '0.5rem' }}>Cancel</button>
        </div>
      )}

      {requests.length === 0 ? (
        <p>No time off requests.</p>
      ) : (
        <table>
          <thead>
            <tr>
              {role === 'admin' && <th>Volunteer</th>}
              <th>From</th>
              <th>To</th>
              <th>Reason</th>
              <th>Status</th>
              <th>Actions</th>
            </tr>
          </thead>
          <tbody>
            {requests.map(r => (
              <tr key={r.id}>
                {role === 'admin' && <td>{volunteerName(r.volunteer_id)}</td>}
                <td>{new Date(r.starts_at).toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' })}</td>
                <td>{new Date(r.ends_at).toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' })}</td>
                <td>{r.reason ?? '—'}</td>
                <td><span className={statusClass(r.status)}>{r.status}</span></td>
                <td>
                  {role === 'admin' && r.status === 'pending' && (
                    <>
                      <button className="btn-small" onClick={() => handleReview(r.id, 'approved')}>Approve</button>
                      <button className="btn-small btn-danger" onClick={() => handleReview(r.id, 'rejected')}>Reject</button>
                    </>
                  )}
                  {canEditOrDelete(r) && (
                    <>
                      <button className="btn-small" onClick={() => startEdit(r)}>Edit</button>
                      <button className="btn-small btn-danger" onClick={() => handleDeleteClick(r.id)}>Delete</button>
                    </>
                  )}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      )}
    </div>
  );
}
