'use client'

import { useEffect, useState } from 'react'
import { useRouter } from 'next/navigation'
import { authFetch, clearToken, getApiBase, getToken } from '../lib/auth'

type PortalPermissions = {
  can_edit?: boolean
  can_comment?: boolean
  can_moderate?: boolean
}

type PortalItem = {
  id: number
  kind: 'request' | 'issue' | 'feature'
  title: string
  description: string
  media_type?: 'movie' | 'tv' | null
  year?: number | null
  external_ref?: string | null
  source_system?: string | null
  source_request_id?: number | null
  status: string
  priority: string
  created_by_username: string
  assignee_username?: string | null
  created_at: string
  updated_at: string
  last_activity_at: string
  permissions?: PortalPermissions
  workflow?: {
    request_status?: string
    media_status?: string
    stage_label?: string
    is_terminal?: boolean
  }
  issue?: {
    issue_type?: string
    related_item_id?: number | null
    is_resolved?: boolean
    resolved_at?: string | null
  }
}

type PortalComment = {
  id: number
  item_id: number
  author_username: string
  author_role: string
  message: string
  is_internal: boolean
  created_at: string
}

type PortalOverview = {
  overview?: {
    total_items?: number
    total_comments?: number
    by_kind?: Record<string, number>
    by_status?: Record<string, number>
  }
  my_items?: number
}

type UserProfile = {
  username: string
  role: string
}

type DiscoveryResult = {
  title: string
  year?: number | null
  type?: 'movie' | 'tv' | null
  tmdbId?: number | null
  requestId?: number | null
  statusLabel?: string | null
  status?: number | null
  accessible?: boolean
  posterPath?: string | null
  backdropPath?: string | null
}

const KIND_OPTIONS = [
  { value: 'request', label: 'Request' },
  { value: 'issue', label: 'Issue' },
  { value: 'feature', label: 'Feature' },
] as const

const STATUS_OPTIONS = [
  { value: 'new', label: 'New' },
  { value: 'triaging', label: 'Triaging' },
  { value: 'planned', label: 'Planned' },
  { value: 'in_progress', label: 'In progress' },
  { value: 'blocked', label: 'Blocked' },
  { value: 'done', label: 'Done' },
  { value: 'pending', label: 'Pending approval' },
  { value: 'approved', label: 'Approved' },
  { value: 'processing', label: 'Processing' },
  { value: 'partially_available', label: 'Partially available' },
  { value: 'available', label: 'Available' },
  { value: 'failed', label: 'Failed' },
  { value: 'declined', label: 'Declined' },
  { value: 'closed', label: 'Closed' },
] as const

const REQUEST_STATUS_OPTIONS = [
  { value: 'pending', label: 'Pending approval' },
  { value: 'approved', label: 'Approved' },
  { value: 'declined', label: 'Declined' },
] as const

const MEDIA_STATUS_OPTIONS = [
  { value: 'pending', label: 'Pending' },
  { value: 'processing', label: 'Processing' },
  { value: 'partially_available', label: 'Partially available' },
  { value: 'available', label: 'Available' },
  { value: 'failed', label: 'Failed' },
  { value: 'unknown', label: 'Unknown' },
] as const

const PRIORITY_OPTIONS = [
  { value: 'low', label: 'Low' },
  { value: 'normal', label: 'Normal' },
  { value: 'high', label: 'High' },
  { value: 'urgent', label: 'Urgent' },
] as const

const MEDIA_TYPE_OPTIONS = [
  { value: '', label: 'None' },
  { value: 'movie', label: 'Movie' },
  { value: 'tv', label: 'TV' },
] as const

const formatDate = (value?: string | null) => {
  if (!value) return 'Never'
  const parsed = new Date(value)
  if (Number.isNaN(parsed.valueOf())) return value
  return parsed.toLocaleString()
}

const toPositiveInt = (value: string) => {
  const parsed = Number.parseInt(value, 10)
  if (Number.isNaN(parsed) || parsed <= 0) return null
  return parsed
}

