import { useEffect, useState } from 'react'
import { Plus } from 'lucide-react'
import { CategoryModal } from '../components/CategoryModal'
import { BlogCategoryTree } from '../components/BlogCategoryTree'
import { Breadcrumbs } from '../components/Breadcrumbs'
import { ConfirmDeleteModal } from '../components/ConfirmDeleteModal'
import type { Category, CategoryFormData } from '../types/category'
import { ApiError } from '../lib/api'
import { useT } from '../i18n/useT'
import {
  createPortfolioCategory,
  deletePortfolioCategory,
  listPortfolioCategories,
  mapPortfolioCategoryToUi,
  toPortfolioCategoryFormPayload,
  updatePortfolioCategory,
} from '../services/portfolioCategoryService'
import pageStyles from '../components/PageContent.module.css'
import styles from './CategoriesPage.module.css'

export function PortfolioCategoriesPage() {
  const t = useT()
  const [categories, setCategories] = useState<Category[]>([])
  const [expandedIds, setExpandedIds] = useState<Set<string>>(() => new Set())
  const [modalOpen, setModalOpen] = useState(false)
  const [defaultParentId, setDefaultParentId] = useState('')
  const [modalTitle, setModalTitle] = useState(() => t('categories.add'))
  const [editingCategory, setEditingCategory] = useState<Category | null>(null)
  const [isLoading, setIsLoading] = useState(true)
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [error, setError] = useState('')
  const [deleteTarget, setDeleteTarget] = useState<Category | null>(null)

  useEffect(() => {
    const controller = new AbortController()
    void loadCategories(controller.signal)
    return () => controller.abort()
  }, [])

  async function loadCategories(signal?: AbortSignal) {
    setIsLoading(true)
    setError('')
    try {
      const items = await listPortfolioCategories(signal)
      setCategories(items.map(mapPortfolioCategoryToUi))
    } catch (err) {
      if (err instanceof DOMException && err.name === 'AbortError') return
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError(t('portfolio.categories.errorLoad'))
      }
    } finally {
      setIsLoading(false)
    }
  }

  function openCreateModal(parentId = '', title?: string) {
    setEditingCategory(null)
    setDefaultParentId(parentId)
    setModalTitle(title ?? t('categories.add'))
    setModalOpen(true)
    if (parentId) {
      setExpandedIds((prev) => new Set(prev).add(parentId))
    }
  }

  function openEditModal(category: Category) {
    setEditingCategory(category)
    setDefaultParentId(category.parentId ?? '')
    setModalTitle(t('categories.edit'))
    setModalOpen(true)
  }

  function toggleExpanded(id: string) {
    setExpandedIds((prev) => {
      const next = new Set(prev)
      if (next.has(id)) next.delete(id)
      else next.add(id)
      return next
    })
  }

  async function handleSubmit(data: CategoryFormData) {
    setIsSubmitting(true)
    setError('')

    try {
      const payload = toPortfolioCategoryFormPayload(data)

      if (editingCategory) {
        const result = await updatePortfolioCategory(editingCategory.id, {
          ...payload,
          parentId: data.parentId || null,
        })
        setCategories((prev) =>
          prev.map((category) =>
            category.id === editingCategory.id
              ? mapPortfolioCategoryToUi(result.category)
              : category,
          ),
        )
      } else {
        const result = await createPortfolioCategory(payload)
        setCategories((prev) => [...prev, mapPortfolioCategoryToUi(result.category)])
        if (data.parentId) {
          setExpandedIds((prev) => new Set(prev).add(data.parentId))
        }
      }

      setModalOpen(false)
      setEditingCategory(null)
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError(t('portfolio.categories.errorSave'))
      }
    } finally {
      setIsSubmitting(false)
    }
  }

  async function confirmDelete() {
    if (!deleteTarget) return

    setIsSubmitting(true)
    setError('')

    try {
      const result = await deletePortfolioCategory(deleteTarget.id)
      const removed = new Set(result.deletedIds)
      setCategories((prev) => prev.filter((category) => !removed.has(category.id)))
      setExpandedIds((prev) => {
        const next = new Set(prev)
        removed.forEach((id) => next.delete(id))
        return next
      })
      setDeleteTarget(null)
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError(t('portfolio.categories.errorDelete'))
      }
    } finally {
      setIsSubmitting(false)
    }
  }

  return (
    <main className={pageStyles.content}>
      <Breadcrumbs
        items={[
          { label: 'Dashboard', href: '/' },
          { label: 'Portfolios', href: '/portfolios' },
          { label: 'Categories' },
        ]}
      />
      <div className={pageStyles.pageHeader}>
        <div>
          <h2 className={pageStyles.pageTitle}>{t('portfolio.categories.title')}</h2>
          <p className={pageStyles.pageSubtitle}>{t('portfolio.categories.subtitle')}</p>
        </div>
      </div>

      {error && (
        <div className={styles.error} role="alert">
          {error}
        </div>
      )}

      <div className={styles.list}>
        {isLoading ? (
          <p className={styles.empty}>{t('categories.loading')}</p>
        ) : categories.length === 0 ? (
          <p className={styles.empty}>{t('portfolio.categories.empty')}</p>
        ) : (
          <BlogCategoryTree
            categories={categories}
            expandedIds={expandedIds}
            onToggle={toggleExpanded}
            onAddSub={(id) => openCreateModal(id, t('categories.addSub'))}
            onEdit={(id) => {
              const category = categories.find((item) => item.id === id)
              if (category) openEditModal(category)
            }}
            onRemove={(id) => {
              const category = categories.find((item) => item.id === id)
              if (category) setDeleteTarget(category)
            }}
          />
        )}
      </div>

      <CategoryModal
        open={modalOpen}
        onClose={() => {
          if (!isSubmitting) {
            setModalOpen(false)
            setEditingCategory(null)
          }
        }}
        title={modalTitle}
        defaultParentId={defaultParentId}
        categories={categories}
        editingCategory={editingCategory}
        onSubmit={handleSubmit}
        isSubmitting={isSubmitting}
      />

      <ConfirmDeleteModal
        open={!!deleteTarget}
        title={t('categories.deleteTitle')}
        message={
          deleteTarget
            ? t('categories.deleteMessage', { name: deleteTarget.nameEn })
            : ''
        }
        onConfirm={confirmDelete}
        onCancel={() => !isSubmitting && setDeleteTarget(null)}
      />

      <div className={styles.fabDock}>
        <button
          type="button"
          className={styles.addFab}
          onClick={() => openCreateModal()}
          aria-label={t('categories.add')}
        >
          <Plus size={24} />
        </button>
      </div>
    </main>
  )
}
