import { useEffect, useState, type FormEvent } from 'react'
import {
  fetchAdministratorDashboardMetrics,
  searchAdministratorDashboard,
} from '../api/session'
import { useAuth } from '../auth/AuthProvider'
import type {
  AdministratorDashboardMetricsResponse,
  AdministratorDashboardSearchResponse,
} from '../api/types'

export function AppHome() {
  const { user } = useAuth()
  const [metrics, setMetrics] = useState<AdministratorDashboardMetricsResponse | null>(null)
  const [query, setQuery] = useState('')
  const [search, setSearch] = useState<AdministratorDashboardSearchResponse | null>(null)
  const [loadingMetrics, setLoadingMetrics] = useState(true)
  const [searching, setSearching] = useState(false)
  const [error, setError] = useState<string | null>(null)

  useEffect(() => {
    let cancelled = false
    ;(async () => {
      setLoadingMetrics(true)
      try {
        const data = await fetchAdministratorDashboardMetrics()
        if (!cancelled) {
          setMetrics(data)
          setError(null)
        }
      } catch (e) {
        if (!cancelled) {
          setError(e instanceof Error ? e.message : 'Unable to load dashboard.')
        }
      } finally {
        if (!cancelled) setLoadingMetrics(false)
      }
    })()
    return () => {
      cancelled = true
    }
  }, [])

  async function onSearch(event: FormEvent) {
    event.preventDefault()
    setSearching(true)
    setError(null)
    try {
      const results = await searchAdministratorDashboard(query)
      setSearch(results)
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Unable to search dashboard records.')
    } finally {
      setSearching(false)
    }
  }

  const counts = metrics?.counts ?? {}
  const statCards = [
    { key: 'students', title: 'Students', icon: 'bi bi-mortarboard', value: counts.students ?? 0, tone: 'primary' },
    { key: 'teachers', title: 'Teachers', icon: 'bi bi-person-video3', value: counts.teachers ?? 0, tone: 'success' },
    { key: 'teacherAssistants', title: 'Teacher Assistants', icon: 'bi bi-people', value: counts.teacherAssistants ?? 0, tone: 'warning' },
    { key: 'admins', title: 'Admins', icon: 'bi bi-person-badge', value: counts.admins ?? 0, tone: 'info' },
    { key: 'parents', title: 'Parents', icon: 'bi bi-people-fill', value: counts.parents ?? 0, tone: 'light' },
  ] as const

  return (
    <div className="container-fluid admin-dashboard">
      <section className="mb-4">
        <h2>Welcome, {user?.name || 'Administrator'}</h2>
        <p>Here is an overview of your site's activity.</p>
      </section>

      <section className="mb-5">
        <h2 className="mb-3">Search</h2>
        {error ? <div className="alert alert-danger">{error}</div> : null}

        <form className="mb-3" onSubmit={onSearch}>
          <div className="input-group">
            <input
              type="text"
              className="form-control"
              placeholder="Search name, email, phone, school ID, badge code..."
              value={query}
              onChange={(event) => setQuery(event.target.value)}
              required
            />
            <button className="btn btn-outline-secondary" type="submit" disabled={searching}>
              {searching ? 'Searching...' : 'Search'}
            </button>
          </div>
          <div className="form-text">Supports Users, Parents, Staff, Students, and Emergency Contacts.</div>
        </form>

        {search?.query ? (
          <div className="mb-2 small text-muted">
            Showing results for: <strong>{search.query}</strong>
          </div>
        ) : null}

        {search && (
          <div className="row g-3">
            <SearchTable title="Users" icon="bi bi-people" columns={['Name', 'Email', 'Phone', 'School ID']} rows={search.results.users ?? []} renderRow={(row) => [
              `${stringValue(row.firstname)} ${stringValue(row.lastname)}`.trim() || '—',
              stringValue(row.email),
              stringValue(row.cellphone),
              stringValue(row.school_id),
            ]} />
            <SearchTable title="Students" icon="bi bi-mortarboard" columns={['School ID', 'Name', 'Gender', 'DOB']} rows={search.results.students ?? []} renderRow={(row) => [
              stringValue(row.school_id),
              `${stringValue(row.firstname)} ${stringValue(row.lastname)}`.trim() || '—',
              stringValue(row.gender),
              stringValue(row.dob),
            ]} />
            <SearchTable title="Parents" icon="bi bi-people-fill" columns={['First Parent ID', 'Second Parent', 'Email', 'Phone']} rows={search.results.parents ?? []} renderRow={(row) => [
              stringValue(row.firstparent_id),
              `${stringValue(row.secondparent_firstname)} ${stringValue(row.secondparent_lastname)}`.trim() || '—',
              stringValue(row.secondparent_email),
              stringValue(row.secondparent_phone),
            ]} />
            <SearchTable title="Staff" icon="bi bi-person-badge" columns={['Role', 'Name', 'Email', 'Phone', 'Status']} rows={search.results.staff ?? []} renderRow={(row) => [
              stringValue(row.role_name),
              `${stringValue(row.firstname)} ${stringValue(row.lastname)}`.trim() || '—',
              stringValue(row.email),
              stringValue(row.phone),
              stringValue(row.active_role),
            ]} />
            <SearchTable title="Emergency Contacts" icon="bi bi-telephone-outbound" columns={['Name', 'Relation', 'Phone', 'Email']} rows={search.results.emergency_contacts ?? []} renderRow={(row) => [
              stringValue(row.emergency_contact_name),
              stringValue(row.relation),
              stringValue(row.cellphone),
              stringValue(row.email),
            ]} fullWidth />
          </div>
        )}
      </section>

      <section className="mb-5">
        <h2 className="mb-4 text-center">Statistics</h2>
        {loadingMetrics ? (
          <p className="text-muted text-center">Loading...</p>
        ) : (
          <div className="stats-row">
            {statCards.map((item) => (
              <div key={item.key} className={`stat-circle circle-${item.tone}`}>
                <div className="stat-icon"><i className={item.icon} aria-hidden /></div>
                <div className="stat-value">{item.value}</div>
                <div className="stat-title">{item.title}</div>
              </div>
            ))}
          </div>
        )}
      </section>

      <section>
        <h2 className="mb-3">Recent Activity</h2>
        <div className="card border-0 shadow-sm">
          <div className="card-body">
            {(metrics?.recentActivities ?? []).length === 0 ? (
              <p className="text-muted mb-0">No recent login activity.</p>
            ) : (
              <ul className="mb-0">
                {(metrics?.recentActivities ?? []).map((item, index) => (
                  <li key={`${item.email ?? 'activity'}-${index}`}>
                    {item.email ?? 'Unknown user'} <span className="text-muted">· {item.login_time ?? '—'}</span>
                  </li>
                ))}
              </ul>
            )}
          </div>
        </div>
      </section>
    </div>
  )
}

