import { useEffect, useMemo, useState } from 'react'
import { Filter, X } from 'lucide-react'
import { useNavigate, useParams } from 'react-router-dom'
import PageHeader from '../components/PageHeader'
import ProductCard from '../components/ProductCard'
import { listCategories, listProducts } from '../lib/api'
import { isCuid } from '../lib/ids'
import type { CategoryNode, Product } from '../lib/types'
import handbagIcon from '../assets/images/Handbag.svg'
import './ProductsListPage.css'

function flattenCategories(nodes: CategoryNode[], depth = 0): Array<CategoryNode & { depth: number }> {
  const result: Array<CategoryNode & { depth: number }> = []
  for (const node of nodes) {
    result.push({ ...node, depth })
    if (node.children?.length) {
      result.push(...flattenCategories(node.children, depth + 1))
    }
  }
  return result
}

const PAGE_SIZE = 12

export default function ProductsListPage() {
  const navigate = useNavigate()
  const { slugOrId = '' } = useParams()
  const categorySlug = slugOrId && !isCuid(slugOrId) ? slugOrId : ''

  const [products, setProducts] = useState<Product[]>([])
  const [categories, setCategories] = useState<CategoryNode[]>([])
  const [total, setTotal] = useState(0)
  const [page, setPage] = useState(1)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [filterOpen, setFilterOpen] = useState(false)

  const [draftQ, setDraftQ] = useState('')
  const [draftCategorySlug, setDraftCategorySlug] = useState('')
  const [draftMinPrice, setDraftMinPrice] = useState('')
  const [draftMaxPrice, setDraftMaxPrice] = useState('')

  const [q, setQ] = useState('')
  const [minPrice, setMinPrice] = useState<number | undefined>()
  const [maxPrice, setMaxPrice] = useState<number | undefined>()

  const flatCategories = useMemo(() => flattenCategories(categories), [categories])
  const totalPages = Math.max(1, Math.ceil(total / PAGE_SIZE))

  useEffect(() => {
    document.title = 'شیرینی بلوط - صفحه محصولات'
  }, [])

  useEffect(() => {
    setDraftCategorySlug(categorySlug)
    setPage(1)
  }, [categorySlug])

  useEffect(() => {
    listCategories()
      .then(setCategories)
      .catch(() => setCategories([]))
  }, [])

  useEffect(() => {
    let cancelled = false
    setLoading(true)
    setError(null)

    listProducts({
      q: q || undefined,
      categorySlug: categorySlug || undefined,
      minPrice,
      maxPrice,
      page,
      pageSize: PAGE_SIZE,
    })
      .then((result) => {
        if (cancelled) return
        setProducts(result.items)
        setTotal(result.total)
      })
      .catch((err: Error) => {
        if (cancelled) return
        setProducts([])
        setTotal(0)
        setError(err.message || 'خطا در دریافت محصولات')
      })
      .finally(() => {
        if (!cancelled) setLoading(false)
      })

    return () => {
      cancelled = true
    }
  }, [q, categorySlug, minPrice, maxPrice, page])

  function applyFilters() {
    setQ(draftQ.trim())
    setMinPrice(draftMinPrice ? Number(draftMinPrice) : undefined)
    setMaxPrice(draftMaxPrice ? Number(draftMaxPrice) : undefined)
    setPage(1)
    setFilterOpen(false)

    if (draftCategorySlug) {
      navigate(`/products/${draftCategorySlug}`)
    } else {
      navigate('/products')
    }
  }

  function resetFilters() {
    setDraftQ('')
    setDraftCategorySlug('')
    setDraftMinPrice('')
    setDraftMaxPrice('')
    setQ('')
    setMinPrice(undefined)
    setMaxPrice(undefined)
    setPage(1)
    setFilterOpen(false)
    navigate('/products')
  }

  return (
    <div className="products-page">
      <PageHeader
        fluid
        icon={handbagIcon}
        placeholder="New Products"
        secondary="محصولات"
        primary="جدید شیرینی بلوط"
        crumbs={[
          { label: 'صفحه اصلی', to: '/' },
          { label: 'محصولات', to: categorySlug ? '/products' : undefined },
          ...(categorySlug
            ? [
                {
                  label:
                    flatCategories.find((cat) => cat.slug === categorySlug)?.nameFa ||
                    categorySlug,
                },
              ]
            : []),
        ]}
      />

      <div className="max-container max-container--fluid products-page__toolbar">
        <button
          type="button"
          className="products-page__filter-btn"
          onClick={() => setFilterOpen((v) => !v)}
        >
          <Filter size={16} strokeWidth={1.75} />
          فیلتر کردن
        </button>
      </div>

      {filterOpen && (
        <div className="max-container max-container--fluid products-page__filters">
          <div className="products-page__filters-head">
            <span>فیلتر محصولات</span>
            <button type="button" onClick={() => setFilterOpen(false)} aria-label="بستن">
              <X size={18} />
            </button>
          </div>
          <div className="products-page__filters-grid">
            <label>
              <span>جستجو</span>
              <input
                type="text"
                value={draftQ}
                onChange={(e) => setDraftQ(e.target.value)}
                placeholder="نام محصول"
              />
            </label>
            <label>
              <span>دسته‌بندی</span>
              <select
                value={draftCategorySlug}
                onChange={(e) => setDraftCategorySlug(e.target.value)}
              >
                <option value="">همه</option>
                {flatCategories.map((cat) => (
                  <option key={cat.id} value={cat.slug}>
                    {'—'.repeat(cat.depth)} {cat.nameFa}
                  </option>
                ))}
              </select>
            </label>
            <label>
              <span>حداقل قیمت</span>
              <input
                type="number"
                min={0}
                value={draftMinPrice}
                onChange={(e) => setDraftMinPrice(e.target.value)}
              />
            </label>
            <label>
              <span>حداکثر قیمت</span>
              <input
                type="number"
                min={0}
                value={draftMaxPrice}
                onChange={(e) => setDraftMaxPrice(e.target.value)}
              />
            </label>
          </div>
          <div className="products-page__filters-actions">
            <button type="button" className="btn-primary" onClick={applyFilters}>
              اعمال فیلتر
            </button>
            <button type="button" className="products-page__reset" onClick={resetFilters}>
              حذف فیلتر
            </button>
          </div>
        </div>
      )}

      <div className="max-container max-container--fluid products-page__content">
        {loading && (
          <div className="products-page__state">
            <div className="products-page__spinner" />
            <p>در حال بارگذاری محصولات...</p>
          </div>
        )}

        {!loading && error && (
          <div className="products-page__state products-page__state--error">
            <p>{error}</p>
            <p className="products-page__hint">
              مطمئن شوید بک‌اند روی پورت 3100 در حال اجراست.
            </p>
          </div>
        )}

        {!loading && !error && products.length === 0 && (
          <div className="products-page__state">
            <p>محصولی یافت نشد.</p>
          </div>
        )}

        {!loading && !error && products.length > 0 && (
          <>
            <div className="products-page__grid">
              {products.map((product) => (
                <ProductCard key={product.id} product={product} />
              ))}
            </div>

            {totalPages > 1 && (
              <div className="products-page__pagination">
                <button
                  type="button"
                  disabled={page <= 1}
                  onClick={() => setPage((p) => Math.max(1, p - 1))}
                >
                  قبلی
                </button>
                {Array.from({ length: totalPages }, (_, i) => i + 1)
                  .filter((n) => n === 1 || n === totalPages || Math.abs(n - page) <= 2)
                  .map((n, index, arr) => (
                    <span key={n} className="products-page__page-wrap">
                      {index > 0 && arr[index - 1] !== n - 1 && (
                        <span className="products-page__ellipsis">…</span>
                      )}
                      <button
                        type="button"
                        className={n === page ? 'is-active' : undefined}
                        onClick={() => setPage(n)}
                      >
                        {n.toLocaleString('fa-IR')}
                      </button>
                    </span>
                  ))}
                <button
                  type="button"
                  disabled={page >= totalPages}
                  onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
                >
                  بعدی
                </button>
              </div>
            )}
          </>
        )}
      </div>
    </div>
  )
}
