import { useCallback, useEffect, useMemo, useState } from 'react'
import { Plus, RefreshCw, Camera, BedDouble, Layers, ChevronDown } from 'lucide-react'
import type { Task, Category, Location, AppConfig, TaskStatus } from '../types'
import { STATUS_LABELS, can } from '../types'
import { fetchTasks, fetchLocations, fetchConfig, fetchOccupancy } from '../api'
import { useAuth } from '../components/AuthGate'
import NewTaskModal from '../components/NewTaskModal'
import TaskModal from '../components/TaskModal'
import { PriorityBadge, StatusBadge, UnusableBadge, ageLabel, formatDate } from '../components/shared'

const OPEN_STATUSES: TaskStatus[] = ['submitted', 'in_progress', 'hold_parts', 'hold_scheduled', 'temporary_fix']

export default function Summary() {
  const { user } = useAuth()
  const [tasks, setTasks] = useState<Task[]>([])
  const [categories, setCategories] = useState<Category[]>([])
  const [locations, setLocations] = useState<Location[]>([])
  const [config, setConfig] = useState<AppConfig | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [loading, setLoading] = useState(false)
  const [occupiedSiteIds, setOccupiedSiteIds] = useState<Set<string>>(new Set())
  const [arrivingSiteIds, setArrivingSiteIds] = useState<Set<string>>(new Set())

  const [statusFilter, setStatusFilter] = useState<TaskStatus | null>(null)
  const [categoryFilter, setCategoryFilter] = useState<number | null>(null)
  const [mineOnly, setMineOnly] = useState(false)
  const [roomsView, setRoomsView] = useState(false)
  const [groupByLocation, setGroupByLocation] = useState(false)

  const [statusOpen, setStatusOpen] = useState(false)
  const [filtersOpen, setFiltersOpen] = useState(false)

  const [showNew, setShowNew] = useState(false)
  const [openTask, setOpenTask] = useState<number | null>(null)

  const roomsCat = useMemo(() => categories.find(c => c.is_rooms) ?? null, [categories])

  const load = useCallback(() => {
    setLoading(true)
    const taskFetch = fetchTasks({
      status: statusFilter ?? OPEN_STATUSES.join(','),
      // In rooms-view mode filter to rooms category; otherwise use the active category chip
      category_id: roomsView ? (roomsCat?.id ?? undefined) : (categoryFilter ?? undefined),
      assigned_to: mineOnly ? user.email : undefined,
    })
    // When rooms-view is on, also fetch live occupancy to mark occupied tasks
    const occFetch = roomsView ? fetchOccupancy().catch(() => null) : Promise.resolve(null)

    Promise.all([taskFetch, occFetch])
      .then(([t, occ]) => {
        setTasks(t)
        setOccupiedSiteIds(occ ? new Set(occ.occupied_site_ids) : new Set())
        setArrivingSiteIds(occ ? new Set(occ.arriving_site_ids) : new Set())
        setError(null)
      })
      .catch(err => setError(err.message))
      .finally(() => setLoading(false))
  }, [statusFilter, categoryFilter, mineOnly, roomsView, roomsCat, user.email])

  useEffect(() => { load() }, [load])
  useEffect(() => {
    fetchLocations().then(d => { setCategories(d.categories); setLocations(d.locations) }).catch(() => {})
    fetchConfig().then(setConfig).catch(() => {})
  }, [])

  const counts = useMemo(() => {
    const c: Partial<Record<TaskStatus, number>> = {}
    for (const t of tasks) c[t.status] = (c[t.status] || 0) + 1
    return c
  }, [tasks])

  const categoryCounts = useMemo(() => {
    const c: Record<number, number> = {}
    for (const t of tasks) c[t.category_id] = (c[t.category_id] || 0) + 1
    return c
  }, [tasks])

  // Rooms chip counts: occupied = guest in room, arriving = booked today not yet in
  const roomsCounts = useMemo(() => {
    if (!roomsView) return null
    let occupied = 0, arriving = 0
    for (const t of tasks) {
      const sid = t.newbook_site_id ? String(t.newbook_site_id) : null
      if (sid && occupiedSiteIds.has(sid)) occupied++
      else if (sid && arrivingSiteIds.has(sid)) arriving++
    }
    return { total: tasks.length, occupied, arriving, free: tasks.length - occupied - arriving }
  }, [tasks, roomsView, occupiedSiteIds, arrivingSiteIds])

  const taskGroups = useMemo(() => {
    if (!groupByLocation) return null
    const groups: Record<string, Task[]> = {}
    for (const t of tasks) {
      const key = t.location_name || 'Unknown'
      if (!groups[key]) groups[key] = []
      groups[key].push(t)
    }
    return Object.entries(groups).sort(([a], [b]) => a.localeCompare(b))
  }, [tasks, groupByLocation])

  const roomsCategoryExists = !!roomsCat

  function toggleRoomsView() {
    setRoomsView(v => !v)
    setCategoryFilter(null) // clear any category chip when entering/leaving rooms-view
  }

  return (
    <div className="page">
      <div className="page-header">
        <h1>Open maintenance</h1>
        <button className="btn" onClick={load} disabled={loading}>
          <RefreshCw size={14} strokeWidth={1.75} /> Refresh
        </button>
        {can(user, 'report') && (
          <button className="btn btn-primary" onClick={() => setShowNew(true)}>
            <Plus size={14} strokeWidth={1.75} /> Report fault
          </button>
        )}
      </div>

      {error && <div className="error-banner">{error}</div>}

      <div className="filter-section">
        <div className="filter-section-header" onClick={() => setStatusOpen(v => !v)}>
          <span className="filter-section-label">Status</span>
          <span className={`filter-section-summary${statusFilter === null ? ' muted' : ''}`}>
            {statusFilter === null ? 'All open' : `${STATUS_LABELS[statusFilter]}${counts[statusFilter] ? ` (${counts[statusFilter]})` : ''}`}
          </span>
          <ChevronDown size={14} strokeWidth={1.75} className={`filter-section-chevron${statusOpen ? ' open' : ''}`} />
        </div>
        {statusOpen && (
          <div className="chip-bar">
            <button className={`chip ${statusFilter === null ? 'active' : ''}`} onClick={() => setStatusFilter(null)}>
              All open
            </button>
            {OPEN_STATUSES.map(s => (
              <button key={s} className={`chip ${statusFilter === s ? 'active' : ''}`} onClick={() => setStatusFilter(statusFilter === s ? null : s)}>
                {STATUS_LABELS[s]}{counts[s] ? ` (${counts[s]})` : ''}
              </button>
            ))}
          </div>
        )}
      </div>

      <div className="filter-section">
        <div className="filter-section-header" onClick={() => setFiltersOpen(v => !v)}>
          <span className="filter-section-label">Filters</span>
          <span className={`filter-section-summary${!categoryFilter && !mineOnly && !roomsView && !groupByLocation ? ' muted' : ''}`}>
            {[
              !roomsView && categoryFilter ? categories.find(c => c.id === categoryFilter)?.name : null,
              roomsView ? 'Rooms view' : null,
              mineOnly ? 'Mine only' : null,
              groupByLocation ? 'Grouped' : null,
            ].filter(Boolean).join(' · ') || 'All categories'}
          </span>
          <ChevronDown size={14} strokeWidth={1.75} className={`filter-section-chevron${filtersOpen ? ' open' : ''}`} />
        </div>
        {filtersOpen && (
          <div className="chip-bar">
            {!roomsView && categories.map(c => (
              <button key={c.id} className={`chip ${categoryFilter === c.id ? 'active' : ''}`} onClick={() => setCategoryFilter(categoryFilter === c.id ? null : c.id)}>
                {c.name}{categoryCounts[c.id] ? ` (${categoryCounts[c.id]})` : ''}
              </button>
            ))}
            <button className={`chip ${mineOnly ? 'active' : ''}`} onClick={() => setMineOnly(!mineOnly)}>
              Mine
            </button>
            {roomsCategoryExists && (
              <button
                className={`chip ${roomsView ? 'active' : ''}`}
                title="Show all rooms tasks — greyed tasks have an in-house guest so access may be limited"
                onClick={toggleRoomsView}
              >
                <BedDouble size={13} strokeWidth={1.75} />
                {roomsView && roomsCounts
                  ? `Rooms (${roomsCounts.free} free${roomsCounts.arriving ? ` • ${roomsCounts.arriving} arriving` : ''}${roomsCounts.occupied ? ` • ${roomsCounts.occupied} occupied` : ''})`
                  : 'Rooms Accessible View'}
              </button>
            )}
            <button className={`chip ${groupByLocation ? 'active' : ''}`} onClick={() => setGroupByLocation(v => !v)}>
              <Layers size={13} strokeWidth={1.75} /> Group by location
            </button>
          </div>
        )}
      </div>

      {tasks.length === 0 && !loading && (
        <div className="empty-state">No open tasks match these filters.</div>
      )}

      {(() => {
        const renderTask = (t: Task) => {
          const sid = t.newbook_site_id ? String(t.newbook_site_id) : null
          const isOccupied = roomsView && !!sid && occupiedSiteIds.has(sid)
          const isArriving = roomsView && !!sid && !isOccupied && arrivingSiteIds.has(sid)
          return (
            <div
              key={t.id}
              className={`card task-card ${t.priority === 'urgent' ? 'urgent' : t.priority === 'high' ? 'high' : ''} ${t.unusable ? 'unusable' : ''}`}
              style={isOccupied ? { opacity: 0.5, filter: 'grayscale(0.3)' } : undefined}
              onClick={() => setOpenTask(t.id)}
            >
              <div className="task-card-main">
                <div className="task-card-title">
                  {t.title}
                  {isOccupied && <span className="badge badge-outline"><BedDouble size={10} strokeWidth={1.75} /> Occupied</span>}
                  {isArriving && <span className="badge" style={{ background: '#fef3c7', color: '#92400e', border: '1px solid #fcd34d' }}><BedDouble size={10} strokeWidth={1.75} /> Arrival today</span>}
                  {t.unusable && <UnusableBadge />}
                  {t.template_id && <span className="badge badge-outline">Recurring</span>}
                </div>
                <div className="task-card-meta">
                  {!groupByLocation && <span>{t.location_name}</span>}
                  <span>{t.category_name}</span>
                  {t.asset_name && <span>{t.asset_name}</span>}
                  <span>{ageLabel(t.created_at)} old</span>
                  {t.due_date && (
                    <span className={new Date(t.due_date) < new Date() ? 'overdue' : ''}>
                      due {formatDate(t.due_date)}
                    </span>
                  )}
                  {t.hold_until && <span>held until {formatDate(t.hold_until)}</span>}
                  {t.photo_count > 0 && <span><Camera size={12} strokeWidth={1.75} style={{ verticalAlign: -2 }} /> {t.photo_count}</span>}
                </div>
              </div>
              <div className="task-card-side">
                <PriorityBadge priority={t.priority} />
                <StatusBadge status={t.status} />
                <span className="muted" style={{ fontSize: 11.5 }}>
                  {t.assigned_type === 'contractor' ? (t.contractor_name || '—') : (t.assigned_to_name || 'Unassigned')}
                </span>
              </div>
            </div>
          )
        }

        if (taskGroups) {
          return taskGroups.map(([locationName, groupTasks]) => (
            <div key={locationName}>
              <div className="section-title">{locationName} <span style={{ fontWeight: 400, textTransform: 'none', letterSpacing: 0 }}>({groupTasks.length})</span></div>
              {groupTasks.map(renderTask)}
            </div>
          ))
        }
        return tasks.map(renderTask)
      })()}

      {showNew && (
        <NewTaskModal
          categories={categories}
          locations={locations}
          config={config}
          onClose={() => setShowNew(false)}
          onCreated={load}
        />
      )}
      {openTask !== null && (
        <TaskModal taskId={openTask} onClose={() => setOpenTask(null)} onChanged={load} />
      )}
    </div>
  )
}
