import { useEffect, useMemo, useRef, useState } from 'react'
import { Accordion, Button, ButtonGroup, Col, Container, Form, Modal, Row, Tab, Tabs } from 'react-bootstrap'
import DataTable, { createTheme } from 'react-data-table-component'
import { useTranslation } from 'react-i18next'
import { useDropzone } from 'react-dropzone'
import {
  createForum,
  deleteForum,
  fetchSettings,
  listAllForums,
  listUsers,
  reorderForums,
  saveSetting,
  saveSettings,
  uploadFavicon,
  uploadLogo,
  updateForum,
} from '../api/client'

export default function Acp({ isAdmin }) {
  const { t } = useTranslation()
  const [forums, setForums] = useState([])
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState('')
  const [selectedId, setSelectedId] = useState(null)
  const [draggingId, setDraggingId] = useState(null)
  const [overId, setOverId] = useState(null)
  const pendingOrder = useRef(null)
  const [createType, setCreateType] = useState(null)
  const [users, setUsers] = useState([])
  const [usersLoading, setUsersLoading] = useState(false)
  const [usersError, setUsersError] = useState('')
  const [usersPage, setUsersPage] = useState(1)
  const [usersPerPage, setUsersPerPage] = useState(10)
  const [generalSaving, setGeneralSaving] = useState(false)
  const [generalUploading, setGeneralUploading] = useState(false)
  const [generalError, setGeneralError] = useState('')
  const [generalSettings, setGeneralSettings] = useState({
    forum_name: '',
    default_theme: 'auto',
    accent_color_dark: '',
    accent_color_light: '',
    logo_dark: '',
    logo_light: '',
    show_header_name: 'true',
    favicon_ico: '',
    favicon_16: '',
    favicon_32: '',
    favicon_48: '',
    favicon_64: '',
    favicon_128: '',
    favicon_256: '',
  })
  const settingsDetailMap = {
    forum_name: 'forumName',
    default_theme: 'defaultTheme',
    accent_color_dark: 'accentDark',
    accent_color_light: 'accentLight',
    logo_dark: 'logoDark',
    logo_light: 'logoLight',
    show_header_name: 'showHeaderName',
    favicon_ico: 'faviconIco',
    favicon_16: 'favicon16',
    favicon_32: 'favicon32',
    favicon_48: 'favicon48',
    favicon_64: 'favicon64',
    favicon_128: 'favicon128',
    favicon_256: 'favicon256',
  }
  const [themeMode, setThemeMode] = useState(
    document.documentElement.getAttribute('data-bs-theme') || 'light'
  )

  useEffect(() => {
    createTheme('speedbb-dark', {
      text: {
        primary: '#e6e8eb',
        secondary: '#9aa4b2',
      },
      background: {
        default: 'transparent',
      },
      context: {
        background: '#1a1f29',
        text: '#ffffff',
      },
      divider: {
        default: '#2a2f3a',
      },
      action: {
        button: 'rgba(230, 232, 235, 0.12)',
        hover: 'rgba(230, 232, 235, 0.08)',
        disabled: 'rgba(230, 232, 235, 0.35)',
      },
    })

    createTheme('speedbb-light', {
      text: {
        primary: '#0e121b',
        secondary: '#5b6678',
      },
      background: {
        default: '#ffffff',
      },
      context: {
        background: '#f7f2ea',
        text: '#0e121b',
      },
      divider: {
        default: '#e0d7c7',
      },
      action: {
        button: 'rgba(14, 18, 27, 0.12)',
        hover: 'rgba(14, 18, 27, 0.06)',
        disabled: 'rgba(14, 18, 27, 0.35)',
      },
    })
  }, [])

  useEffect(() => {
    if (!isAdmin) return
    let active = true
    const loadSettings = async () => {
      try {
        const allSettings = await fetchSettings()
        const settingsMap = new Map(allSettings.map((setting) => [setting.key, setting.value]))
        if (!active) return
        const next = {
          forum_name: settingsMap.get('forum_name') || '',
          default_theme: settingsMap.get('default_theme') || 'auto',
          accent_color_dark: settingsMap.get('accent_color_dark') || '',
          accent_color_light: settingsMap.get('accent_color_light') || '',
          logo_dark: settingsMap.get('logo_dark') || '',
          logo_light: settingsMap.get('logo_light') || '',
          show_header_name: settingsMap.get('show_header_name') || 'true',
          favicon_ico: settingsMap.get('favicon_ico') || '',
          favicon_16: settingsMap.get('favicon_16') || '',
          favicon_32: settingsMap.get('favicon_32') || '',
          favicon_48: settingsMap.get('favicon_48') || '',
          favicon_64: settingsMap.get('favicon_64') || '',
          favicon_128: settingsMap.get('favicon_128') || '',
          favicon_256: settingsMap.get('favicon_256') || '',
        }
        setGeneralSettings(next)
      } catch (err) {
        if (active) setGeneralError(err.message)
      }
    }
    loadSettings()
    return () => {
      active = false
    }
  }, [isAdmin])

  const handleGeneralSave = async (event) => {
    event.preventDefault()
    setGeneralSaving(true)
    setGeneralError('')
    try {
      await saveSettings(
        Object.entries(generalSettings).map(([key, value]) => ({
          key,
          value: typeof value === 'string' ? value.trim() : String(value ?? ''),
        }))
      )
      const detail = Object.entries(generalSettings).reduce((acc, [key, value]) => {
        const mappedKey = settingsDetailMap[key]
        if (!mappedKey) return acc
        if (key === 'show_header_name') {
          acc[mappedKey] = value !== 'false'
          return acc
        }
        acc[mappedKey] = typeof value === 'string' ? value.trim() : String(value ?? '')
        return acc
      }, {})
      window.dispatchEvent(new CustomEvent('speedbb-settings-updated', { detail }))
    } catch (err) {
      setGeneralError(err.message)
    } finally {
      setGeneralSaving(false)
    }
  }

  const handleDefaultThemeChange = async (value) => {
    const previous = generalSettings.default_theme
    setGeneralSettings((prev) => ({ ...prev, default_theme: value }))
    setGeneralError('')
    try {
      await saveSetting('default_theme', value)
      window.dispatchEvent(
        new CustomEvent('speedbb-settings-updated', {
          detail: { defaultTheme: value },
        })
      )
    } catch (err) {
      setGeneralSettings((prev) => ({ ...prev, default_theme: previous }))
      setGeneralError(err.message)
    }
  }

  const handleLogoUpload = async (file, settingKey) => {
    if (!file) return
    setGeneralUploading(true)
    setGeneralError('')
    try {
      const result = await uploadLogo(file)
      const url = result?.url || ''
      setGeneralSettings((prev) => ({ ...prev, [settingKey]: url }))
      if (url) {
        await saveSetting(settingKey, url)
        const mappedKey = settingsDetailMap[settingKey]
        if (mappedKey) {
          window.dispatchEvent(
            new CustomEvent('speedbb-settings-updated', {
              detail: { [mappedKey]: url },
            })
          )
        }
      }
    } catch (err) {
      setGeneralError(err.message)
    } finally {
      setGeneralUploading(false)
    }
  }

  const handleFaviconUpload = async (file, settingKey) => {
    if (!file) return
    setGeneralUploading(true)
    setGeneralError('')
    try {
      const result = await uploadFavicon(file)
      const url = result?.url || ''
      setGeneralSettings((prev) => ({ ...prev, [settingKey]: url }))
      if (url) {
        await saveSetting(settingKey, url)
        const mappedKey = settingsDetailMap[settingKey]
        if (mappedKey) {
          window.dispatchEvent(
            new CustomEvent('speedbb-settings-updated', {
              detail: { [mappedKey]: url },
            })
          )
        }
      }
    } catch (err) {
      setGeneralError(err.message)
    } finally {
      setGeneralUploading(false)
    }
  }

  const faviconIcoDropzone = useDropzone({
    accept: {
      'image/png': ['.png'],
      'image/x-icon': ['.ico'],
    },
    maxFiles: 1,
    onDrop: (files) => handleFaviconUpload(files[0], 'favicon_ico'),
  })

  const favicon16Dropzone = useDropzone({
    accept: {
      'image/png': ['.png'],
      'image/x-icon': ['.ico'],
    },
    maxFiles: 1,
    onDrop: (files) => handleFaviconUpload(files[0], 'favicon_16'),
  })

  const favicon32Dropzone = useDropzone({
    accept: {
      'image/png': ['.png'],
      'image/x-icon': ['.ico'],
    },
    maxFiles: 1,
    onDrop: (files) => handleFaviconUpload(files[0], 'favicon_32'),
  })

  const favicon48Dropzone = useDropzone({
    accept: {
      'image/png': ['.png'],
      'image/x-icon': ['.ico'],
    },
    maxFiles: 1,
    onDrop: (files) => handleFaviconUpload(files[0], 'favicon_48'),
  })

  const favicon64Dropzone = useDropzone({
    accept: {
      'image/png': ['.png'],
      'image/x-icon': ['.ico'],
    },
    maxFiles: 1,
    onDrop: (files) => handleFaviconUpload(files[0], 'favicon_64'),
  })

  const favicon128Dropzone = useDropzone({
    accept: {
      'image/png': ['.png'],
      'image/x-icon': ['.ico'],
    },
    maxFiles: 1,
    onDrop: (files) => handleFaviconUpload(files[0], 'favicon_128'),
  })

  const favicon256Dropzone = useDropzone({
    accept: {
      'image/png': ['.png'],
      'image/x-icon': ['.ico'],
    },
    maxFiles: 1,
    onDrop: (files) => handleFaviconUpload(files[0], 'favicon_256'),
  })

  const darkLogoDropzone = useDropzone({
    accept: {
      'image/*': ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg'],
    },
    maxFiles: 1,
    onDrop: (files) => handleLogoUpload(files[0], 'logo_dark'),
  })

  const lightLogoDropzone = useDropzone({
    accept: {
      'image/*': ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg'],
    },
    maxFiles: 1,
    onDrop: (files) => handleLogoUpload(files[0], 'logo_light'),
  })

  useEffect(() => {
    const observer = new MutationObserver(() => {
      setThemeMode(document.documentElement.getAttribute('data-bs-theme') || 'light')
    })

    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['data-bs-theme'],
    })

    return () => observer.disconnect()
  }, [])
  const userColumns = useMemo(
    () => [
      {
        name: t('user.name'),
        selector: (row) => row.name,
        sortable: true,
      },
      {
        name: t('user.email'),
        selector: (row) => row.email,
        sortable: true,
      },
      {
        name: '',
        width: '180px',
        right: true,
        cell: (row) => (
          <div className="bb-user-actions">
            <ButtonGroup className="bb-action-group">
              <Button
                variant="dark"
                title={t('user.impersonate')}
                onClick={() => console.log('impersonate', row)}
              >
                <i className="bi bi-person-badge" aria-hidden="true" />
              </Button>
              <Button
                variant="dark"
                title={t('user.edit')}
                onClick={() => console.log('edit user', row)}
              >
                <i className="bi bi-pencil" aria-hidden="true" />
              </Button>
              <Button
                variant="dark"
                title={t('user.delete')}
                onClick={() => console.log('delete user', row)}
              >
                <i className="bi bi-trash" aria-hidden="true" />
              </Button>
            </ButtonGroup>
          </div>
        ),
      },
    ],
    [t]
  )
  const userTableStyles = useMemo(
    () => ({
      table: {
        style: {
          backgroundColor: themeMode === 'dark' ? 'transparent' : '#ffffff',
        },
      },
      headRow: {
        style: {
          backgroundColor: themeMode === 'dark' ? '#1a1f29' : '#f7f2ea',
          borderBottomColor: themeMode === 'dark' ? '#2a2f3a' : '#e0d7c7',
          color: themeMode === 'dark' ? '#e6e8eb' : '#0e121b',
          fontWeight: 600,
        },
      },
      rows: {
        style: {
          backgroundColor: themeMode === 'dark' ? 'rgba(255, 255, 255, 0.02)' : '#ffffff',
          color: themeMode === 'dark' ? '#e6e8eb' : '#0e121b',
        },
        stripedStyle: {
          backgroundColor: themeMode === 'dark' ? 'rgba(255, 255, 255, 0.05)' : '#f7f2ea',
          color: themeMode === 'dark' ? '#e6e8eb' : '#0e121b',
        },
        highlightOnHoverStyle: {
          backgroundColor: themeMode === 'dark'
            ? 'transparent'
            : 'rgba(0, 0, 0, 0.04)',
        },
      },
      pagination: {
        style: {
          backgroundColor: themeMode === 'dark' ? '#1a1f29' : '#ffffff',
          color: themeMode === 'dark' ? '#cfd6df' : '#5b6678',
          borderTopColor: themeMode === 'dark' ? '#2a2f3a' : '#e0d7c7',
        },
      },
    }),
    [themeMode]
  )

  const UsersPagination = ({ rowsPerPage, rowCount, onChangePage }) => {
    const totalPages = Math.max(1, Math.ceil(rowCount / rowsPerPage))
    const current = Math.min(usersPage, totalPages)

    const pages = []
    for (let page = Math.max(1, current - 2); page <= Math.min(totalPages, current + 2); page += 1) {
      pages.push(page)
    }

    const goTo = (page) => {
      if (page < 1 || page > totalPages) return
      onChangePage(page, rowCount)
    }

    return (
      <div className="bb-pagination">
        <div className="bb-pagination-range">
          {t('table.rows_per_page')} {rowsPerPage}{' '}
          <span className="bb-muted">
            {((current - 1) * rowsPerPage) + 1}-{Math.min(current * rowsPerPage, rowCount)} {t('table.range_separator')} {rowCount}
          </span>
        </div>
        <div className="bb-pagination-actions">
          <button type="button" onClick={() => goTo(1)} disabled={current === 1}>
            «
          </button>
          <button type="button" onClick={() => goTo(current - 1)} disabled={current === 1}>
            ‹
          </button>
          {pages.map((page) => (
            <button
              key={page}
              type="button"
              className={page === current ? 'is-active' : ''}
              onClick={() => goTo(page)}
            >
              {page}
            </button>
          ))}
          <button type="button" onClick={() => goTo(current + 1)} disabled={current === totalPages}>
            ›
          </button>
          <button type="button" onClick={() => goTo(totalPages)} disabled={current === totalPages}>
            »
          </button>
        </div>
      </div>
    )
  }
  const [collapsed, setCollapsed] = useState(() => new Set())
  const hasInitializedCollapse = useRef(false)
  const [showModal, setShowModal] = useState(false)
  const [form, setForm] = useState({
    name: '',
    description: '',
    type: 'category',
    parentId: '',
  })

  const refreshForums = async () => {
    setLoading(true)
    setError('')
    try {
      const data = await listAllForums()
      setForums(data.filter((forum) => !forum.deleted_at))
    } catch (err) {
      setError(err.message)
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    if (isAdmin) {
      refreshForums()
    }
  }, [isAdmin])

  useEffect(() => {
    if (!hasInitializedCollapse.current && forums.length > 0) {
      const ids = forums
        .filter((forum) => forum.type === 'category')
        .map((forum) => String(forum.id))
      setCollapsed(new Set(ids))
      hasInitializedCollapse.current = true
    }
  }, [forums])

  const refreshUsers = async () => {
    setUsersLoading(true)
    setUsersError('')
    try {
      const data = await listUsers()
      setUsers(data)
    } catch (err) {
      setUsersError(err.message)
    } finally {
      setUsersLoading(false)
    }
  }

  useEffect(() => {
    if (isAdmin) {
      refreshUsers()
    }
  }, [isAdmin])

  const getParentId = (forum) => {
    if (!forum.parent) return null
    if (typeof forum.parent === 'string') {
      return forum.parent.split('/').pop()
    }
    return forum.parent.id ?? null
  }

  const forumTree = useMemo(() => {
    const map = new Map()
    const roots = []

    forums.forEach((forum) => {
      map.set(String(forum.id), { ...forum, children: [] })
    })

    forums.forEach((forum) => {
      const parentId = getParentId(forum)
      const node = map.get(String(forum.id))
      if (parentId && map.has(String(parentId))) {
        map.get(String(parentId)).children.push(node)
      } else {
        roots.push(node)
      }
    })

    const sortNodes = (nodes) => {
      nodes.sort((a, b) => {
        if (a.position !== b.position) return a.position - b.position
        return a.name.localeCompare(b.name)
      })
      nodes.forEach((node) => sortNodes(node.children))
    }

    sortNodes(roots)

    return { roots, map }
  }, [forums])

  const categoryOptions = useMemo(
    () => forums.filter((forum) => forum.type === 'category'),
    [forums]
  )

  const handleSelectForum = (forum) => {
    const parentId =
      typeof forum.parent === 'string'
        ? forum.parent.split('/').pop()
        : forum.parent?.id ?? ''
    setSelectedId(String(forum.id))
    setShowModal(true)
    setCreateType(null)
    setForm({
      name: forum.name || '',
      description: forum.description || '',
      type: forum.type || 'category',
      parentId: parentId ? String(parentId) : '',
    })
  }

  const handleReset = () => {
    setSelectedId(null)
    setShowModal(false)
    setCreateType(null)
    setForm({
      name: '',
      description: '',
      type: 'category',
      parentId: '',
    })
  }

  const isExpanded = (forumId) => {
    const key = String(forumId)
    return !collapsed.has(key)
  }

  const toggleExpanded = (forumId) => {
    const key = String(forumId)
    setCollapsed((prev) => {
      const next = new Set(prev)
      if (next.has(key)) {
        next.delete(key)
      } else {
        next.add(key)
      }
      return next
    })
  }

  const handleCollapseAll = () => {
    const ids = forums
      .filter((forum) => forum.type === 'category')
      .map((forum) => String(forum.id))
    setCollapsed(new Set(ids))
  }

  const handleExpandAll = () => {
    setCollapsed(new Set())
  }

  const handleStartCreate = (type) => {
    const current = selectedId
    setSelectedId(null)
    setShowModal(true)
    setCreateType(type)
    const parentFromSelection = current
      ? forums.find((forum) => String(forum.id) === String(current))
      : null
    const parentId =
      parentFromSelection?.type === 'category' ? String(parentFromSelection.id) : ''
    setForm({
      name: '',
      description: '',
      type,
      parentId,
    })
  }

  const handleStartCreateChild = (type, parentId) => {
    setSelectedId(null)
    setShowModal(true)
    setCreateType(type)
    setForm({
      name: '',
      description: '',
      type,
      parentId: parentId ? String(parentId) : '',
    })
  }

  const handleSubmit = async (event) => {
    event.preventDefault()
    setError('')
    const trimmedName = form.name.trim()
    if (!trimmedName) {
      setError(t('acp.forums_name_required'))
      return
    }
    if (form.type === 'forum' && !form.parentId) {
      setError(t('acp.forums_parent_required'))
      return
    }
    try {
      if (selectedId) {
        await updateForum(selectedId, {
          name: trimmedName,
          description: form.description,
          type: form.type,
          parentId: form.parentId || null,
        })
      } else {
        await createForum({
          name: trimmedName,
          description: form.description,
          type: form.type,
          parentId: form.parentId || null,
        })
      }
      handleReset()
      refreshForums()
    } catch (err) {
      setError(err.message)
    }
  }

  const handleDelete = async (forumId) => {
    setError('')
    if (!confirm(t('acp.forums_confirm_delete'))) {
      return
    }
    try {
      await deleteForum(forumId)
      if (selectedId === String(forumId)) {
        handleReset()
      }
      refreshForums()
    } catch (err) {
      setError(err.message)
    }
  }

  const handleDragStart = (event, forumId) => {
    event.dataTransfer.effectAllowed = 'move'
    event.dataTransfer.setData('text/plain', String(forumId))
    setDraggingId(String(forumId))
  }

  const handleDragEnd = () => {
    if (pendingOrder.current) {
      const { parentId, ordered } = pendingOrder.current
      pendingOrder.current = null
      reorderForums(parentId, ordered).catch((err) => setError(err.message))
    }
    setDraggingId(null)
    setOverId(null)
  }

  const applyLocalOrder = (parentId, orderedIds) => {
    setForums((prev) =>
      prev.map((forum) => {
        const pid = getParentId(forum)
        if (String(pid ?? '') !== String(parentId ?? '')) {
          return forum
        }
        const newIndex = orderedIds.indexOf(String(forum.id))
        return newIndex === -1 ? forum : { ...forum, position: newIndex + 1 }
      })
    )
  }

  const handleDragOver = (event, targetId, parentId) => {
    event.preventDefault()
    event.dataTransfer.dropEffect = 'move'
    if (!draggingId || String(draggingId) === String(targetId)) {
      return
    }

    const draggedForum = forums.find((forum) => String(forum.id) === String(draggingId))
    if (!draggedForum) {
      return
    }

    const draggedParentId = getParentId(draggedForum)
    if (String(draggedParentId ?? '') !== String(parentId ?? '')) {
      return
    }

    const siblings = forums.filter((forum) => {
      const pid = getParentId(forum)
      return String(pid ?? '') === String(parentId ?? '')
    })

    const ordered = siblings
      .slice()
      .sort((a, b) => {
        if (a.position !== b.position) return a.position - b.position
        return a.name.localeCompare(b.name)
      })
      .map((forum) => String(forum.id))

    const fromIndex = ordered.indexOf(String(draggingId))
    const toIndex = ordered.indexOf(String(targetId))
    if (fromIndex === -1 || toIndex === -1 || fromIndex === toIndex) {
      return
    }

    ordered.splice(toIndex, 0, ordered.splice(fromIndex, 1)[0])
    setOverId(String(targetId))
    applyLocalOrder(parentId, ordered)
    pendingOrder.current = { parentId, ordered }
  }

  const handleDragEnter = (forumId) => {
    if (draggingId && String(forumId) !== String(draggingId)) {
      setOverId(String(forumId))
    }
  }

  const handleDragLeave = (event, forumId) => {
    if (event.currentTarget.contains(event.relatedTarget)) {
      return
    }
    if (overId === String(forumId)) {
      setOverId(null)
    }
  }

  const handleDrop = async (event, targetId, parentId) => {
    event.preventDefault()
    const draggedId = event.dataTransfer.getData('text/plain')
    if (!draggedId || String(draggedId) === String(targetId)) {
      setDraggingId(null)
      setOverId(null)
      return
    }

    const siblings = forums.filter((forum) => {
      const pid = getParentId(forum)
      return String(pid ?? '') === String(parentId ?? '')
    })

    const ordered = siblings
      .slice()
      .sort((a, b) => {
        if (a.position !== b.position) return a.position - b.position
        return a.name.localeCompare(b.name)
      })
      .map((forum) => String(forum.id))

    const fromIndex = ordered.indexOf(String(draggedId))
    const toIndex = ordered.indexOf(String(targetId))
    if (fromIndex === -1 || toIndex === -1) {
      return
    }

    ordered.splice(toIndex, 0, ordered.splice(fromIndex, 1)[0])
    pendingOrder.current = null

    try {
      await reorderForums(parentId, ordered)
      const updated = forums.map((forum) => {
        const pid = getParentId(forum)
        if (String(pid ?? '') !== String(parentId ?? '')) {
          return forum
        }
        const newIndex = ordered.indexOf(String(forum.id))
        return newIndex === -1 ? forum : { ...forum, position: newIndex + 1 }
      })
      setForums(updated)
    } catch (err) {
      setError(err.message)
    } finally {
      setDraggingId(null)
      setOverId(null)
    }
  }

  const renderTree = (nodes, depth = 0) =>
    nodes.map((node) => (
      <div key={node.id}>
        <div
          className={`bb-drag-item d-flex align-items-center justify-content-between border rounded p-2 mb-2 ${
            overId === String(node.id) ? 'bb-drop-target' : ''
          } ${draggingId === String(node.id) ? 'bb-dragging' : ''}`}
          style={{ marginLeft: depth * 16 }}
          draggable
          onDragStart={(event) => handleDragStart(event, node.id)}
          onDragEnd={handleDragEnd}
          onDragOver={(event) => handleDragOver(event, node.id, getParentId(node))}
          onDragEnter={() => handleDragEnter(node.id)}
          onDragLeave={(event) => handleDragLeave(event, node.id)}
          onDrop={(event) => handleDrop(event, node.id, getParentId(node))}
        >
          <div className="d-flex align-items-start gap-3">
            <span className={`bb-icon ${node.type === 'forum' ? 'bb-icon--forum' : ''}`}>
              <i className={`bi ${node.type === 'category' ? 'bi-folder2' : 'bi-chat-left-text'}`} />
              {node.type === 'category' && node.children?.length > 0 && (
                <button
                  type="button"
                  className="bb-collapse-toggle"
                  onClick={() => toggleExpanded(node.id)}
                  aria-label={isExpanded(node.id) ? t('acp.collapse') : t('acp.expand')}
                  title={isExpanded(node.id) ? t('acp.collapse') : t('acp.expand')}
                >
                  <i
                    className={`bi ${
                      isExpanded(node.id) ? 'bi-caret-down-fill' : 'bi-caret-right-fill'
                    }`}
                    aria-hidden="true"
                  />
                </button>
              )}
            </span>
            <div>
              <div className="fw-semibold d-flex align-items-center gap-2">
                <span>{node.name}</span>
              </div>
              <div className="bb-muted">{node.description || t('forum.no_description')}</div>
            </div>
          </div>
          <div className="d-flex align-items-center gap-3">
            <span
              className="bb-drag-handle text-muted"
              style={{ cursor: 'grab', display: 'inline-flex' }}
              title={t('acp.drag_handle')}
            >
              <i className="bi bi-arrow-down-up" aria-hidden="true" />
            </span>
            <div className="bb-tree-action-group">
              <ButtonGroup size="sm" className="bb-action-group w-100">
                {node.type === 'category' && (
                  <>
                    <Button
                      variant="dark"
                      onClick={() => handleStartCreateChild('category', node.id)}
                      title={t('acp.add_category')}
                    >
                      <i className="bi bi-folder-plus" aria-hidden="true" />
                    </Button>
                    <Button
                      variant="dark"
                      onClick={() => handleStartCreateChild('forum', node.id)}
                      title={t('acp.add_forum')}
                    >
                      <i className="bi bi-chat-left-text" aria-hidden="true" />
                    </Button>
                  </>
                )}
                <Button variant="dark" onClick={() => handleSelectForum(node)} title={t('acp.edit')}>
                  <i className="bi bi-pencil" aria-hidden="true" />
                </Button>
                <Button variant="dark" onClick={() => handleDelete(node.id)} title={t('acp.delete')}>
                  <i className="bi bi-trash" aria-hidden="true" />
                </Button>
              </ButtonGroup>
            </div>
          </div>
        </div>
        {node.children?.length > 0 &&
          (!node.type || node.type !== 'category' || isExpanded(node.id)) && (
            <div className="mb-2">{renderTree(node.children, depth + 1)}</div>
          )}
      </div>
    ))

  if (!isAdmin) {
    return (
      <Container fluid className="py-5">
        <h2 className="mb-3">{t('acp.title')}</h2>
        <p className="bb-muted">{t('acp.no_access')}</p>
      </Container>
    )
  }

  return (
    <Container fluid className="bb-acp py-4">
      <h2 className="mb-4">{t('acp.title')}</h2>
      <Tabs defaultActiveKey="general" className="mb-3">
        <Tab eventKey="general" title={t('acp.general')}>
          <p className="bb-muted">{t('acp.general_hint')}</p>
          {generalError && <p className="text-danger">{generalError}</p>}
          <Form onSubmit={handleGeneralSave} className="bb-acp-general">
            <Row className="g-3">
              <Col lg={6}>
                <Form.Group>
                  <Form.Label>{t('acp.forum_name')}</Form.Label>
                  <Form.Control
                    type="text"
                    value={generalSettings.forum_name}
                    onChange={(event) =>
                      setGeneralSettings((prev) => ({ ...prev, forum_name: event.target.value }))
                    }
                  />
                </Form.Group>
                <Form.Group className="mt-2">
                  <Form.Check
                    type="checkbox"
                    id="acp-show-header-name"
                    label={t('acp.show_header_name')}
                    checked={generalSettings.show_header_name !== 'false'}
                    onChange={(event) =>
                      setGeneralSettings((prev) => ({
                        ...prev,
                        show_header_name: event.target.checked ? 'true' : 'false',
                      }))
                    }
                  />
                </Form.Group>
              </Col>
              <Col lg={6}>
                <Form.Group>
                  <Form.Label>{t('acp.default_theme')}</Form.Label>
                  <Form.Select
                    value={generalSettings.default_theme}
                    onChange={(event) => handleDefaultThemeChange(event.target.value)}
                  >
                    <option value="auto">{t('ucp.system_default')}</option>
                    <option value="dark">{t('nav.theme_dark')}</option>
                    <option value="light">{t('nav.theme_light')}</option>
                  </Form.Select>
                </Form.Group>
              </Col>
              <Col lg={6}>
                <Form.Group>
                  <Form.Label>{t('acp.accent_dark')}</Form.Label>
                  <div className="d-flex align-items-center gap-2">
                    <Form.Control
                      type="text"
                      value={generalSettings.accent_color_dark}
                      onChange={(event) =>
                        setGeneralSettings((prev) => ({
                          ...prev,
                          accent_color_dark: event.target.value,
                        }))
                      }
                      placeholder="#f29b3f"
                    />
                    <Form.Control
                      type="color"
                      value={generalSettings.accent_color_dark || '#f29b3f'}
                      onChange={(event) =>
                        setGeneralSettings((prev) => ({
                          ...prev,
                          accent_color_dark: event.target.value,
                        }))
                      }
                    />
                  </div>
                </Form.Group>
              </Col>
              <Col lg={6}>
                <Form.Group>
                  <Form.Label>{t('acp.accent_light')}</Form.Label>
                  <div className="d-flex align-items-center gap-2">
                    <Form.Control
                      type="text"
                      value={generalSettings.accent_color_light}
                      onChange={(event) =>
                        setGeneralSettings((prev) => ({
                          ...prev,
                          accent_color_light: event.target.value,
                        }))
                      }
                      placeholder="#f29b3f"
                    />
                    <Form.Control
                      type="color"
                      value={generalSettings.accent_color_light || '#f29b3f'}
                      onChange={(event) =>
                        setGeneralSettings((prev) => ({
                          ...prev,
                          accent_color_light: event.target.value,
                        }))
                      }
                    />
                  </div>
                </Form.Group>
              </Col>
              <Col lg={6}>
                <Form.Group>
                  <Form.Label>{t('acp.logo_dark')}</Form.Label>
                  <div
                    {...darkLogoDropzone.getRootProps({
                      className: 'bb-dropzone',
                    })}
                  >
                    <input {...darkLogoDropzone.getInputProps()} />
                    {generalSettings.logo_dark ? (
                      <div className="bb-dropzone-preview">
                        <img src={generalSettings.logo_dark} alt={t('acp.logo_dark')} />
                      </div>
                    ) : (
                      <div className="bb-dropzone-placeholder">
                        <i className="bi bi-upload" aria-hidden="true" />
                        <span>{t('acp.logo_upload')}</span>
                      </div>
                    )}
                  </div>
                </Form.Group>
              </Col>
              <Col lg={6}>
                <Form.Group>
                  <Form.Label>{t('acp.logo_light')}</Form.Label>
                  <div
                    {...lightLogoDropzone.getRootProps({
                      className: 'bb-dropzone',
                    })}
                  >
                    <input {...lightLogoDropzone.getInputProps()} />
                    {generalSettings.logo_light ? (
                      <div className="bb-dropzone-preview">
                        <img src={generalSettings.logo_light} alt={t('acp.logo_light')} />
                      </div>
                    ) : (
                      <div className="bb-dropzone-placeholder">
                        <i className="bi bi-upload" aria-hidden="true" />
                        <span>{t('acp.logo_upload')}</span>
                      </div>
                    )}
                  </div>
                </Form.Group>
              </Col>
              <Col xs={12}>
                <Accordion className="bb-acp-accordion">
                  <Accordion.Item eventKey="favicons">
                    <Accordion.Header>{t('acp.favicons')}</Accordion.Header>
                    <Accordion.Body>
                      <Row className="g-3">
                        <Col lg={4}>
                          <Form.Group>
                            <Form.Label>{t('acp.favicon_ico')}</Form.Label>
                            <div {...faviconIcoDropzone.getRootProps({ className: 'bb-dropzone' })}>
                              <input {...faviconIcoDropzone.getInputProps()} />
                              {generalSettings.favicon_ico ? (
                                <div className="bb-dropzone-preview">
                                  <img src={generalSettings.favicon_ico} alt={t('acp.favicon_ico')} />
                                </div>
                              ) : (
                                <div className="bb-dropzone-placeholder">
                                  <i className="bi bi-upload" aria-hidden="true" />
                                  <span>{t('acp.logo_upload')}</span>
                                </div>
                              )}
                            </div>
                          </Form.Group>
                        </Col>
                        <Col lg={4}>
                          <Form.Group>
                            <Form.Label>{t('acp.favicon_16')}</Form.Label>
                            <div {...favicon16Dropzone.getRootProps({ className: 'bb-dropzone' })}>
                              <input {...favicon16Dropzone.getInputProps()} />
                              {generalSettings.favicon_16 ? (
                                <div className="bb-dropzone-preview">
                                  <img src={generalSettings.favicon_16} alt={t('acp.favicon_16')} />
                                </div>
                              ) : (
                                <div className="bb-dropzone-placeholder">
                                  <i className="bi bi-upload" aria-hidden="true" />
                                  <span>{t('acp.logo_upload')}</span>
                                </div>
                              )}
                            </div>
                          </Form.Group>
                        </Col>
                        <Col lg={4}>
                          <Form.Group>
                            <Form.Label>{t('acp.favicon_32')}</Form.Label>
                            <div {...favicon32Dropzone.getRootProps({ className: 'bb-dropzone' })}>
                              <input {...favicon32Dropzone.getInputProps()} />
                              {generalSettings.favicon_32 ? (
                                <div className="bb-dropzone-preview">
                                  <img src={generalSettings.favicon_32} alt={t('acp.favicon_32')} />
                                </div>
                              ) : (
                                <div className="bb-dropzone-placeholder">
                                  <i className="bi bi-upload" aria-hidden="true" />
                                  <span>{t('acp.logo_upload')}</span>
                                </div>
                              )}
                            </div>
                          </Form.Group>
                        </Col>
                        <Col lg={4}>
                          <Form.Group>
                            <Form.Label>{t('acp.favicon_48')}</Form.Label>
                            <div {...favicon48Dropzone.getRootProps({ className: 'bb-dropzone' })}>
                              <input {...favicon48Dropzone.getInputProps()} />
                              {generalSettings.favicon_48 ? (
                                <div className="bb-dropzone-preview">
                                  <img src={generalSettings.favicon_48} alt={t('acp.favicon_48')} />
                                </div>
                              ) : (
                                <div className="bb-dropzone-placeholder">
                                  <i className="bi bi-upload" aria-hidden="true" />
                                  <span>{t('acp.logo_upload')}</span>
                                </div>
                              )}
                            </div>
                          </Form.Group>
                        </Col>
                        <Col lg={4}>
                          <Form.Group>
                            <Form.Label>{t('acp.favicon_64')}</Form.Label>
                            <div {...favicon64Dropzone.getRootProps({ className: 'bb-dropzone' })}>
                              <input {...favicon64Dropzone.getInputProps()} />
                              {generalSettings.favicon_64 ? (
                                <div className="bb-dropzone-preview">
                                  <img src={generalSettings.favicon_64} alt={t('acp.favicon_64')} />
                                </div>
                              ) : (
                                <div className="bb-dropzone-placeholder">
                                  <i className="bi bi-upload" aria-hidden="true" />
                                  <span>{t('acp.logo_upload')}</span>
                                </div>
                              )}
                            </div>
                          </Form.Group>
                        </Col>
                        <Col lg={4}>
                          <Form.Group>
                            <Form.Label>{t('acp.favicon_128')}</Form.Label>
                            <div {...favicon128Dropzone.getRootProps({ className: 'bb-dropzone' })}>
                              <input {...favicon128Dropzone.getInputProps()} />
                              {generalSettings.favicon_128 ? (
                                <div className="bb-dropzone-preview">
                                  <img src={generalSettings.favicon_128} alt={t('acp.favicon_128')} />
                                </div>
                              ) : (
                                <div className="bb-dropzone-placeholder">
                                  <i className="bi bi-upload" aria-hidden="true" />
                                  <span>{t('acp.logo_upload')}</span>
                                </div>
                              )}
                            </div>
                          </Form.Group>
                        </Col>
                        <Col lg={4}>
                          <Form.Group>
                            <Form.Label>{t('acp.favicon_256')}</Form.Label>
                            <div {...favicon256Dropzone.getRootProps({ className: 'bb-dropzone' })}>
                              <input {...favicon256Dropzone.getInputProps()} />
                              {generalSettings.favicon_256 ? (
                                <div className="bb-dropzone-preview">
                                  <img src={generalSettings.favicon_256} alt={t('acp.favicon_256')} />
                                </div>
                              ) : (
                                <div className="bb-dropzone-placeholder">
                                  <i className="bi bi-upload" aria-hidden="true" />
                                  <span>{t('acp.logo_upload')}</span>
                                </div>
                              )}
                            </div>
                          </Form.Group>
                        </Col>
                      </Row>
                    </Accordion.Body>
                  </Accordion.Item>
                </Accordion>
              </Col>
              <Col xs={12} className="d-flex justify-content-end">
                <Button
                  type="submit"
                  className="bb-accent-button"
                  disabled={generalSaving || generalUploading}
                >
                  {generalSaving ? t('form.saving') : t('acp.save')}
                </Button>
              </Col>
            </Row>
          </Form>
        </Tab>
        <Tab eventKey="forums" title={t('acp.forums')}>
          <p className="bb-muted">{t('acp.forums_hint')}</p>
          {error && <p className="text-danger">{error}</p>}
          <Row className="g-4">
            <Col lg={12}>
              <div className="d-flex align-items-center justify-content-between mb-3 gap-3 flex-wrap">
                <div className="d-flex align-items-center gap-2">
                  <h5 className="mb-0">{t('acp.forums_tree')}</h5>
                  <Button size="sm" variant="outline-dark" className="bb-acp-action" onClick={handleExpandAll}>
                    <i className="bi bi-arrows-expand me-1" aria-hidden="true" />
                    {t('acp.expand_all')}
                  </Button>
                  <Button size="sm" variant="outline-dark" className="bb-acp-action" onClick={handleCollapseAll}>
                    <i className="bi bi-arrows-collapse me-1" aria-hidden="true" />
                    {t('acp.collapse_all')}
                  </Button>
                </div>
                <div className="d-flex gap-2">
                  <Button
                    size="sm"
                    variant="outline-dark"
                    className={`bb-acp-action ${createType === 'category' ? 'bb-acp-action--active' : ''}`}
                    onClick={() => handleStartCreate('category')}
                  >
                    <i className="bi bi-folder2 me-1" aria-hidden="true" />
                    {t('acp.new_category')}
                  </Button>
                  <Button
                    size="sm"
                    variant="outline-dark"
                    className={`bb-acp-action ${createType === 'forum' ? 'bb-acp-action--active' : ''}`}
                    onClick={() => handleStartCreate('forum')}
                  >
                    <i className="bi bi-chat-left-text me-1" aria-hidden="true" />
                    {t('acp.new_forum')}
                  </Button>
                </div>
              </div>
              {loading && <p className="bb-muted">{t('acp.loading')}</p>}
              {!loading && forumTree.roots.length === 0 && (
                <p className="bb-muted">{t('acp.forums_empty')}</p>
              )}
              {forumTree.roots.length > 0 && (
                <div className="mt-2">{renderTree(forumTree.roots)}</div>
              )}
            </Col>
          </Row>
        </Tab>
        <Tab eventKey="users" title={t('acp.users')}>
          {usersError && <p className="text-danger">{usersError}</p>}
          {usersLoading && <p className="bb-muted">{t('acp.loading')}</p>}
          {!usersLoading && (
            <DataTable
              columns={userColumns}
              data={users}
              pagination
              striped
              highlightOnHover={themeMode !== 'dark'}
              dense
              theme={themeMode === 'dark' ? 'speedbb-dark' : 'speedbb-light'}
              customStyles={userTableStyles}
              paginationComponentOptions={{
                rowsPerPageText: t('table.rows_per_page'),
                rangeSeparatorText: t('table.range_separator'),
              }}
              paginationPerPage={usersPerPage}
              onChangePage={(page) => setUsersPage(page)}
              onChangeRowsPerPage={(perPage) => {
                setUsersPerPage(perPage)
                setUsersPage(1)
              }}
              paginationComponent={UsersPagination}
            />
          )}
        </Tab>
      </Tabs>
      <Modal show={showModal} onHide={handleReset} centered size="lg">
        <Modal.Header closeButton closeVariant="white">
          <Modal.Title>
            {selectedId
              ? form.type === 'category'
                ? t('acp.forums_edit_category_title')
                : t('acp.forums_edit_forum_title')
              : createType === 'category'
                ? t('acp.forums_create_category_title')
                : createType === 'forum'
                  ? t('acp.forums_create_forum_title')
                  : t('acp.forums_create_title')}
          </Modal.Title>
        </Modal.Header>
        <Modal.Body>
          <p className="bb-muted">
            {selectedId
              ? form.type === 'category'
                ? t('acp.forums_edit_category_hint')
                : t('acp.forums_edit_forum_hint')
              : createType === 'category'
                ? t('acp.forums_create_category_hint')
                : createType === 'forum'
                  ? t('acp.forums_create_forum_hint')
                  : t('acp.forums_form_hint')}
          </p>
          <Form onSubmit={handleSubmit}>
            <Form.Group className="mb-3">
              <Form.Label>{t('form.title')}</Form.Label>
              <Form.Control
                type="text"
                value={form.name}
                onChange={(event) => setForm({ ...form, name: event.target.value })}
                required
              />
            </Form.Group>
            <Form.Group className="mb-3">
              <Form.Label>{t('form.description')}</Form.Label>
              <Form.Control
                as="textarea"
                rows={3}
                value={form.description}
                onChange={(event) => setForm({ ...form, description: event.target.value })}
              />
            </Form.Group>
            {selectedId && (
              <Form.Group className="mb-3">
                <Form.Label>{t('acp.forums_type')}</Form.Label>
                <Form.Select
                  value={form.type}
                  onChange={(event) => setForm({ ...form, type: event.target.value })}
                >
                  <option value="category">{t('forum.type_category')}</option>
                  <option value="forum">{t('forum.type_forum')}</option>
                </Form.Select>
              </Form.Group>
            )}
            <Form.Group className="mb-3">
              <Form.Label>{t('acp.forums_parent')}</Form.Label>
              <Form.Select
                value={form.parentId}
                onChange={(event) => setForm({ ...form, parentId: event.target.value })}
              >
                <option value="" disabled={form.type === 'forum'}>
                  {t('acp.forums_parent_root')}
                </option>
                {categoryOptions
                  .filter((option) => String(option.id) !== String(selectedId))
                  .map((option) => (
                    <option key={option.id} value={option.id}>
                      {option.name}
                    </option>
                  ))}
              </Form.Select>
            </Form.Group>
            <div className="d-flex gap-2 justify-content-between">
              <Button type="button" variant="outline-secondary" onClick={handleReset}>
                {t('acp.cancel')}
              </Button>
              <Button type="submit" className="bb-accent-button">
                {selectedId ? t('acp.save') : t('acp.create')}
              </Button>
            </div>
          </Form>
        </Modal.Body>
      </Modal>
    </Container>
  )
}
