import { PaginatedDocs } from 'payload'
import { Author, Book, HoldRequest, Repository, User } from '@/payload-types'
import { Button } from '../ui/button'
import Image from 'next/image'
import ApproveHoldRequestModal from './ApproveHoldRequestModal'
import { useCallback, useState } from 'react'
import CheckoutFromHoldModal from './CheckoutFromHoldModal'
import rejectHoldRequest from '@/serverActions/RejectHoldRequests'
import { getUserRepos } from '@/serverActions/GetUserRepos'
import { Loader2 } from 'lucide-react'
import { toast } from 'sonner'

type Props = {
  repos: PaginatedDocs<Repository> | null
  user: User
}
const HoldRequestNotifications = (props: Props) => {
  const [repos, setRepos] = useState<PaginatedDocs<Repository> | null>(props.repos)

  const [openedModalId, setOpenedModalId] = useState<number | null>(null)

  const totalHoldNotifications =
    repos?.docs
      .flatMap((r) => r.holdRequests?.docs)
      .filter((r) => {
        const request = r as HoldRequest
        return !request.isCheckedOut && !request.isRejected
      }).length || 0

  const [isRejectingId, setIsRejectingId] = useState<number | null>()

  const handleRejectHoldClick = useCallback(
    async (holdRequestId: number) => {
      if (isRejectingId) return
      setIsRejectingId(holdRequestId)
      const rejectRequest = await rejectHoldRequest({ holdRequestId })

      if (rejectRequest?.isRejected) {
        const updatedRepos = await getUserRepos({ userId: props.user.id })
        setRepos(updatedRepos)
        toast('Request was rejected')
      } else {
        toast('Error rejecting request')
      }

      setIsRejectingId(null)
    },
    [isRejectingId, setIsRejectingId, props.user.id],
  )

  const holdRequestsByRepoElements = repos?.docs.map((r) => {
    return (
      <ul key={r.id} role="list" className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
        {r.holdRequests?.docs
          ?.map((h) => {
            const hold = h as HoldRequest
            const book = hold.book as Book
            const authors = book.authors as Author[]
            const dateRequested = hold.dateRequested ? new Date(hold.dateRequested) : new Date()
            const holdingUntilDate = hold.holdingUntilDate
              ? new Date(hold.holdingUntilDate)
              : new Date()
            const userRequested = hold.userRequested as User
            const userName = `${userRequested.firstName} ${userRequested.lastName}`

            if (hold.isRejected) return null

            return (
              <li key={hold.id} className="col-span-1 rounded-lg shadow-sm border border-accent">
                <div className="flex w-full items-center justify-between space-x-6 p-6">
                  <div className="flex-1 truncate">
                    <div className="flex items-center space-x-3">
                      <h3 className="truncate text-sm font-medium text-foreground">{book.title}</h3>
                    </div>
                    <p className="mt-1 truncate  text-sm text-gray-500">
                      {authors.map((a) => a.lf).join(' | ')}
                    </p>
                    {hold.isHolding ? (
                      <span className="text-wrap">
                        <span className="mr-0.5 text-xs">{userName} Until</span>
                        <time className="inline-flex shrink-0 items-center rounded-full bg-background/20 px-1.5 py-0.5 text-xs font-medium text-emerald-600 ring-1 ring-emerald-600/20 ring-inset">
                          {holdingUntilDate.toLocaleDateString()}
                        </time>
                      </span>
                    ) : (
                      <span>
                        <time className="inline-flex shrink-0 items-center rounded-full bg-background/20 px-1.5 py-0.5 text-xs font-medium text-amber-500 ring-1 ring-amber-600/20 ring-inset">
                          {dateRequested.toLocaleDateString()}
                        </time>
                        <span className="text-xs">{userName}</span>
                      </span>
                    )}
                  </div>
                  <img
                    alt=""
                    className="h-16 shrink-0 rounded bg-gray-300"
                    src={
                      book.isbn
                        ? `https://covers.openlibrary.org/b/isbn/${book.isbn}-M.jpg`
                        : '/images/book-48.svg'
                    }
                  />
                </div>
                <div>
                  <div className="flex gap-2 justify-around">
                    <Button
                      className="inline-flex flex-1 items-center justify-center gap-3 rounded-bl-lg border border-transparent py-4 text-sm font-semibold text-foreground bg-foreground/5 hover:bg-red-400/10 cursor-pointer [&:not(:disabled)]:hover:scale-105"
                      disabled={!!isRejectingId}
                      onClick={() => handleRejectHoldClick(hold.id)}
                    >
                      {isRejectingId === hold.id ? (
                        <>
                          <Loader2 className="animate-spin size-[24px] text-red-200 dark:text-red-700" />
                          <span className="text-red-200 dark:text-red-700">Rejecting</span>
                        </>
                      ) : (
                        <>
                          <Image
                            width={24}
                            height={24}
                            src="/images/reject.svg"
                            alt="approve hold"
                          />
                          <span>Reject</span>
                        </>
                      )}
                    </Button>

                    <Button
                      className="inline-flex flex-1 items-center justify-center gap-3 rounded-br-lg border border-transparent py-4 text-sm font-semibold text-foreground bg-emerald-400/30 hover:bg-emerald-300/60 cursor-pointer hover:scale-105"
                      disabled={!!isRejectingId || !!openedModalId}
                      onClick={() => setOpenedModalId(hold.id)}
                    >
                      <Image width={24} height={24} src="/images/approve.svg" alt="approve hold" />
                      <span>{hold.isHolding ? 'Checkout' : 'Approve'}</span>
                    </Button>

                    {hold.isHolding ? (
                      <CheckoutFromHoldModal
                        isOpen={openedModalId === hold.id}
                        onOpenChange={() => setOpenedModalId(null)}
                        holdRequest={hold}
                      />
                    ) : (
                      <ApproveHoldRequestModal
                        isOpen={openedModalId === hold.id}
                        onOpenChange={() => setOpenedModalId(null)}
                        holdRequest={hold}
                      />
                    )}
                  </div>
                </div>
              </li>
            )
          })
          .filter((element) => !!element)}
      </ul>
    )
  })

  return (
    <section className="py-6">
      <div className="mb-4 flex justify-between items-end">
        <h3 className="px-4 text-lg font-semibold">Incoming Hold Requests</h3>
        {!!totalHoldNotifications && (
          <span className="font-bold">{totalHoldNotifications} Unaddressed</span>
        )}
      </div>
      {holdRequestsByRepoElements}
    </section>
  )
}

export default HoldRequestNotifications
