import { h } from 'preact'
import { useCallback, useEffect, useState } from 'preact/hooks'
import { route } from 'preact-router'
import rek, { type FetchError } from 'rek'

import { useNotifications } from '../contexts/notifications.tsx'
import useItemsReducer from '../hooks/use_items_reducer.ts'
import RoleForm from './role_form.tsx'
import Modal from './modal.tsx'
import RolesTable from './roles_table.tsx'
import PageHeader from './page_header.tsx'
import Section from './section.tsx'

import type { Role } from '../../../server/services/roles/types.ts'

const RolesPage = () => {
  const { notify } = useNotifications()
  const [roles, actions] = useItemsReducer<Role>()
  const [edit, setEdit] = useState<Role | null | undefined>(null)

  useEffect(() => {
    rek('/api/roles' + location.search).then(actions.reset)
  }, [location.search])

  const onDelete = useCallback(async (id: number) => {
    if (confirm(`Delete role ${id}?`)) {
      try {
        await rek.delete(`/api/roles/${id}`)

        actions.del(id)

        notify.success(`Role ${id} deleted`)
      } catch (err) {
        notify.error((err as FetchError).body?.message || (err as FetchError).toString())
      }
    }
  }, [])

  const onEdit = useCallback(
    async (id: number) => {
      setEdit(id ? roles.find((role) => role.id === id) : null)
    },
    [roles],
  )

  const onSortBy = useCallback((column: string | null) => {
    const searchParams = new URLSearchParams(location.search)

    const newSort = (searchParams.get('sort') || 'id') === column ? '-' + column : column

    route(location.pathname + (newSort !== 'id' ? `?sort=${newSort}` : ''))
  }, [])

  return (
    <section>
      <PageHeader>Roles</PageHeader>

      <Section maxWidth='50%'>
        <Section.Heading>Create New Role</Section.Heading>

        <Section.Body>
          <RoleForm onCreate={actions.add} />
        </Section.Body>
      </Section>

      <Section>
        <Section.Heading>List</Section.Heading>

        <Section.Body noPadding>
          <RolesTable roles={roles} onDelete={onDelete} onEdit={onEdit} onSortBy={onSortBy} />
        </Section.Body>
      </Section>

      {edit != null && (
        <Modal onClose={() => setEdit(null)}>
          <RoleForm
            onCancel={() => setEdit(null)}
            onUpdate={(role: ANY) => actions.update(role.id, role)}
            role={edit}
          />
        </Modal>
      )}
    </section>
  )
}

export default RolesPage
