import { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { Plus } from 'lucide-react'
import { Breadcrumbs } from '../components/Breadcrumbs'
import { BlogCard } from '../components/BlogCard'
import { BlogCommentsModal } from '../components/BlogCommentsModal'
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 {
  BLOGS_PER_PAGE,
  deleteBlog,
  listBlogs,
  mapBlogApiToUi,
  setBlogVerified,
  isBlogVerified,
} from '../services/blogService'
import type { Blog } from '../types/blog'
import pageStyles from '../components/PageContent.module.css'
import styles from './BlogPage.module.css'

export function BlogListPage() {
  const navigate = useNavigate()
  const { showToast } = useToast()
  const t = useT()
  const [blogs, setBlogs] = useState<Blog[]>([])
  const [totalBlogs, setTotalBlogs] = useState(0)
  const [currentPage, setCurrentPage] = useState(1)
  const [isLoading, setIsLoading] = useState(true)
  const [isDeleting, setIsDeleting] = useState(false)
  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 [verifyingId, setVerifyingId] = useState<string | null>(null)

  const totalPages = Math.max(1, Math.ceil(totalBlogs / BLOGS_PER_PAGE))

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

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

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

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

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

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

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

    setIsDeleting(true)
    setError('')

    try {
      await deleteBlog(deleteTarget.id)
      showToast(t('blog.list.toast.removed'), 'success')
      const nextTotal = totalBlogs - 1
      const nextTotalPages = Math.max(1, Math.ceil(nextTotal / BLOGS_PER_PAGE))
      const nextPage = currentPage > nextTotalPages ? nextTotalPages : currentPage
      setDeleteTarget(null)
      setCurrentPage(nextPage)
      await loadBlogs(nextPage)
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError(t('blog.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,
    }))
  }

  async function handleToggleVerify(id: string) {
    const blog = blogs.find((item) => item.id === id)
    if (!blog) return

    const nextVerified = !isBlogVerified(blog)
    setVerifyingId(id)
    setError('')

    try {
      const result = await setBlogVerified(id, nextVerified)
      setBlogs((prev) =>
        prev.map((item) => (item.id === id ? mapBlogApiToUi(result.blog) : item)),
      )
      showToast(
        nextVerified ? t('blog.list.toast.verified') : t('blog.list.toast.unverified'),
        'success',
      )
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError(t('blog.list.errorVerify'))
      }
    } finally {
      setVerifyingId(null)
    }
  }

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

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

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

      {isLoading ? (
        <p className={styles.empty}>{t('blog.list.loading')}</p>
      ) : blogs.length === 0 ? (
        <p className={styles.empty}>{t('blog.list.empty')}</p>
      ) : (
        <>
          <div className={pageStyles.grid}>
            {blogs.map((blog) => (
              <BlogCard
                key={blog.id}
                blog={blog}
                commentCount={commentCounts[blog.id] ?? blog.commentCount}
                onEdit={handleEdit}
                onComments={handleComments}
                onToggleVerify={handleToggleVerify}
                onRemove={handleRemoveRequest}
                isVerifying={verifyingId === blog.id}
              />
            ))}
          </div>

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

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

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

      {commentsTarget && (
        <BlogCommentsModal
          open={!!commentsTarget}
          blogId={commentsTarget.id}
          blogTitle={commentsTarget.title}
          onClose={() => setCommentsTarget(null)}
          onCountChange={handleCommentCountChange}
        />
      )}
    </main>
  )
}