function SearchTable({
  title,
  icon,
  columns,
  rows,
  renderRow,
  fullWidth = false,
}: {
  title: string
  icon: string
  columns: string[]
  rows: Record<string, unknown>[]
  renderRow: (row: Record<string, unknown>) => string[]
  fullWidth?: boolean
}) {
  return (
    <div className={`col-12 ${fullWidth ? '' : 'col-lg-6'}`}>
      <div className="card">
        <div className="card-header"><i className={`${icon} me-1`} aria-hidden />{title}</div>
        <div className="card-body p-0">
          <div className="table-responsive">
            <table className="table table-sm mb-0">
              <thead>
                <tr>{columns.map((column) => <th key={column}>{column}</th>)}</tr>
              </thead>
              <tbody>
                {rows.length === 0 ? (
                  <tr><td colSpan={columns.length} className="text-muted">No {title.toLowerCase()} found.</td></tr>
                ) : (
                  rows.map((row, index) => (
                    <tr key={String(row.id ?? `${title}-${index}`)}>
                      {renderRow(row).map((cell, cellIndex) => <td key={`${index}-${cellIndex}`}>{cell || '—'}</td>)}
                    </tr>
                  ))
                )}
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
  )
}

function stringValue(value: unknown) {
  return value == null || value === '' ? '—' : String(value)
}
