import { useEffect, useState } from 'react'
import { createPortal } from 'react-dom'
import { X, ThumbsUp, Check, XCircle, Trash2 } from 'lucide-react'
import { useLocale } from '@meshkee/dashboard-ui'
import type { ProductComment } from '../types/comment'
import { formatCommentDate } from '../data/productComments'
import { ApiError } from '../lib/api'
import {
  COMMENTS_PER_PAGE,
  deleteComment,
  listPortfolioComments,
  updateCommentApproval,
} from '../services/commentService'
import { Pagination } from './Pagination'
import styles from './ProductCommentsModal.module.css'

interface PortfolioCommentsModalProps {
  open: boolean
  portfolioId: string
  portfolioTitle: string
  onClose: () => void
  onCountChange?: (count: number) => void
}

const ANIMATION_MS = 220

export function PortfolioCommentsModal({
  open,
  portfolioId,
  portfolioTitle,
  onClose,
  onCountChange,
}: PortfolioCommentsModalProps) {
  const { locale } = useLocale()
  const dateLocale = locale === 'fa' ? 'fa' : 'en'
  const [mounted, setMounted] = useState(open)
  const [closing, setClosing] = useState(false)
  const [comments, setComments] = useState<ProductComment[]>([])
  const [totalComments, setTotalComments] = useState(0)
  const [currentPage, setCurrentPage] = useState(1)
  const [isLoading, setIsLoading] = useState(false)
  const [error, setError] = useState('')
  const [actionId, setActionId] = useState<string | null>(null)

  const totalPages = Math.max(1, Math.ceil(totalComments / COMMENTS_PER_PAGE))

  useEffect(() => {
    if (open) {
      setMounted(true)
      setClosing(false)
      setCurrentPage(1)
    } else if (mounted) {
      setClosing(true)
      const timer = setTimeout(() => {
        setMounted(false)
        setClosing(false)
      }, ANIMATION_MS)
      return () => clearTimeout(timer)
    }
  }, [open, mounted])

  useEffect(() => {
    if (!open || !portfolioId) return

    const controller = new AbortController()
    void loadComments(currentPage, controller.signal)
    return () => controller.abort()
  }, [open, portfolioId, currentPage])

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

    try {
      const data = await listPortfolioComments(portfolioId, page, COMMENTS_PER_PAGE, signal)
      setComments(data.items)
      setTotalComments(data.total)
      onCountChange?.(data.total)
    } catch (err) {
      if (err instanceof DOMException && err.name === 'AbortError') return
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError('Unable to load comments.')
      }
    } finally {
      setIsLoading(false)
    }
  }

  useEffect(() => {
    if (currentPage > totalPages) {
      setCurrentPage(totalPages)
    }
  }, [currentPage, totalPages])

  useEffect(() => {
    if (!mounted || closing) return
    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose()
    }
    document.addEventListener('keydown', onKey)
    return () => document.removeEventListener('keydown', onKey)
  }, [mounted, closing, onClose])

  if (!mounted) return null

  async function toggleApproval(comment: ProductComment) {
    setActionId(comment.id)
    setError('')

    try {
      const updated = await updateCommentApproval(comment.id, !comment.approved)
      setComments((prev) => prev.map((c) => (c.id === comment.id ? updated : c)))
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError('Unable to update comment approval.')
      }
    } finally {
      setActionId(null)
    }
  }

  async function removeComment(commentId: string) {
    setActionId(commentId)
    setError('')

    try {
      await deleteComment(commentId)
      const nextTotal = totalComments - 1
      const nextTotalPages = Math.max(1, Math.ceil(nextTotal / COMMENTS_PER_PAGE))
      const nextPage = currentPage > nextTotalPages ? nextTotalPages : currentPage
      setTotalComments(nextTotal)
      onCountChange?.(nextTotal)

      if (nextPage !== currentPage) {
        setCurrentPage(nextPage)
      } else {
        setComments((prev) => prev.filter((c) => c.id !== commentId))
      }
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError('Unable to delete comment.')
      }
    } finally {
      setActionId(null)
    }
  }

  return createPortal(
    <div
      className={`${styles.overlay} ${closing ? styles.overlayOut : styles.overlayIn}`}
      onClick={onClose}
    >
      <div
        className={`${styles.modal} ${closing ? styles.modalOut : styles.modalIn}`}
        onClick={(e) => e.stopPropagation()}
        role="dialog"
        aria-modal="true"
        aria-labelledby="portfolio-comments-title"
      >
        <div className={styles.header}>
          <div>
            <h3 id="portfolio-comments-title" className={styles.title}>
              Comments
            </h3>
            {portfolioTitle && (
              <p className={styles.subtitle}>
                {portfolioTitle} · {totalComments}{' '}
                {totalComments === 1 ? 'comment' : 'comments'}
              </p>
            )}
          </div>
          <button className={styles.closeBtn} onClick={onClose} aria-label="Close">
            <X size={20} />
          </button>
        </div>

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

          {isLoading ? (
            <p className={styles.emptyText}>Loading comments...</p>
          ) : totalComments === 0 ? (
            <p className={styles.emptyText}>No comments yet for this portfolio item.</p>
          ) : (
            <>
              <div className={styles.list}>
                {comments.map((comment) => (
                  <article
                    key={comment.id}
                    className={`${styles.comment} ${comment.approved ? styles.commentApproved : ''}`}
                  >
                    <div className={styles.commentHeader}>
                      <div className={styles.commentMeta}>
                        <div className={styles.author}>{comment.author}</div>
                        <div className={styles.dateTime}>
                          {formatCommentDate(comment.createdAt, dateLocale)}
                        </div>
                      </div>
                      <span className={styles.likes}>
                        <ThumbsUp size={13} />
                        {comment.likesCount}
                      </span>
                    </div>
                    <p className={styles.text}>{comment.text}</p>
                    <div className={styles.commentActions}>
                      {comment.approved ? (
                        <button
                          type="button"
                          className={styles.rejectBtn}
                          disabled={actionId === comment.id}
                          onClick={() => void toggleApproval(comment)}
                        >
                          <XCircle size={14} />
                          Reject
                        </button>
                      ) : (
                        <button
                          type="button"
                          className={styles.approveBtn}
                          disabled={actionId === comment.id}
                          onClick={() => void toggleApproval(comment)}
                        >
                          <Check size={14} />
                          Approve
                        </button>
                      )}
                      <button
                        type="button"
                        className={styles.removeBtn}
                        disabled={actionId === comment.id}
                        onClick={() => void removeComment(comment.id)}
                      >
                        <Trash2 size={14} />
                        Remove
                      </button>
                    </div>
                  </article>
                ))}
              </div>

              {totalComments > COMMENTS_PER_PAGE && (
                <div className={styles.paginationWrap}>
                  <Pagination
                    currentPage={currentPage}
                    totalPages={totalPages}
                    onPageChange={setCurrentPage}
                  />
                </div>
              )}
            </>
          )}
        </div>
      </div>
    </div>
  ,
  document.body,
  )
}
