import { useEffect, useMemo, useState } from 'react'
import { Plus } from 'lucide-react'
import { Breadcrumbs } from '../components/Breadcrumbs'
import { ConfirmDeleteModal } from '../components/ConfirmDeleteModal'
import { EditStoreItemsModal } from '../components/EditStoreItemsModal'
import { PickStoreSpecialItemsModal } from '../components/PickStoreSpecialItemsModal'
import { PickStoreVariantModal } from '../components/PickStoreVariantModal'
import { ShoppingCartModal } from '../components/ShoppingCartModal'
import { StoreItemDiscountModal } from '../components/StoreItemDiscountModal'
import { StoreItemFestivalModal } from '../components/StoreItemFestivalModal'
import { StoreSpecialCarousel } from '../components/StoreSpecialCarousel'
import { StoreSpecialModal } from '../components/StoreSpecialModal'
import { useDraftCart } from '../context/DraftCartContext'
import { useToast } from '../context/ToastContext'
import { ApiError } from '../lib/api'
import {
  createStoreSpecial,
  deleteStoreSpecial,
  listStoreSpecials,
  updateStoreSpecial,
} from '../services/storeSpecialService'
import type { StoreItem } from '../services/storeItemService'
import type { StoreSpecial } from '../types/storeSpecial'
import type { StoreProductListing } from '../utils/storeProductGroups'
import pageStyles from '../components/PageContent.module.css'
import fabStyles from './StoreItemsPage.module.css'
import styles from './StoreSpecialsPage.module.css'