export default function PortalPage() {
  const router = useRouter()
  const [me, setMe] = useState<UserProfile | null>(null)
  const [overview, setOverview] = useState<PortalOverview | null>(null)
  const [items, setItems] = useState<PortalItem[]>([])
  const [selectedItemId, setSelectedItemId] = useState<number | null>(null)
  const [selectedItem, setSelectedItem] = useState<PortalItem | null>(null)
  const [comments, setComments] = useState<PortalComment[]>([])
  const [loadingItems, setLoadingItems] = useState(true)
  const [loadingItem, setLoadingItem] = useState(false)
  const [creating, setCreating] = useState(false)
  const [saving, setSaving] = useState(false)
  const [commenting, setCommenting] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [status, setStatus] = useState<string | null>(null)
  const [totalItems, setTotalItems] = useState(0)
  const [hasMore, setHasMore] = useState(false)

  const [filterKind, setFilterKind] = useState('')
  const [filterStatus, setFilterStatus] = useState('')
  const [filterMine, setFilterMine] = useState(false)
  const [filterSearch, setFilterSearch] = useState('')

  const [createKind, setCreateKind] = useState<'request' | 'issue' | 'feature'>('request')
  const [createTitle, setCreateTitle] = useState('')
  const [createDescription, setCreateDescription] = useState('')
  const [createMediaType, setCreateMediaType] = useState('')
  const [createYear, setCreateYear] = useState('')
  const [createExternalRef, setCreateExternalRef] = useState('')
  const [createPriority, setCreatePriority] = useState<'low' | 'normal' | 'high' | 'urgent'>('normal')

  const [editTitle, setEditTitle] = useState('')
  const [editDescription, setEditDescription] = useState('')
  const [editMediaType, setEditMediaType] = useState('')
  const [editYear, setEditYear] = useState('')
  const [editExternalRef, setEditExternalRef] = useState('')
  const [editStatus, setEditStatus] = useState('new')
  const [editRequestStatus, setEditRequestStatus] = useState('pending')
  const [editMediaStatus, setEditMediaStatus] = useState('pending')
  const [editPriority, setEditPriority] = useState('normal')
  const [editAssignee, setEditAssignee] = useState('')

  const [commentText, setCommentText] = useState('')
  const [commentInternal, setCommentInternal] = useState(false)
  const [preselectedItemId, setPreselectedItemId] = useState<number | null>(null)
  const [discoverQuery, setDiscoverQuery] = useState('')
  const [discoverLoading, setDiscoverLoading] = useState(false)
  const [discoverResults, setDiscoverResults] = useState<DiscoveryResult[]>([])
  const [discoverError, setDiscoverError] = useState<string | null>(null)
  const [requestingTmdbIds, setRequestingTmdbIds] = useState<Record<string, boolean>>({})

  const isAdmin = me?.role === 'admin'

  useEffect(() => {
    if (typeof window === 'undefined') return
    const raw = new URLSearchParams(window.location.search).get('item')
    if (!raw) {
      setPreselectedItemId(null)
      return
    }
    const parsed = Number.parseInt(raw, 10)
    setPreselectedItemId(Number.isNaN(parsed) || parsed <= 0 ? null : parsed)
  }, [])

  const loadMe = async () => {
    const baseUrl = getApiBase()
    const response = await authFetch(`${baseUrl}/auth/me`)
    if (!response.ok) {
      if (response.status === 401) {
        clearToken()
        router.push('/login')
        return null
      }
      throw new Error(`Failed to load session (${response.status})`)
    }
    const data = await response.json()
    const profile: UserProfile = {
      username: data?.username ?? 'unknown',
      role: data?.role ?? 'user',
    }
    setMe(profile)
    return profile
  }

  const loadOverview = async () => {
    try {
      const baseUrl = getApiBase()
      const response = await authFetch(`${baseUrl}/portal/overview`)
      if (!response.ok) {
        if (response.status === 401) {
          clearToken()
          router.push('/login')
          return
        }
        throw new Error(`Failed to load portal overview (${response.status})`)
      }
      const data = await response.json()
      setOverview(data)
    } catch (err) {
      console.error(err)
    }
  }

  const loadItem = async (itemId: number) => {
    setLoadingItem(true)
    try {
      const baseUrl = getApiBase()
      const response = await authFetch(`${baseUrl}/portal/items/${itemId}`)
      if (!response.ok) {
        if (response.status === 401) {
          clearToken()
          router.push('/login')
          return
        }
        if (response.status === 404) {
          setSelectedItem(null)
          setComments([])
          return
        }
        throw new Error(`Failed to load portal item (${response.status})`)
      }
      const data = await response.json()
      const item = (data?.item ?? null) as PortalItem | null
      setSelectedItem(item)
      setComments(Array.isArray(data?.comments) ? data.comments : [])
    } catch (err) {
      console.error(err)
      setError('Could not load portal item details.')
    } finally {
      setLoadingItem(false)
    }
  }

  const loadItems = async (options?: { preferItemId?: number | null }) => {
    setLoadingItems(true)
    try {
      const baseUrl = getApiBase()
      const params = new URLSearchParams({
        limit: '60',
        offset: '0',
      })
      if (filterKind) params.set('kind', filterKind)
      if (filterStatus) params.set('status', filterStatus)
      if (filterMine) params.set('mine', '1')
      const trimmedSearch = filterSearch.trim()
      if (trimmedSearch) params.set('search', trimmedSearch)

      const response = await authFetch(`${baseUrl}/portal/items?${params.toString()}`)
      if (!response.ok) {
        if (response.status === 401) {
          clearToken()
          router.push('/login')
          return
        }
        throw new Error(`Failed to load portal items (${response.status})`)
      }
      const data = await response.json()
      const loadedItems = Array.isArray(data?.items) ? (data.items as PortalItem[]) : []
      setItems(loadedItems)
      setTotalItems(Number(data?.total ?? loadedItems.length ?? 0))
      setHasMore(Boolean(data?.has_more))

      const preferred = options?.preferItemId ?? selectedItemId ?? preselectedItemId
      if (preferred && loadedItems.some((item) => item.id === preferred)) {
        setSelectedItemId(preferred)
      } else if (loadedItems.length > 0) {
        setSelectedItemId(loadedItems[0].id)
      } else {
        setSelectedItemId(null)
        setSelectedItem(null)
        setComments([])
      }
    } catch (err) {
      console.error(err)
      setError('Could not load portal items.')
    } finally {
      setLoadingItems(false)
    }
  }

  const resolveTmdbArtworkUrl = (path?: string | null, size: 'w185' | 'w342' = 'w185') => {
    if (!path) return null
    const normalized = path.startsWith('/') ? path : `/${path}`
    return `https://image.tmdb.org/t/p/${size}${normalized}`
  }

  const runDiscoverySearch = async (event?: React.FormEvent) => {
    if (event) event.preventDefault()
    const query = discoverQuery.trim()
    if (!query) {
      setDiscoverResults([])
      setDiscoverError('Enter a title to search.')
      return
    }
    setDiscoverLoading(true)
    setDiscoverError(null)
    try {
      const baseUrl = getApiBase()
      const response = await authFetch(`${baseUrl}/requests/search?query=${encodeURIComponent(query)}`)
      if (!response.ok) {
        if (response.status === 401) {
          clearToken()
          router.push('/login')
          return
        }
        const text = await response.text()
        throw new Error(text || `Search failed (${response.status})`)
      }
      const data = await response.json()
      const mapped: DiscoveryResult[] = Array.isArray(data?.results)
        ? data.results.map((item: any) => ({
            title: item?.title ?? 'Untitled',
            year: typeof item?.year === 'number' ? item.year : null,
            type: item?.type === 'movie' || item?.type === 'tv' ? item.type : null,
            tmdbId: typeof item?.tmdbId === 'number' ? item.tmdbId : null,
            requestId: typeof item?.requestId === 'number' ? item.requestId : null,
            statusLabel: item?.statusLabel ?? null,
            status: typeof item?.status === 'number' ? item.status : null,
            accessible: Boolean(item?.accessible),
            posterPath: item?.posterPath ?? null,
            backdropPath: item?.backdropPath ?? null,
          }))
        : []
      setDiscoverResults(mapped)
    } catch (err) {
      console.error(err)
      setDiscoverResults([])
      setDiscoverError(err instanceof Error ? err.message : 'Search failed.')
    } finally {
      setDiscoverLoading(false)
    }
  }

  const requestDiscoveryItem = async (item: DiscoveryResult) => {
    if (!item.tmdbId || !item.type) {
      setError('Could not request this result because required media details are missing.')
      return
    }
    const key = `${item.type}:${item.tmdbId}`
    setRequestingTmdbIds((prev) => ({ ...prev, [key]: true }))
    setError(null)
    setStatus(null)
    try {
      const baseUrl = getApiBase()
      const response = await authFetch(`${baseUrl}/requests/create`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          mediaType: item.type,
          tmdbId: item.tmdbId,
        }),
      })
      if (!response.ok) {
        if (response.status === 401) {
          clearToken()
          router.push('/login')
          return
        }
        const text = await response.text()
        throw new Error(text || `Request failed (${response.status})`)
      }
      const data = await response.json()
      const requestId = typeof data?.requestId === 'number' ? data.requestId : null
      const statusLabel = typeof data?.statusLabel === 'string' ? data.statusLabel : item.statusLabel
      const statusCode = typeof data?.statusCode === 'number' ? data.statusCode : item.status
      setDiscoverResults((prev) =>
        prev.map((entry) =>
          entry.tmdbId === item.tmdbId && entry.type === item.type
            ? {
                ...entry,
                requestId,
                statusLabel,
                status: statusCode,
                accessible: true,
              }
            : entry
        )
      )
      if (requestId) {
        const mode = data?.status === 'exists' ? 'already exists' : 'created'
        setStatus(`Request ${mode}. Open request #${requestId} for the full pipeline.`)
      } else {
        setStatus('Request submitted.')
      }
      await Promise.all([loadItems(), loadOverview()])
    } catch (err) {
      console.error(err)
      setError(err instanceof Error ? err.message : 'Could not create request.')
    } finally {
      setRequestingTmdbIds((prev) => {
        const next = { ...prev }
        delete next[key]
        return next
      })
    }
  }

  useEffect(() => {
    if (!getToken()) {
      router.push('/login')
      return
    }
    const bootstrap = async () => {
      try {
        setError(null)
        await loadMe()
        await Promise.all([loadOverview(), loadItems({ preferItemId: preselectedItemId })])
      } catch (err) {
        console.error(err)
        setError('Could not load request portal.')
      }
    }
    void bootstrap()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [router])

  useEffect(() => {
    if (!getToken()) {
      return
    }
    void loadItems({ preferItemId: preselectedItemId })
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [filterKind, filterStatus, filterMine, filterSearch])

  useEffect(() => {
    if (selectedItemId == null) return
    void loadItem(selectedItemId)
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [selectedItemId])

  useEffect(() => {
    if (!selectedItem) return
    setEditTitle(selectedItem.title ?? '')
    setEditDescription(selectedItem.description ?? '')
    setEditMediaType(selectedItem.media_type ?? '')
    setEditYear(selectedItem.year == null ? '' : String(selectedItem.year))
    setEditExternalRef(selectedItem.external_ref ?? '')
    setEditStatus(selectedItem.status ?? 'new')
    setEditRequestStatus(selectedItem.workflow?.request_status ?? 'pending')
    setEditMediaStatus(selectedItem.workflow?.media_status ?? 'pending')
    setEditPriority(selectedItem.priority ?? 'normal')
    setEditAssignee(selectedItem.assignee_username ?? '')
  }, [selectedItem])

  const createItem = async (event: React.FormEvent) => {
    event.preventDefault()
    setCreating(true)
    setError(null)
    setStatus(null)
    try {
      const payload: Record<string, any> = {
        kind: createKind,
        title: createTitle,
        description: createDescription,
        media_type: createMediaType || null,
        year: createYear.trim() ? toPositiveInt(createYear) : null,
        external_ref: createExternalRef || null,
        priority: createPriority,
      }
      const baseUrl = getApiBase()
      const response = await authFetch(`${baseUrl}/portal/items`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      })
      if (!response.ok) {
        if (response.status === 401) {
          clearToken()
          router.push('/login')
          return
        }
        const text = await response.text()
        throw new Error(text || 'Could not create portal item.')
      }
      const data = await response.json()
      const item = data?.item as PortalItem | undefined
      setStatus('Portal item created.')
      setCreateTitle('')
      setCreateDescription('')
      setCreateMediaType('')
      setCreateYear('')
      setCreateExternalRef('')
      setCreatePriority('normal')
      await Promise.all([
        loadItems({ preferItemId: item?.id ?? null }),
        loadOverview(),
      ])
    } catch (err) {
      console.error(err)
      setError(err instanceof Error ? err.message : 'Could not create portal item.')
    } finally {
      setCreating(false)
    }
  }

  const saveItem = async (event: React.FormEvent) => {
    event.preventDefault()
    if (!selectedItem) return
    setSaving(true)
    setError(null)
    setStatus(null)
    try {
      const payload: Record<string, any> = {
        title: editTitle,
        description: editDescription,
        media_type: editMediaType || null,
        year: editYear.trim() ? toPositiveInt(editYear) : null,
        external_ref: editExternalRef || null,
      }
      if (selectedItem.permissions?.can_moderate) {
        if (selectedItem.kind === 'request') {
          payload.request_status = editRequestStatus
          payload.media_status = editMediaStatus
        } else {
          payload.status = editStatus
        }
        payload.priority = editPriority
        payload.assignee_username = editAssignee || null
      }
      const baseUrl = getApiBase()
      const response = await authFetch(`${baseUrl}/portal/items/${selectedItem.id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      })
      if (!response.ok) {
        if (response.status === 401) {
          clearToken()
          router.push('/login')
          return
        }
        const text = await response.text()
        throw new Error(text || 'Could not update portal item.')
      }
      const data = await response.json()
      setSelectedItem((data?.item ?? null) as PortalItem | null)
      setComments(Array.isArray(data?.comments) ? data.comments : [])
      setStatus('Portal item updated.')
      await Promise.all([
        loadItems({ preferItemId: selectedItem.id }),
        loadOverview(),
      ])
    } catch (err) {
      console.error(err)
      setError(err instanceof Error ? err.message : 'Could not update portal item.')
    } finally {
      setSaving(false)
    }
  }

  const postComment = async (event: React.FormEvent) => {
    event.preventDefault()
    if (!selectedItem) return
    if (!commentText.trim()) {
      setError('Comment message is required.')
      return
    }
    setCommenting(true)
    setError(null)
    setStatus(null)
    try {
      const baseUrl = getApiBase()
      const response = await authFetch(`${baseUrl}/portal/items/${selectedItem.id}/comments`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          message: commentText,
          is_internal: commentInternal,
        }),
      })
      if (!response.ok) {
        if (response.status === 401) {
          clearToken()
          router.push('/login')
          return
        }
        const text = await response.text()
        throw new Error(text || 'Could not add comment.')
      }
      setCommentText('')
      setCommentInternal(false)
      setStatus('Comment added.')
      await Promise.all([
        loadItem(selectedItem.id),
        loadItems({ preferItemId: selectedItem.id }),
        loadOverview(),
      ])
    } catch (err) {
      console.error(err)
      setError(err instanceof Error ? err.message : 'Could not add comment.')
    } finally {
      setCommenting(false)
    }
  }

  if (loadingItems && !items.length) {
    return <main className="card">Loading request portal...</main>
  }

  return (
    <main className="card portal-page">
      <div className="user-directory-panel-header">
        <div>
          <h1>Request portal</h1>
          <p className="lede">
            Raise requests, issues, and feature ideas. Track progress and keep discussion in one place.
          </p>
        </div>
      </div>

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

      <section className="admin-panel portal-discovery-panel">
        <div className="user-directory-panel-header">
          <div>
            <h2>Search and request content</h2>
            <p className="lede">
              Search Seerr content directly, then submit a request in one click.
            </p>
          </div>
        </div>
        <form className="portal-discovery-form" onSubmit={runDiscoverySearch}>
          <input
            value={discoverQuery}
            onChange={(event) => setDiscoverQuery(event.target.value)}
            placeholder="Search movies or TV shows"
          />
          <button type="submit" disabled={discoverLoading}>
            {discoverLoading ? 'Searching…' : 'Search'}
          </button>
        </form>
        {discoverError && <div className="error-banner">{discoverError}</div>}
        <div className="portal-discovery-results">
          {discoverLoading ? (
            <div className="status-banner">Searching Seerr…</div>
          ) : discoverResults.length === 0 ? (
            <div className="status-banner">No discovery results yet.</div>
          ) : (
            discoverResults.map((item, index) => {
              const key = `${item.type ?? 'unknown'}:${item.tmdbId ?? index}`
              const requesting = Boolean(requestingTmdbIds[key])
              const poster = resolveTmdbArtworkUrl(item.posterPath, 'w185')
              const hasRequest = typeof item.requestId === 'number' && item.requestId > 0
              return (
                <div key={key} className="portal-discovery-item">
                  <div className="portal-discovery-media">
                    {poster ? <img src={poster} alt="" loading="lazy" /> : <div className="poster-fallback">No artwork</div>}
                  </div>
                  <div className="portal-discovery-main">
                    <div className="portal-discovery-title-row">
                      <strong>{item.title || 'Untitled'}</strong>
                      <span className="small-pill">{item.type ?? 'unknown'}</span>
                      {item.year ? <span className="small-pill is-muted">{item.year}</span> : null}
                    </div>
                    <p>
                      {hasRequest ? (
                        <>
                          Already requested
                          {item.statusLabel ? ` · ${item.statusLabel}` : ''}
                          {item.requestId ? ` · #${item.requestId}` : ''}
                        </>
                      ) : (
                        'Not requested yet'
                      )}
                    </p>
                  </div>
                  <div className="portal-discovery-actions">
                    {hasRequest ? (
                      <button
                        type="button"
                        onClick={() => router.push(`/requests/${item.requestId}`)}
                      >
                        Open request
                      </button>
                    ) : (
                      <button
                        type="button"
                        onClick={() => void requestDiscoveryItem(item)}
                        disabled={requesting || !item.tmdbId || !item.type}
                      >
                        {requesting ? 'Requesting…' : 'Request'}
                      </button>
                    )}
                  </div>
                </div>
              )
            })
          )}
        </div>
      </section>

      <section className="portal-overview-grid">
        <div className="portal-overview-card">
          <span>Total items</span>
          <strong>{Number(overview?.overview?.total_items ?? totalItems ?? 0)}</strong>
        </div>
        <div className="portal-overview-card">
          <span>Total comments</span>
          <strong>{Number(overview?.overview?.total_comments ?? 0)}</strong>
        </div>
        <div className="portal-overview-card">
          <span>My items</span>
          <strong>{Number(overview?.my_items ?? 0)}</strong>
        </div>
        <div className="portal-overview-card">
          <span>Visible</span>
          <strong>{items.length}</strong>
        </div>
      </section>

      <section className="admin-panel portal-create-panel">
        <h2>Create item</h2>
        <p className="lede">
          Use <strong>Request</strong> for new content, <strong>Issue</strong> for broken behavior, and <strong>Feature</strong> for improvements.
        </p>
        <form onSubmit={createItem} className="admin-form compact-form portal-form-grid">
          <label>
            <span>Type</span>
            <select
              value={createKind}
              onChange={(event) =>
                setCreateKind(event.target.value as 'request' | 'issue' | 'feature')
              }
            >
              {KIND_OPTIONS.map((option) => (
                <option key={option.value} value={option.value}>
                  {option.label}
                </option>
              ))}
            </select>
          </label>
          <label>
            <span>Priority</span>
            <select
              value={createPriority}
              onChange={(event) =>
                setCreatePriority(event.target.value as 'low' | 'normal' | 'high' | 'urgent')
              }
            >
              {PRIORITY_OPTIONS.map((option) => (
                <option key={option.value} value={option.value}>
                  {option.label}
                </option>
              ))}
            </select>
          </label>
          <label className="portal-field-span-2">
            <span>Title</span>
            <input
              required
              value={createTitle}
              onChange={(event) => setCreateTitle(event.target.value)}
              placeholder="Short summary of the request or issue"
            />
          </label>
          <label className="portal-field-span-2">
            <span>Description</span>
            <textarea
              required
              rows={4}
              value={createDescription}
              onChange={(event) => setCreateDescription(event.target.value)}
              placeholder="Add details, expected behavior, and any context."
            />
          </label>
          <label>
            <span>Media type</span>
            <select value={createMediaType} onChange={(event) => setCreateMediaType(event.target.value)}>
              {MEDIA_TYPE_OPTIONS.map((option) => (
                <option key={option.value || 'none'} value={option.value}>
                  {option.label}
                </option>
              ))}
            </select>
          </label>
          <label>
            <span>Year</span>
            <input
              value={createYear}
              onChange={(event) => setCreateYear(event.target.value)}
              inputMode="numeric"
              placeholder="Optional"
            />
          </label>
          <label className="portal-field-span-2">
            <span>External reference</span>
            <input
              value={createExternalRef}
              onChange={(event) => setCreateExternalRef(event.target.value)}
              placeholder="Optional: URL, ticket number, or request id"
            />
          </label>
          <div className="admin-inline-actions portal-field-span-2">
            <button type="submit" disabled={creating}>
              {creating ? 'Creating…' : 'Create portal item'}
            </button>
          </div>
        </form>
      </section>

      <section className="portal-toolbar">
        <label>
          <span>Type</span>
          <select value={filterKind} onChange={(event) => setFilterKind(event.target.value)}>
            <option value="">All</option>
            {KIND_OPTIONS.map((option) => (
              <option key={option.value} value={option.value}>
                {option.label}
              </option>
            ))}
          </select>
        </label>
        <label>
          <span>Status</span>
          <select value={filterStatus} onChange={(event) => setFilterStatus(event.target.value)}>
            <option value="">All</option>
            {STATUS_OPTIONS.map((option) => (
              <option key={option.value} value={option.value}>
                {option.label}
              </option>
            ))}
          </select>
        </label>
        <label className="portal-search-filter">
          <span>Search</span>
          <input
            value={filterSearch}
            onChange={(event) => setFilterSearch(event.target.value)}
            placeholder="Title, description, or item id"
          />
        </label>
        <label className="inline-checkbox portal-mine-toggle">
          <input
            type="checkbox"
            checked={filterMine}
            onChange={(event) => setFilterMine(event.target.checked)}
          />
          My items only
        </label>
      </section>

      <div className="portal-workspace">
        <section className="admin-panel portal-list-panel">
          <div className="user-directory-panel-header">
            <div>
              <h2>Items</h2>
              <p className="lede">
                {totalItems} total
                {hasMore ? ' (showing first 60)' : ''}
              </p>
            </div>
          </div>
          {items.length === 0 ? (
            <div className="status-banner">No portal items match this filter.</div>
          ) : (
            <div className="portal-item-list">
              {items.map((item) => (
                <button
                  key={item.id}
                  type="button"
                  className={`portal-item-row ${selectedItemId === item.id ? 'is-active' : ''}`}
                  onClick={() => setSelectedItemId(item.id)}
                >
                  <div className="portal-item-row-main">
                    <div className="portal-item-row-title">
                      <strong>{item.title}</strong>
                      <span className="small-pill">{item.kind}</span>
                      <span className="small-pill is-muted">{item.priority}</span>
                    </div>
                    <p>{item.description}</p>
                    <div className="portal-item-row-meta">
                      <span>#{item.id}</span>
                      <span>
                        Status:{' '}
                        {item.kind === 'request'
                          ? item.workflow?.stage_label ?? item.status
                          : item.status}
                      </span>
                      <span>By: {item.created_by_username}</span>
                      <span>Updated: {formatDate(item.last_activity_at)}</span>
                    </div>
                  </div>
                </button>
              ))}
            </div>
          )}
        </section>

        <section className="admin-panel portal-detail-panel">
          {!selectedItemId ? (
            <div className="status-banner">Select an item to view details.</div>
          ) : loadingItem ? (
            <div className="status-banner">Loading details…</div>
          ) : !selectedItem ? (
            <div className="status-banner">Item not found.</div>
          ) : (
            <>
              <div className="user-directory-panel-header">
                <div>
                  <h2>Item #{selectedItem.id}</h2>
                  <p className="lede">
                    Created by {selectedItem.created_by_username} on {formatDate(selectedItem.created_at)}
                  </p>
                  {selectedItem.kind === 'request' && (
                    <p className="lede">
                      Pipeline:{' '}
                      <strong>
                        {selectedItem.workflow?.request_status ?? 'pending'} /{' '}
                        {selectedItem.workflow?.media_status ?? 'pending'}
                      </strong>{' '}
                      ({selectedItem.workflow?.stage_label ?? 'Pending'})
                    </p>
                  )}
                </div>
              </div>

              <form className="admin-form compact-form portal-form-grid" onSubmit={saveItem}>
                <label className="portal-field-span-2">
                  <span>Title</span>
                  <input
                    value={editTitle}
                    onChange={(event) => setEditTitle(event.target.value)}
                    disabled={!selectedItem.permissions?.can_edit}
                  />
                </label>
                <label className="portal-field-span-2">
                  <span>Description</span>
                  <textarea
                    rows={4}
                    value={editDescription}
                    onChange={(event) => setEditDescription(event.target.value)}
                    disabled={!selectedItem.permissions?.can_edit}
                  />
                </label>
                <label>
                  <span>Media type</span>
                  <select
                    value={editMediaType}
                    onChange={(event) => setEditMediaType(event.target.value)}
                    disabled={!selectedItem.permissions?.can_edit}
                  >
                    {MEDIA_TYPE_OPTIONS.map((option) => (
                      <option key={option.value || 'none'} value={option.value}>
                        {option.label}
                      </option>
                    ))}
                  </select>
                </label>
                <label>
                  <span>Year</span>
                  <input
                    value={editYear}
                    onChange={(event) => setEditYear(event.target.value)}
                    inputMode="numeric"
                    disabled={!selectedItem.permissions?.can_edit}
                  />
                </label>
                <label className="portal-field-span-2">
                  <span>External reference</span>
                  <input
                    value={editExternalRef}
                    onChange={(event) => setEditExternalRef(event.target.value)}
                    disabled={!selectedItem.permissions?.can_edit}
                  />
                </label>
                {selectedItem.permissions?.can_moderate && (
                  <>
                    {selectedItem.kind === 'request' ? (
                      <>
                        <label>
                          <span>Request status</span>
                          <select
                            value={editRequestStatus}
                            onChange={(event) => setEditRequestStatus(event.target.value)}
                          >
                            {REQUEST_STATUS_OPTIONS.map((option) => (
                              <option key={option.value} value={option.value}>
                                {option.label}
                              </option>
                            ))}
                          </select>
                        </label>
                        <label>
                          <span>Media status</span>
                          <select
                            value={editMediaStatus}
                            onChange={(event) => setEditMediaStatus(event.target.value)}
                          >
                            {MEDIA_STATUS_OPTIONS.map((option) => (
                              <option key={option.value} value={option.value}>
                                {option.label}
                              </option>
                            ))}
                          </select>
                        </label>
                      </>
                    ) : (
                      <label>
                        <span>Status</span>
                        <select value={editStatus} onChange={(event) => setEditStatus(event.target.value)}>
                          {STATUS_OPTIONS.map((option) => (
                            <option key={option.value} value={option.value}>
                              {option.label}
                            </option>
                          ))}
                        </select>
                      </label>
                    )}
                    <label>
                      <span>Priority</span>
                      <select
                        value={editPriority}
                        onChange={(event) => setEditPriority(event.target.value)}
                      >
                        {PRIORITY_OPTIONS.map((option) => (
                          <option key={option.value} value={option.value}>
                            {option.label}
                          </option>
                        ))}
                      </select>
                    </label>
                    <label className="portal-field-span-2">
                      <span>Assignee username</span>
                      <input
                        value={editAssignee}
                        onChange={(event) => setEditAssignee(event.target.value)}
                        placeholder="Optional assignee"
                      />
                    </label>
                  </>
                )}
                <div className="admin-inline-actions portal-field-span-2">
                  <button
                    type="submit"
                    disabled={saving || !selectedItem.permissions?.can_edit}
                  >
                    {saving ? 'Saving…' : 'Save changes'}
                  </button>
                </div>
              </form>

              <div className="portal-comments-block">
                <h3>Comments</h3>
                {comments.length === 0 ? (
                  <div className="status-banner">No comments yet.</div>
                ) : (
                  <div className="portal-comment-list">
                    {comments.map((comment) => (
                      <article key={comment.id} className="portal-comment-card">
                        <header>
                          <strong>{comment.author_username}</strong>
                          <span className="small-pill">{comment.author_role}</span>
                          {comment.is_internal && <span className="small-pill is-muted">internal</span>}
                          <span>{formatDate(comment.created_at)}</span>
                        </header>
                        <p>{comment.message}</p>
                      </article>
                    ))}
                  </div>
                )}
                <form onSubmit={postComment} className="admin-form compact-form portal-comment-form">
                  <label>
                    <span>Add comment</span>
                    <textarea
                      rows={3}
                      value={commentText}
                      onChange={(event) => setCommentText(event.target.value)}
                      placeholder="Add an update, troubleshooting note, or next step."
                    />
                  </label>
                  {isAdmin && (
                    <label className="inline-checkbox">
                      <input
                        type="checkbox"
                        checked={commentInternal}
                        onChange={(event) => setCommentInternal(event.target.checked)}
                      />
                      Internal comment (admin only)
                    </label>
                  )}
                  <div className="admin-inline-actions">
                    <button type="submit" disabled={commenting}>
                      {commenting ? 'Posting…' : 'Post comment'}
                    </button>
                  </div>
                </form>
              </div>
            </>
          )}
        </section>
      </div>
    </main>
  )
}
