'use client'

import { useState, useMemo, useRef, useEffect, useCallback } from 'react'
import {
  Modal,
  Button,
  Checkbox,
  ModalHeader,
  ModalBody,
  ModalFooter,
} from 'flowbite-react'
import { LuSearch, LuLink } from 'react-icons/lu'
import { toast } from 'react-toastify'

import { getReferralLinks } from '@/lib/services/referral-link-services'
import { ReferralLink } from '@/app/(dashboard)/referral-links/types'
import { paginationDefaultData } from '@/lib/data/pagination'
import * as PaginationConstant from '@/lib/constants/pagination'

interface ReferralLinkSearchModalProps {
  isOpen: boolean
  excludeIds: number[]
  onClose: () => void
  onSelect: (referralLinks: ReferralLink[]) => void
}

export default function ReferralLinkSearchModal({
  isOpen,
  excludeIds,
  onClose,
  onSelect,
}: ReferralLinkSearchModalProps) {
  const [searchValue, setSearchValue] = useState('')
  const [debouncedSearch, setDebouncedSearch] = useState('')
  const [referralLinks, setReferralLinks] = useState<Pagination<ReferralLink>>(
    paginationDefaultData,
  )
  const [isLoading, setIsLoading] = useState(true)
  const [isLoadingMore, setIsLoadingMore] = useState(false)
  const [selectedLinks, setSelectedLinks] = useState<ReferralLink[]>([])
  const inputRef = useRef<HTMLInputElement>(null)
  const sentinelRef = useRef<HTMLDivElement>(null)
  const scrollContainerRef = useRef<HTMLDivElement>(null)

  const hasMore = useMemo(
    () =>
      !!referralLinks.next_page_url &&
      referralLinks.current_page < referralLinks.last_page,
    [referralLinks],
  )

  // Debounce search input
  useEffect(() => {
    const timer = setTimeout(() => {
      setDebouncedSearch(searchValue)
    }, 300)

    return () => clearTimeout(timer)
  }, [searchValue])

  // Fetch referral links (initial + on search change)
  useEffect(() => {
    if (!isOpen) return

    async function fetchReferralLinks() {
      setIsLoading(true)

      try {
        const data = await getReferralLinks({
          page: 1,
          limit: PaginationConstant.MIN_DATA_PER_PAGE,
          link_name: debouncedSearch || undefined,
        })
        setReferralLinks(data)
      } catch {
        toast.error('Error fetching referral links.')
      } finally {
        setIsLoading(false)
      }
    }

    fetchReferralLinks()
  }, [isOpen, debouncedSearch])

  // Load more pages for infinite scroll
  const loadMore = useCallback(async () => {
    if (isLoadingMore || !hasMore) return

    setIsLoadingMore(true)

    try {
      const data = await getReferralLinks({
        page: referralLinks.current_page + 1,
        limit: PaginationConstant.MIN_DATA_PER_PAGE,
        link_name: debouncedSearch || undefined,
      })

      setReferralLinks((prev) => ({
        ...data,
        data: [...prev.data, ...data.data],
      }))
    } catch {
      toast.error('Error loading more referral links.')
    } finally {
      setIsLoadingMore(false)
    }
  }, [referralLinks, hasMore, isLoadingMore, debouncedSearch])

  // IntersectionObserver for infinite scroll
  useEffect(() => {
    if (!sentinelRef.current || !scrollContainerRef.current) return

    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting && hasMore && !isLoadingMore) {
          loadMore()
        }
      },
      {
        root: scrollContainerRef.current,
        threshold: 0.1,
      },
    )

    observer.observe(sentinelRef.current)

    return () => observer.disconnect()
  }, [hasMore, isLoadingMore, loadMore])

  // Reset state when modal opens/closes
  useEffect(() => {
    if (isOpen) {
      setSearchValue('')
      setDebouncedSearch('')
      setSelectedLinks([])
      setReferralLinks(paginationDefaultData)
      setTimeout(() => {
        inputRef.current?.focus()
      }, 100)
    }
  }, [isOpen])

  // Filter out already-selected referral links
  const availableLinks = referralLinks.data.filter(
    (link) => !excludeIds.includes(link.id),
  )

  function isSelected(link: ReferralLink) {
    return selectedLinks.some((s) => s.id === link.id)
  }

  function toggleSelection(link: ReferralLink) {
    setSelectedLinks((prev) =>
      isSelected(link) ? prev.filter((s) => s.id !== link.id) : [...prev, link],
    )
  }

  function toggleSelectAll() {
    if (selectedLinks.length === availableLinks.length) {
      setSelectedLinks([])
    } else {
      setSelectedLinks([...availableLinks])
    }
  }

  function handleConfirm() {
    onSelect(selectedLinks)
    onClose()
  }

  function handleCancel() {
    onClose()
  }

  return (
    <Modal show={isOpen} onClose={handleCancel} size="2xl" position="center">
      <ModalHeader>
        <div className="flex items-center gap-3">
          <div className="w-8 h-8 bg-blue-100 rounded-full flex items-center justify-center">
            <LuLink className="w-4 h-4 text-blue-600" />
          </div>
          <div>
            <h3 className="text-xl font-semibold text-gray-900">
              Select Referral Links
            </h3>
            <p className="text-sm text-gray-500 mt-1">
              Search and select referral links to assign to this agent
            </p>
          </div>
        </div>
      </ModalHeader>

      <ModalBody className="p-0">
        {/* Search Input */}
        <div className="p-6 border-b border-gray-200">
          <div className="relative">
            <LuSearch className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
            <input
              type="text"
              placeholder="Search by link name..."
              value={searchValue}
              ref={inputRef}
              onChange={(e) => setSearchValue(e.target.value)}
              className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm"
            />
          </div>
        </div>

        {/* Select All */}
        {!isLoading && availableLinks.length > 0 && (
          <div className="px-6 py-3 border-b border-gray-200 bg-gray-50">
            <label className="flex items-center gap-3 cursor-pointer">
              <Checkbox
                color="blue"
                checked={
                  selectedLinks.length === availableLinks.length &&
                  availableLinks.length > 0
                }
                onChange={toggleSelectAll}
              />
              <span className="text-sm font-medium text-gray-700">
                Select All ({selectedLinks.length}/{availableLinks.length})
              </span>
            </label>
          </div>
        )}

        {/* Link List */}
        <div className="max-h-96 overflow-y-auto" ref={scrollContainerRef}>
          {isLoading ? (
            <div className="p-4 space-y-3">
              {Array.from({ length: 5 }).map((_, i) => (
                <div key={i} className="flex items-center gap-3 p-3">
                  <div className="w-4 h-4 bg-gray-200 rounded animate-pulse" />
                  <div className="flex-1 space-y-2">
                    <div className="h-4 bg-gray-200 rounded animate-pulse w-3/4" />
                    <div className="h-3 bg-gray-200 rounded animate-pulse w-1/2" />
                  </div>
                </div>
              ))}
            </div>
          ) : availableLinks.length > 0 ? (
            <div>
              {availableLinks.map((link, index) => (
                <label
                  key={link.id}
                  className={`flex items-center gap-3 px-6 py-4 cursor-pointer hover:bg-gray-50 transition-colors duration-200 ${
                    isSelected(link) ? 'bg-blue-50' : ''
                  } ${index !== availableLinks.length - 1 ? 'border-b border-gray-100' : ''}`}
                >
                  <Checkbox
                    color="blue"
                    checked={isSelected(link)}
                    onChange={() => toggleSelection(link)}
                  />
                  <div className="flex-1 min-w-0">
                    <div className="font-medium text-gray-900">
                      {link.link_name}
                    </div>
                    <div className="text-sm text-gray-500">
                      Merchant: {link.user?.name || 'N/A'}
                    </div>
                  </div>
                </label>
              ))}

              {/* Infinite scroll sentinel */}
              {hasMore && (
                <div ref={sentinelRef} className="p-4 text-center">
                  {isLoadingMore && (
                    <span className="text-sm text-gray-500 animate-pulse">
                      Loading more referral links...
                    </span>
                  )}
                </div>
              )}
            </div>
          ) : (
            <div className="px-4 py-8 text-center text-gray-500">
              <LuLink className="w-12 h-12 mx-auto mb-3 text-gray-300" />
              <p className="text-lg font-medium mb-1">
                No referral links found
              </p>
              <p className="text-sm">
                {excludeIds.length > 0
                  ? 'All available referral links have already been added'
                  : 'Try adjusting your search criteria'}
              </p>
            </div>
          )}
        </div>
      </ModalBody>

      <ModalFooter className="flex justify-between gap-3">
        <span className="text-sm text-gray-500">
          {selectedLinks.length} link{selectedLinks.length !== 1 ? 's' : ''}{' '}
          selected
        </span>
        <div className="flex gap-3">
          <Button color="light" onClick={handleCancel}>
            Cancel
          </Button>
          <Button
            color="blue"
            onClick={handleConfirm}
            disabled={selectedLinks.length === 0}
          >
            Add Selected
          </Button>
        </div>
      </ModalFooter>
    </Modal>
  )
}