export function StoreSpecialsPage() {
  const { itemCount, hasItems, addVariant } = useDraftCart()
  const { showToast } = useToast()
  const [specials, setSpecials] = useState<StoreSpecial[]>([])
  const [isLoading, setIsLoading] = useState(true)
  const [isSaving, setIsSaving] = useState(false)
  const [error, setError] = useState('')

  const [createOpen, setCreateOpen] = useState(false)
  const [editSpecialTarget, setEditSpecialTarget] = useState<StoreSpecial | null>(null)
  const [deleteSpecialTarget, setDeleteSpecialTarget] = useState<StoreSpecial | null>(null)
  const [pickItemsTarget, setPickItemsTarget] = useState<StoreSpecial | null>(null)

  const [editListingTarget, setEditListingTarget] = useState<StoreProductListing | null>(null)
  const [discountTarget, setDiscountTarget] = useState<StoreProductListing | null>(null)
  const [festivalTarget, setFestivalTarget] = useState<StoreProductListing | null>(null)
  const [removeTarget, setRemoveTarget] = useState<{
    special: StoreSpecial
    listing: StoreProductListing
  } | null>(null)
  const [pickVariantTarget, setPickVariantTarget] = useState<StoreProductListing | null>(null)
  const [cartOpen, setCartOpen] = useState(false)

  const productItems = useMemo(() => {
    const target = editListingTarget ?? discountTarget ?? festivalTarget
    if (!target) return []
    return target.variants
  }, [editListingTarget, discountTarget, festivalTarget])

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

  async function loadSpecials(signal?: AbortSignal) {
    setIsLoading(true)
    setError('')

    try {
      const data = await listStoreSpecials(1, 50, signal)
      setSpecials(data.items)
    } catch (err) {
      if (err instanceof DOMException && err.name === 'AbortError') return
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError('Unable to load special categories.')
      }
    } finally {
      setIsLoading(false)
    }
  }

  function replaceSpecial(updated: StoreSpecial) {
    setSpecials((prev) => prev.map((entry) => (entry.id === updated.id ? updated : entry)))
  }

  function mergeUpdatedItems(updated: StoreItem[]) {
    const byId = new Map(updated.map((item) => [item.id, item]))
    setSpecials((prev) =>
      prev.map((special) => ({
        ...special,
        items: special.items.map((storeItem) => ({
          ...storeItem,
          variants: storeItem.variants.map((variant) => {
            const next = byId.get(variant.id)
            if (!next) return variant
            return {
              ...variant,
              price: next.price,
              discountedPrice: next.discountedPrice,
              stockQuantity: next.stockQuantity,
              rewardPoints: next.rewardPoints,
              isFestival: next.isFestival,
            }
          }),
        })),
      })),
    )
  }

  function replaceProductItems(updated: StoreItem[]) {
    const productId = updated[0]?.productId ?? editListingTarget?.productId
    if (!productId) return

    setSpecials((prev) =>
      prev.map((special) => ({
        ...special,
        items: special.items.map((storeItem) => {
          if (storeItem.productId !== productId) return storeItem
          if (updated.length === 0) return storeItem

          return {
            ...storeItem,
            productTitle: updated[0].productTitle,
            productNameFa: updated[0].productNameFa,
            productImage: updated[0].productImage,
            variants: updated.map((item) => ({
              id: item.id,
              label: item.label,
              selections: item.selections,
              price: item.price,
              discountedPrice: item.discountedPrice,
              stockQuantity: item.stockQuantity,
              rewardPoints: item.rewardPoints,
              isFestival: item.isFestival,
              sortOrder: item.sortOrder,
            })),
          }
        }),
      })),
    )
  }

  async function handleCreateSpecial(title: string) {
    setIsSaving(true)
    setError('')

    try {
      const result = await createStoreSpecial({
        title,
        sortOrder: specials.length,
      })
      setSpecials((prev) => [...prev, result.special])
      setCreateOpen(false)
      showToast('Special category created.', 'success')
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError('Unable to create special category.')
      }
    } finally {
      setIsSaving(false)
    }
  }

  async function handleEditSpecial(title: string) {
    if (!editSpecialTarget) return

    setIsSaving(true)
    setError('')

    try {
      const result = await updateStoreSpecial(editSpecialTarget.id, { title })
      replaceSpecial(result.special)
      setEditSpecialTarget(null)
      showToast('Special category updated.', 'success')
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError('Unable to update special category.')
      }
    } finally {
      setIsSaving(false)
    }
  }

  async function confirmDeleteSpecial() {
    if (!deleteSpecialTarget) return

    setIsSaving(true)
    setError('')

    try {
      await deleteStoreSpecial(deleteSpecialTarget.id)
      setSpecials((prev) => prev.filter((entry) => entry.id !== deleteSpecialTarget.id))
      setDeleteSpecialTarget(null)
      showToast('Special category deleted.', 'success')
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError('Unable to delete special category.')
      }
    } finally {
      setIsSaving(false)
    }
  }

  async function handleAddItems(storeItemIds: string[]) {
    if (!pickItemsTarget) return

    const existingIds = pickItemsTarget.items.map((item) => item.id)
    const nextIds = [...existingIds, ...storeItemIds]

    setIsSaving(true)
    setError('')

    try {
      const result = await updateStoreSpecial(pickItemsTarget.id, {
        storeItemIds: nextIds,
      })
      replaceSpecial(result.special)
      setPickItemsTarget(null)
      showToast('Store items added to special category.', 'success')
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError('Unable to add store items.')
      }
    } finally {
      setIsSaving(false)
    }
  }

  async function confirmRemoveFromSpecial() {
    if (!removeTarget) return

    const { special, listing } = removeTarget
    const storeItemId = listing.representative.storeItemId ?? listing.representative.id
    const nextIds = special.items
      .map((item) => item.id)
      .filter((id) => id !== storeItemId)

    setIsSaving(true)
    setError('')

    try {
      const result = await updateStoreSpecial(special.id, {
        storeItemIds: nextIds,
      })
      replaceSpecial(result.special)
      setRemoveTarget(null)
      showToast('Removed from special category.', 'success')
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError('Unable to remove store item.')
      }
    } finally {
      setIsSaving(false)
    }
  }

  function handleAddToCart(listing: StoreProductListing) {
    if (listing.variantCount > 1) {
      setPickVariantTarget(listing)
      return
    }

    const variant = listing.variants[0]
    if (!variant) return

    const feedback = addVariant(variant)
    if (feedback) {
      showToast(feedback, 'error')
      return
    }

    showToast('Added to shopping cart.', 'success')
  }

  function handleVariantPicked(variant: StoreItem) {
    const feedback = addVariant(variant)
    setPickVariantTarget(null)
    if (feedback) {
      showToast(feedback, 'error')
      return
    }
    showToast('Added to shopping cart.', 'success')
  }

  return (
    <main className={pageStyles.content}>
      <Breadcrumbs
        items={[
          { label: 'Dashboard', href: '/' },
          { label: 'Website', href: '/website' },
          { label: 'Special Items' },
        ]}
      />

      <div className={pageStyles.pageHeader}>
        <div>
          <h2 className={pageStyles.pageTitle}>Special Items</h2>
          <p className={pageStyles.pageSubtitle}>
            Curate featured store items into categories for your website carousels.
          </p>
        </div>
      </div>

      {error && <p className={styles.error}>{error}</p>}

      {isLoading ? (
        <p className={styles.empty}>Loading special categories...</p>
      ) : specials.length === 0 ? (
        <p className={styles.empty}>
          No special categories yet. Use the + button to create one, then add store items to each
          carousel.
        </p>
      ) : (
        <div className={styles.carousels}>
          {specials.map((special) => (
            <StoreSpecialCarousel
              key={special.id}
              special={special}
              onAddItems={setPickItemsTarget}
              onEditSpecial={setEditSpecialTarget}
              onDeleteSpecial={setDeleteSpecialTarget}
              onOpenListing={setEditListingTarget}
              onEditListing={setEditListingTarget}
              onDiscountListing={setDiscountTarget}
              onFestivalListing={setFestivalTarget}
              onRemoveListing={(specialEntry, listing) =>
                setRemoveTarget({ special: specialEntry, listing })
              }
              onAddToCart={handleAddToCart}
            />
          ))}
        </div>
      )}

      <div className={fabStyles.fabDock}>
        {hasItems && (
          <button
            type="button"
            className={fabStyles.cartFabStrip}
            onClick={() => setCartOpen(true)}
            aria-label={`Open shopping cart, ${itemCount} items`}
          >
            <span className={fabStyles.cartFabCount}>{itemCount}</span>
            <span className={fabStyles.cartFabLabel}>
              {itemCount === 1 ? 'item in cart' : 'items in cart'}
            </span>
          </button>
        )}
        <button
          type="button"
          className={fabStyles.addFab}
          onClick={() => setCreateOpen(true)}
          aria-label="Add special category"
        >
          <Plus size={24} />
        </button>
      </div>

      <StoreSpecialModal
        open={createOpen}
        onClose={() => !isSaving && setCreateOpen(false)}
        onSubmit={handleCreateSpecial}
        isSubmitting={isSaving}
      />

      <StoreSpecialModal
        open={!!editSpecialTarget}
        onClose={() => !isSaving && setEditSpecialTarget(null)}
        onSubmit={handleEditSpecial}
        initialTitle={editSpecialTarget?.title ?? ''}
        title="Edit Special Category"
        submitLabel="Save"
        isSubmitting={isSaving}
      />

      <PickStoreSpecialItemsModal
        open={!!pickItemsTarget}
        specialTitle={pickItemsTarget?.title ?? ''}
        existingStoreItemIds={pickItemsTarget?.items.map((item) => item.id) ?? []}
        onClose={() => !isSaving && setPickItemsTarget(null)}
        onConfirm={handleAddItems}
        isSubmitting={isSaving}
      />

      <EditStoreItemsModal
        open={!!editListingTarget}
        productTitle={editListingTarget?.productTitle ?? ''}
        productNameFa={editListingTarget?.productNameFa ?? ''}
        items={productItems}
        onClose={() => setEditListingTarget(null)}
        onSaved={replaceProductItems}
      />

      <StoreItemDiscountModal
        open={!!discountTarget}
        productTitle={discountTarget?.productTitle ?? ''}
        items={productItems}
        onClose={() => setDiscountTarget(null)}
        onSaved={mergeUpdatedItems}
      />

      <StoreItemFestivalModal
        open={!!festivalTarget}
        productTitle={festivalTarget?.productTitle ?? ''}
        items={productItems}
        onClose={() => setFestivalTarget(null)}
        onSaved={mergeUpdatedItems}
      />

      <ConfirmDeleteModal
        open={!!deleteSpecialTarget}
        title="Delete Special Category"
        message={
          deleteSpecialTarget
            ? `Delete "${deleteSpecialTarget.title}"? Store items will remain in your catalog.`
            : ''
        }
        onConfirm={() => void confirmDeleteSpecial()}
        onCancel={() => !isSaving && setDeleteSpecialTarget(null)}
      />

      <ConfirmDeleteModal
        open={!!removeTarget}
        title="Remove from Special"
        message={
          removeTarget
            ? `Remove "${removeTarget.listing.productTitle}" from "${removeTarget.special.title}"?`
            : ''
        }
        onConfirm={() => void confirmRemoveFromSpecial()}
        onCancel={() => !isSaving && setRemoveTarget(null)}
      />

      <PickStoreVariantModal
        open={!!pickVariantTarget}
        productTitle={pickVariantTarget?.productTitle ?? ''}
        productNameFa={pickVariantTarget?.productNameFa ?? ''}
        variants={pickVariantTarget?.variants ?? []}
        onClose={() => setPickVariantTarget(null)}
        onSelect={handleVariantPicked}
      />

      <ShoppingCartModal
        open={cartOpen}
        onClose={() => setCartOpen(false)}
        onOrderCreated={() => void loadSpecials()}
      />
    </main>
  )
}
