import { useEffect, useMemo, useRef, useState } from 'react'
import { Link, useParams, useSearchParams } from 'react-router-dom'
import {
  fetchProducts,
  fetchStore,
  formatInt,
  formatPrice,
  formatRelativeDate,
  hostnameOf,
  ProductsResponse,
  StoreDetail as StoreDetailType,
} from '../api'
import EmptyState from '../components/EmptyState'
import {
  categoryIcon,
  IconExternal,
  IconFacebook,
  IconInstagram,
  IconMapPin,
  IconSearch,
} from '../components/Icons'
import OriginBadge from '../components/OriginBadge'
import Pagination from '../components/Pagination'
import ProductGrid from '../components/ProductGrid'
import Skeleton, { SkeletonGrid } from '../components/Skeleton'
import StoreLogo from '../components/StoreLogo'

const PER_PAGE = 24
const DEFAULT_TITLE = 'Fabri-Ka — Tous les produits québécois. Un seul endroit.'

const SORT_OPTIONS: { value: string; label: string }[] = [
  { value: 'recent', label: 'Plus récents' },
  { value: 'price_asc', label: 'Prix croissant' },
  { value: 'price_desc', label: 'Prix décroissant' },
  { value: 'title', label: 'Ordre alphabétique' },
]

export default function StoreDetail() {
  const { id } = useParams<{ id: string }>()
  const [searchParams, setSearchParams] = useSearchParams()
  const [store, setStore] = useState<StoreDetailType | null>(null)
  const [storeError, setStoreError] = useState(false)
  const [products, setProducts] = useState<ProductsResponse | null>(null)
  const [productsLoading, setProductsLoading] = useState(true)
  const [coverReady, setCoverReady] = useState(false)

  const page = Math.max(1, parseInt(searchParams.get('page') ?? '1', 10) || 1)
  const q = searchParams.get('q') ?? ''
  const sort = searchParams.get('tri') ?? 'recent'

  const [search, setSearch] = useState(q)
  const debounceRef = useRef<number | undefined>(undefined)

  useEffect(() => {
    setSearch(q)
  }, [q])

  // ---- store -------------------------------------------------------------
  useEffect(() => {
    if (!id) return
    const controller = new AbortController()
    setStore(null)
    setStoreError(false)
    setCoverReady(false)
    fetchStore(id, controller.signal)
      .then(setStore)
      .catch((err: unknown) => {
        if (err instanceof DOMException && err.name === 'AbortError') return
        setStoreError(true)
      })
    window.scrollTo({ top: 0 })
    return () => controller.abort()
  }, [id])

  // ---- SEO title ----------------------------------------------------------
  useEffect(() => {
    if (store) document.title = `${store.name} — Fabri-Ka`
    return () => {
      document.title = DEFAULT_TITLE
    }
  }, [store])

  // ---- cover preload (never show a broken cover) --------------------------
  const coverUrl = store?.cover_url ?? null
  useEffect(() => {
    if (!coverUrl) return
    let cancelled = false
    const img = new Image()
    img.onload = () => {
      if (!cancelled) setCoverReady(true)
    }
    img.src = coverUrl
    return () => {
      cancelled = true
    }
  }, [coverUrl])

  // ---- products (in-store search + sort + pagination) ---------------------
  useEffect(() => {
    if (!id) return
    const controller = new AbortController()
    setProductsLoading(true)
    fetchProducts(
      {
        store: id,
        q: q || undefined,
        sort,
        page,
        per_page: PER_PAGE,
      },
      controller.signal
    )
      .then((res) => {
        setProducts(res)
        setProductsLoading(false)
      })
      .catch((err: unknown) => {
        if (err instanceof DOMException && err.name === 'AbortError') return
        setProducts(null)
        setProductsLoading(false)
      })
    return () => controller.abort()
  }, [id, q, sort, page])

  const updateParams = useMemo(
    () =>
      (patch: { q?: string; sort?: string; page?: number }) => {
        setSearchParams(
          (prev) => {
            const next = new URLSearchParams(prev)
            const query = patch.q ?? q
            const tri = patch.sort ?? sort
            const p = patch.page ?? 1
            if (query) next.set('q', query)
            else next.delete('q')
            if (tri && tri !== 'recent') next.set('tri', tri)
            else next.delete('tri')
            if (p > 1) next.set('page', String(p))
            else next.delete('page')
            return next
          },
          { replace: patch.page === undefined }
        )
      },
    [setSearchParams, q, sort]
  )

  function onSearchInput(value: string) {
    setSearch(value)
    window.clearTimeout(debounceRef.current)
    debounceRef.current = window.setTimeout(() => updateParams({ q: value }), 300)
  }

  function goToPage(p: number) {
    updateParams({ page: p })
    document
      .getElementById('store-catalogue')
      ?.scrollIntoView({ behavior: 'smooth', block: 'start' })
  }

  if (storeError) {
    return (
      <div className="page">
        <EmptyState message="Boutique introuvable.">
          <Link className="btn btn-secondary" to="/boutiques">
            Retour aux boutiques
          </Link>
        </EmptyState>
      </div>
    )
  }

  const socials =
    store?.socials && !Array.isArray(store.socials) ? store.socials : {}
  const instagram = socials['instagram']
  const facebook = socials['facebook']
  const stats = store?.product_stats
  const location = store
    ? [store.city, store.region].filter(Boolean).join(', ') || 'Québec'
    : ''
  const lastSyncRel = formatRelativeDate(store?.last_sync ?? null)
  const priceRange =
    stats && stats.price_min !== null && stats.price_max !== null
      ? stats.price_min === stats.price_max
        ? formatPrice(stats.price_min)
        : `${formatPrice(stats.price_min)} – ${formatPrice(stats.price_max)}`
      : null
  const categories = (store?.category_breakdown ?? []).filter(
    (c): c is { key: string; n: number; label: string } =>
      c.key !== null && c.key !== '' && c.n > 0
  )
  const similar = store?.similar ?? []
  const hasCover = Boolean(coverUrl && coverReady)

  return (
    <div className="page page-store-detail">
      <nav className="breadcrumb" aria-label="Fil d'Ariane">
        <Link to="/boutiques">Boutiques</Link>
        <span aria-hidden="true">/</span>
        <span>{store?.name ?? '…'}</span>
      </nav>

      {store ? (
        <>
          {/* ---- Hero ------------------------------------------------- */}
          <header className={hasCover ? 'store-hero store-hero-covered' : 'store-hero'}>
            <div className="store-hero-cover" aria-hidden="true">
              {hasCover && (
                <div
                  className="store-hero-cover-img"
                  style={{ backgroundImage: `url("${coverUrl}")` }}
                />
              )}
              <div className="store-hero-scrim" />
            </div>
            <div className="store-hero-body">
              <StoreLogo
                storeId={store.id}
                name={store.name}
                logoUrl={store.logo_url}
                size="lg"
                ring
                className="store-hero-logo"
              />
              <h1 className="store-hero-name">{store.name}</h1>
              <div className="store-hero-chips">
                <span className="store-hero-chip">
                  <IconMapPin size={14} />
                  {location}
                </span>
                <OriginBadge origin={store.origin_class} withLabel />
              </div>
              <div className="store-hero-actions">
                <a
                  className="btn btn-primary store-hero-cta"
                  href={store.url}
                  target="_blank"
                  rel="noopener noreferrer"
                >
                  Visiter la boutique <IconExternal size={16} />
                </a>
                {instagram && (
                  <a
                    className="store-social-link"
                    href={instagram}
                    target="_blank"
                    rel="noopener noreferrer"
                    aria-label={`Instagram de ${store.name}`}
                    title="Instagram"
                  >
                    <IconInstagram size={19} />
                  </a>
                )}
                {facebook && (
                  <a
                    className="store-social-link"
                    href={facebook}
                    target="_blank"
                    rel="noopener noreferrer"
                    aria-label={`Facebook de ${store.name}`}
                    title="Facebook"
                  >
                    <IconFacebook size={19} />
                  </a>
                )}
                <span className="store-hero-domain">{hostnameOf(store.url)}</span>
              </div>
            </div>
          </header>

          {/* ---- About ------------------------------------------------ */}
          {(store.description_meta || store.origin_evidence) && (
            <section className="store-about">
              {store.description_meta && (
                <p className="store-about-text">{store.description_meta}</p>
              )}
              {store.origin_evidence && (
                <blockquote className="store-evidence">
                  « {store.origin_evidence} »
                </blockquote>
              )}
            </section>
          )}

          {/* ---- Stats band -------------------------------------------- */}
          <section className="store-stats" aria-label="Statistiques de la boutique">
            <div className="store-stat-tile">
              <span className="store-stat-value">
                {formatInt(stats?.n ?? store.product_count)}
              </span>
              <span className="store-stat-label">
                Produit{(stats?.n ?? store.product_count) === 1 ? '' : 's'} en ligne
              </span>
            </div>
            {priceRange && (
              <div className="store-stat-tile">
                <span className="store-stat-value store-stat-value-sm">
                  {priceRange}
                </span>
                <span className="store-stat-label">Fourchette de prix</span>
              </div>
            )}
            <div className="store-stat-tile">
              <span className="store-stat-value store-stat-value-sm">
                {store.region || 'Québec'}
              </span>
              <span className="store-stat-label">
                {store.platform ? `Région · ${store.platform}` : 'Région'}
              </span>
            </div>
            {lastSyncRel && (
              <div className="store-stat-tile">
                <span className="store-stat-value store-stat-value-sm">
                  {lastSyncRel}
                </span>
                <span className="store-stat-label">Dernière synchro</span>
              </div>
            )}
          </section>

          {/* ---- Category chips ---------------------------------------- */}
          {categories.length > 0 && (
            <section className="store-categories" aria-label="Catégories de la boutique">
              <div className="category-chips">
                {categories.map((c) => (
                  <Link
                    key={c.key}
                    className="chip"
                    to={`/produits?store=${encodeURIComponent(store.id)}&category=${encodeURIComponent(c.key)}`}
                  >
                    <span className="chip-icon">{categoryIcon(c.label)}</span>
                    {c.label}
                    <span className="chip-count">{formatInt(c.n)}</span>
                  </Link>
                ))}
              </div>
            </section>
          )}
        </>
      ) : (
        <div className="store-hero">
          <div className="store-hero-cover" aria-hidden="true">
            <div className="store-hero-scrim" />
          </div>
          <div className="store-hero-body">
            <Skeleton height="72px" width="72px" radius="50%" />
            <Skeleton height="2.2rem" width="55%" />
            <Skeleton height="1rem" width="35%" />
          </div>
        </div>
      )}

      {/* ---- Catalogue ------------------------------------------------ */}
      <section className="store-detail-products" id="store-catalogue">
        <div className="section-header">
          <h2>
            Catalogue
            {products && !productsLoading && <> ({formatInt(products.total)})</>}
          </h2>
        </div>
        <div className="store-catalogue-toolbar">
          <div className="store-catalogue-search">
            <span className="searchbar-icon">
              <IconSearch size={17} />
            </span>
            <input
              type="search"
              value={search}
              onChange={(e) => onSearchInput(e.target.value)}
              placeholder="Chercher dans la boutique…"
              aria-label="Chercher dans la boutique"
            />
          </div>
          <select
            value={sort}
            onChange={(e) => updateParams({ sort: e.target.value })}
            aria-label="Trier les produits"
          >
            {SORT_OPTIONS.map((o) => (
              <option key={o.value} value={o.value}>
                {o.label}
              </option>
            ))}
          </select>
        </div>
        {productsLoading ? (
          <SkeletonGrid count={12} />
        ) : (
          <>
            <ProductGrid
              products={products?.items ?? []}
              emptyMessage={
                q
                  ? 'Aucun produit ne correspond à cette recherche dans la boutique'
                  : 'Aucun produit trouvé pour cette boutique'
              }
            />
            {products && (
              <Pagination
                page={products.page}
                perPage={products.per_page}
                total={products.total}
                onPageChange={goToPage}
              />
            )}
          </>
        )}
      </section>

      {/* ---- Similar stores rail --------------------------------------- */}
      {similar.length > 0 && (
        <section className="rail store-similar">
          <header className="section-header">
            <h2>Boutiques similaires</h2>
          </header>
          <div className="rail-track">
            {similar.map((s) => (
              <Link
                key={s.id}
                to={`/boutiques/${encodeURIComponent(s.id)}`}
                className="card store-mini-card"
              >
                <StoreLogo
                  storeId={s.id}
                  name={s.name}
                  logoUrl={s.logo_url}
                  size="sm"
                />
                <span className="store-mini-body">
                  <span className="store-mini-name">{s.name}</span>
                  <span className="store-mini-meta">
                    {s.region || 'Québec'} · {formatInt(s.product_count)} produit
                    {s.product_count === 1 ? '' : 's'}
                  </span>
                </span>
              </Link>
            ))}
          </div>
        </section>
      )}

      {/* ---- Mobile sticky CTA (safe-area aware) ------------------------ */}
      {store && (
        <div className="store-cta-bar">
          <div className="store-cta-id">
            <StoreLogo
              storeId={store.id}
              name={store.name}
              logoUrl={store.logo_url}
              size="sm"
            />
            <span className="store-cta-name">{store.name}</span>
          </div>
          <a
            className="btn btn-primary store-cta-btn"
            href={store.url}
            target="_blank"
            rel="noopener noreferrer"
          >
            Visiter la boutique <IconExternal size={15} />
          </a>
        </div>
      )}
    </div>
  )
}
