import { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { Plus } from 'lucide-react'
import { Breadcrumbs } from '../components/Breadcrumbs'
import { PortfolioCard } from '../components/PortfolioCard'
import { PortfolioCommentsModal } from '../components/PortfolioCommentsModal'
import { ConfirmDeleteModal } from '../components/ConfirmDeleteModal'
import { Pagination } from '../components/Pagination'
import { useToast } from '../context/ToastContext'
import { useT } from '../i18n/useT'
import { ApiError } from '../lib/api'
import {
  PORTFOLIOS_PER_PAGE,
  deletePortfolio,
  listPortfolios,
  updatePortfolio,
} from '../services/portfolioService'
import type { Portfolio } from '../types/portfolio'
import pageStyles from '../components/PageContent.module.css'
import styles from './BlogPage.module.css'

export function PortfolioListPage() {
  const navigate = useNavigate()
  const { showToast } = useToast()
  const t = useT()
  const [portfolios, setPortfolios] = useState<Portfolio[]>([])
  const [totalPortfolios, setTotalPortfolios] = useState(0)
  const [currentPage, setCurrentPage] = useState(1)
  const [isLoading, setIsLoading] = useState(true)
  const [isDeleting, setIsDeleting] = useState(false)
  const [movingUpId, setMovingUpId] = useState<string | null>(null)
  const [error, setError] = useState('')
  const [commentCounts, setCommentCounts] = useState<Record<string, number>>({})
  const [deleteTarget, setDeleteTarget] = useState<{ id: string; title: string } | null>(null)
  const [commentsTarget, setCommentsTarget] = useState<{ id: string; title: string } | null>(
    null,
  )

  const totalPages = Math.max(1, Math.ceil(totalPortfolios / PORTFOLIOS_PER_PAGE))

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

  async function loadPortfolios(page: number, signal?: AbortSignal) {
    setIsLoading(true)
    setError('')

    try {
      const data = await listPortfolios(page, PORTFOLIOS_PER_PAGE, signal)
      setPortfolios(data.items)
      setTotalPortfolios(data.total)
      setCommentCounts(
        Object.fromEntries(data.items.map((item) => [item.id, item.commentCount ?? 0])),
      )
    } catch (err) {
      if (err instanceof DOMException && err.name === 'AbortError') return
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError(t('portfolio.list.errorLoad'))
      }
    } finally {
      setIsLoading(false)
    }
  }

  function handleEdit(id: string) {
    navigate(`/portfolios/edit/${id}`)
  }

  function handleComments(id: string) {
    const portfolio = portfolios.find((item) => item.id === id)
    if (portfolio) {
      setCommentsTarget({ id, title: portfolio.title })
    }
  }

  function handleRemoveRequest(id: string) {
    const portfolio = portfolios.find((item) => item.id === id)
    if (portfolio) {
      setDeleteTarget({ id, title: portfolio.title })
    }
  }

  async function handleMoveUp(id: string) {
    const index = portfolios.findIndex((item) => item.id === id)
    if (index < 0) return
    if (index === 0 && currentPage === 1) return

    const current = portfolios[index]
    setMovingUpId(id)
    setError('')

    try {
      if (index === 0) {
        await updatePortfolio(current.id, { sortOrder: current.sortOrder - 1 })
      } else {
        const previous = portfolios[index - 1]
        if (current.sortOrder === previous.sortOrder) {
          await updatePortfolio(current.id, { sortOrder: previous.sortOrder - 1 })
        } else {
          await Promise.all([
            updatePortfolio(current.id, { sortOrder: previous.sortOrder }),
            updatePortfolio(previous.id, { sortOrder: current.sortOrder }),
          ])
        }
      }
      showToast(t('portfolio.list.toast.movedUp'), 'success')
      await loadPortfolios(currentPage)
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError(t('portfolio.list.errorMove'))
      }
    } finally {
      setMovingUpId(null)
    }
  }

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

    setIsDeleting(true)
    setError('')

    try {
      await deletePortfolio(deleteTarget.id)
      showToast(t('portfolio.list.toast.removed'), 'success')
      const nextTotal = totalPortfolios - 1
      const nextTotalPages = Math.max(1, Math.ceil(nextTotal / PORTFOLIOS_PER_PAGE))
      const nextPage = currentPage > nextTotalPages ? nextTotalPages : currentPage
      setDeleteTarget(null)
      setCurrentPage(nextPage)
      await loadPortfolios(nextPage)
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError(t('portfolio.list.errorDelete'))
      }
    } finally {
      setIsDeleting(false)
    }
  }

  function handlePageChange(page: number) {
    setCurrentPage(page)
    window.scrollTo({ top: 0, behavior: 'smooth' })
  }

  function handleCommentCountChange(count: number) {
    if (!commentsTarget) return
    setCommentCounts((prev) => ({
      ...prev,
      [commentsTarget.id]: count,
    }))
  }

  return (
    <main className={pageStyles.content}>
      <Breadcrumbs
        items={[
          { label: 'Dashboard', href: '/' },
          { label: 'Portfolios', href: '/portfolios' },
          { label: 'My Portfolios' },
        ]}
      />

      <div className={pageStyles.pageHeader}>
        <div>
          <h2 className={pageStyles.pageTitle}>{t('title.myPortfolios')}</h2>
          <p className={pageStyles.pageSubtitle}>
            {t('portfolio.list.subtitle', { count: totalPortfolios })}
          </p>
        </div>
      </div>

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

      {isLoading ? (
        <p className={styles.empty}>{t('portfolio.list.loading')}</p>
      ) : portfolios.length === 0 ? (
        <p className={styles.empty}>{t('portfolio.list.empty')}</p>
      ) : (
        <>
          <div className={pageStyles.gridCols4}>
            {portfolios.map((portfolio, index) => (
              <PortfolioCard
                key={portfolio.id}
                portfolio={portfolio}
                commentCount={commentCounts[portfolio.id] ?? portfolio.commentCount}
                canMoveUp={!(index === 0 && currentPage === 1)}
                isMovingUp={movingUpId === portfolio.id}
                onMoveUp={handleMoveUp}
                onEdit={handleEdit}
                onComments={handleComments}
                onRemove={handleRemoveRequest}
              />
            ))}
          </div>

          <Pagination
            currentPage={currentPage}
            totalPages={totalPages}
            onPageChange={handlePageChange}
          />
        </>
      )}

      <button
        type="button"
        className={styles.addFab}
        onClick={() => navigate('/portfolios/new')}
        aria-label={t('portfolio.list.addNew')}
      >
        <Plus size={26} strokeWidth={2.5} />
      </button>

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

      {commentsTarget && (
        <PortfolioCommentsModal
          open={!!commentsTarget}
          portfolioId={commentsTarget.id}
          portfolioTitle={commentsTarget.title}
          onClose={() => setCommentsTarget(null)}
          onCountChange={handleCommentCountChange}
        />
      )}
    </main>
  )
}
