import { useEffect, useMemo, useState } from 'react'
import { Link } from 'react-router-dom'
import { ApiHttpError } from '../../api/http'
import { deleteRole, fetchAllRoles, type RoleRow } from '../../api/rolePermission'
import { ROLE_PERMISSION_BASE } from './rolePermissionPaths'

export function RoleListPage() {
  const [rows, setRows] = useState<RoleRow[]>([])
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [sortKey, setSortKey] = useState<'id' | 'name' | 'description' | 'user_count'>('name')
  const [sortDir, setSortDir] = useState<'asc' | 'desc'>('asc')
  const [page, setPage] = useState(1)
  const pageSize = 25

  function load() {
    setError(null)
    setLoading(true)
    fetchAllRoles()
      .then((d) => setRows(d.roles ?? []))
      .catch((e: unknown) =>
        setError(e instanceof ApiHttpError ? e.message : 'Unable to load roles.'),
      )
      .finally(() => setLoading(false))
  }

  useEffect(() => {
    load()
  }, [])

  async function onDelete(id: number | string) {
    if (!confirm('Are you sure you want to delete this role?')) return
    try {
      await deleteRole(id)
      load()
    } catch (e: unknown) {
      alert(e instanceof ApiHttpError ? e.message : 'Delete failed.')
    }
  }

  const sortedRows = useMemo(() => {
    const items = [...rows]
    const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' })

    const valueFor = (role: RoleRow): string => {
      switch (sortKey) {
        case 'id':
          return String(role.id ?? '')
        case 'description':
          return String(role.description ?? '')
        case 'user_count':
          return String(role.user_count ?? 0)
        case 'name':
        default:
          return String(role.name ?? '')
      }
    }

    items.sort((a, b) => {
      const result = collator.compare(valueFor(a), valueFor(b))
      return sortDir === 'asc' ? result : -result
    })

    return items
  }, [rows, sortDir, sortKey])

  const totalPages = Math.max(1, Math.ceil(sortedRows.length / pageSize))
  const currentPage = Math.min(page, totalPages)
  const pagedRows = useMemo(() => {
    const start = (currentPage - 1) * pageSize
    return sortedRows.slice(start, start + pageSize)
  }, [currentPage, sortedRows])

  function toggleSort(nextKey: 'id' | 'name' | 'description' | 'user_count') {
    if (sortKey === nextKey) {
      setSortDir((current) => (current === 'asc' ? 'desc' : 'asc'))
      setPage(1)
      return
    }
    setSortKey(nextKey)
    setSortDir('asc')
    setPage(1)
  }

  function sortIndicator(key: 'id' | 'name' | 'description' | 'user_count') {
    if (sortKey !== key) return ''
    return sortDir === 'asc' ? ' ▲' : ' ▼'
  }

  function renderSortableHeader(
    key: 'id' | 'name' | 'description' | 'user_count',
    label: string,
  ) {
    return (
      <button
        type="button"
        onClick={() => toggleSort(key)}
        style={{
          background: 'transparent',
          border: 0,
          color: 'inherit',
          font: 'inherit',
          fontWeight: 600,
          padding: 0,
          textAlign: 'left',
        }}
      >
        {label}
        {sortIndicator(key)}
      </button>
    )
  }

  return (
    <div className="container-fluid py-3">
      <h2 className="text-center mt-4 mb-3">List of Roles</h2>

      {error ? <div className="alert alert-danger">{error}</div> : null}

      <div className="mt-3 d-flex justify-content-end gap-2 flex-wrap">
        <Link to={`${ROLE_PERMISSION_BASE}/roles/create`} className="btn btn-success">
          Add New Role
        </Link>
        <Link to={`${ROLE_PERMISSION_BASE}/assign`} className="btn btn-info">
          Assign Role to User
        </Link>
      </div>

      <div className="table-responsive mt-3">
        <table className="table table-bordered table-striped align-middle">
          <thead className="table-dark">
            <tr>
              <th>{renderSortableHeader('id', 'Role ID')}</th>
              <th>{renderSortableHeader('name', 'Role Name')}</th>
              <th>{renderSortableHeader('description', 'Description')}</th>
              <th>{renderSortableHeader('user_count', 'Number of Users')}</th>
              <th>Actions</th>
            </tr>
          </thead>
          <tbody>
            {loading ? (
              <tr>
                <td colSpan={5} className="text-center text-muted py-4">
                  Loading roles…
                </td>
              </tr>
            ) : rows.length === 0 ? (
              <tr>
                <td colSpan={5} className="text-center text-muted py-4">
                  {error ? '—' : 'No roles found.'}
                </td>
              </tr>
            ) : (
              pagedRows.map((role) => (
                <tr key={String(role.id)}>
                  <td>{String(role.id ?? '')}</td>
                  <td>{String(role.name ?? '')}</td>
                  <td>{String(role.description ?? '')}</td>
                  <td>{Number(role.user_count ?? 0)}</td>
                  <td>
                    <Link
                      to={`${ROLE_PERMISSION_BASE}/roles/${role.id}/permissions`}
                      className="btn btn-sm btn-warning me-1"
                    >
                      Update Role Permissions
                    </Link>
                    <Link
                      to={`${ROLE_PERMISSION_BASE}/roles/${role.id}/edit`}
                      className="btn btn-sm btn-primary me-1"
                    >
                      Edit Role
                    </Link>
                    <button
                      type="button"
                      className="btn btn-sm btn-danger"
                      onClick={() => role.id != null && onDelete(role.id)}
                    >
                      Delete
                    </button>
                  </td>
                </tr>
              ))
            )}
          </tbody>
        </table>
      </div>

      {!loading && rows.length > 0 ? (
        <div className="d-flex flex-wrap justify-content-between align-items-center gap-2 mt-3">
          <div className="text-muted small">
            Showing {(currentPage - 1) * pageSize + 1}-{Math.min(currentPage * pageSize, sortedRows.length)} of{' '}
            {sortedRows.length} roles
          </div>
          <div className="btn-group" role="group" aria-label="Pagination">
            <button
              type="button"
              className="btn btn-outline-secondary btn-sm"
              disabled={currentPage <= 1}
              onClick={() => setPage(1)}
            >
              First
            </button>
            <button
              type="button"
              className="btn btn-outline-secondary btn-sm"
              disabled={currentPage <= 1}
              onClick={() => setPage((p) => Math.max(1, p - 1))}
            >
              Previous
            </button>
            <button type="button" className="btn btn-outline-secondary btn-sm" disabled>
              Page {currentPage} of {totalPages}
            </button>
            <button
              type="button"
              className="btn btn-outline-secondary btn-sm"
              disabled={currentPage >= totalPages}
              onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
            >
              Next
            </button>
            <button
              type="button"
              className="btn btn-outline-secondary btn-sm"
              disabled={currentPage >= totalPages}
              onClick={() => setPage(totalPages)}
            >
              Last
            </button>
          </div>
        </div>
      ) : null}
    </div>
  )
}
