'use client'

import { useEffect, useState } from 'react'
import { toast } from 'react-toastify'
import { Button } from 'flowbite-react'
import { useRouter, useSearchParams } from 'next/navigation'

import * as PaginationConstant from '@/lib/constants/pagination'
import { paginationDefaultData } from '@/lib/data/pagination'
import * as agentServices from '@/lib/services/agent-services'
import buttonTheme from '@/lib/themes/button'
import Pagination from '@/lib/components/Pagination'
import { constructSearchURL } from '@/lib/utils/url'
import { useAuth } from '@/lib/context/AuthContext'
import { AgentData, SearchFormProps } from './types'
import SearchForm from './partials/SearchForm'
import DataTable from './partials/DataTable'
import ModalDeleteAgent from './partials/ModalDeleteAgent'

export default function MainContent() {
  const router = useRouter()
  const searchParams = useSearchParams()
  const [selectedAgent, setSelectedAgent] = useState<AgentData | null>(null)
  const [agents, setAgents] = useState<Pagination<AgentData>>(
    paginationDefaultData,
  )
  const [refreshTrigger, setRefreshTrigger] = useState(0)
  const [searchForm, setSearchForm] = useState<SearchFormProps>({
    searching: false,
    params: {
      search: searchParams.get('search') || '',
      category: searchParams.get('category') || '',
      guest_market: searchParams.get('guest_market') || '',
      page: searchParams.get('page') ? Number(searchParams.get('page')) : 1,
      limit: searchParams.get('limit')
        ? Number(searchParams.get('limit'))
        : PaginationConstant.MIN_DATA_PER_PAGE,
    },
  })
  const [isLoadingInitial, setIsLoadingInitial] = useState(true)
  const [agentModal, setAgentModal] = useState<ModalState<AgentData>>({
    isOpened: false,
    processing: false,
    type: 'delete',
    data: null,
  })
  const { user } = useAuth()

  async function handleConfirmDelete() {
    if (!selectedAgent?.id) return

    setAgentModal((prev) => ({ ...prev, processing: true }))

    try {
      await agentServices.deleteAgent(selectedAgent.id)

      const updatedAgents = (await agentServices.getAgents({
        search: searchParams.get('search') || '',
        category: searchParams.get('category') || '',
        guest_market: searchParams.get('guest_market') || '',
        page: Number(searchParams.get('page') ?? 1),
        limit: Number(
          searchParams.get('limit') ?? PaginationConstant.MIN_DATA_PER_PAGE,
        ),
      })) as Pagination<AgentData>

      if (updatedAgents.data.length === 0 && updatedAgents.current_page > 1) {
        const prevPage = updatedAgents.current_page - 1

        setSearchForm((prev) => ({
          ...prev,
          params: {
            ...prev.params,
            page: prevPage,
            limit: agents.per_page,
          },
        }))

        // Directly pass the updated state value
        return router.push(
          constructSearchURL('/agents', {
            ...searchForm.params,
            page: prevPage,
            limit: agents.per_page,
          }),
        )
      }

      setAgents(updatedAgents)
      setSelectedAgent(null)
      setAgentModal({
        ...agentModal,
        type: 'delete',
        isOpened: false,
        processing: false,
      })

      toast.success('Agent deleted successfully!')
    } catch {
      toast.error(
        'Oops! something went wrong on delete agent data. Please try again later',
      )
    }
  }

  async function handleSearchSubmit(e?: React.FormEvent) {
    e?.preventDefault()

    setSearchForm((prev) => ({ ...prev, searching: true }))
    setAgents(paginationDefaultData)

    const newUrl = constructSearchURL('/agents', {
      ...searchForm.params,
      page: 1,
    })

    // Check if the URL would be the same (search with same parameters)
    const currentUrl = `${window.location.pathname}${window.location.search}`

    if (currentUrl === newUrl) {
      // If URL is the same, trigger a refresh instead of navigation
      setRefreshTrigger((prev) => prev + 1)
      return
    }

    return router.push(newUrl)
  }

  async function handlePageChange(page: number) {
    if (isNaN(page)) {
      setSearchForm((prev) => ({
        ...prev,
        params: {
          ...prev.params,
          page: 1,
        },
      }))

      // Directly pass the updated state value
      return router.push(
        constructSearchURL('/agents', {
          ...searchForm.params,
          page: 1,
        }),
      )
    }

    setSearchForm((prev) => ({
      ...prev,
      params: {
        ...prev.params,
        page,
      },
    }))

    // Directly pass the updated state value
    return router.push(
      constructSearchURL('/agents', {
        ...searchForm.params,
        page,
      }),
    )
  }

  function handleLimitChange(limit: number) {
    if (isNaN(Number(limit))) {
      setSearchForm((prev) => ({
        ...prev,
        params: {
          ...prev.params,
          page: 1,
          limit: PaginationConstant.MIN_DATA_PER_PAGE,
        },
      }))

      // Directly pass the updated state value
      return router.push(
        constructSearchURL('/agents', {
          ...searchForm.params,
          page: 1,
          limit: PaginationConstant.MIN_DATA_PER_PAGE,
        }),
      )
    }

    limit =
      Number(limit) < PaginationConstant.MIN_DATA_PER_PAGE ||
      Number(limit) > PaginationConstant.MAX_DATA_PER_PAGE
        ? PaginationConstant.MIN_DATA_PER_PAGE
        : limit

    setSearchForm((prev) => ({
      ...prev,
      params: {
        ...prev.params,
        page: 1,
        limit,
      },
    }))

    // Directly pass the updated state value
    return router.push(
      constructSearchURL('/agents', {
        ...searchForm.params,
        page: 1,
        limit,
      }),
    )
  }

  useEffect(() => {
    setIsLoadingInitial(true)

    agentServices
      .getAgents({
        search: searchParams.get('search') || '',
        category: searchParams.get('category') || '',
        guest_market: searchParams.get('guest_market') || '',
        page: Number(searchParams.get('page') ?? 1),
        limit: Number(
          searchParams.get('limit') ?? PaginationConstant.MIN_DATA_PER_PAGE,
        ),
      })
      .then((data) => {
        setAgents(data as Pagination<AgentData>)
      })
      .catch(() => {
        toast.error('Failed to load agents. Please try again.')
      })
      .finally(() => {
        setIsLoadingInitial(false)
        setSearchForm((prev) => ({ ...prev, searching: false }))
      })
  }, [searchParams, refreshTrigger])

  // Authorize User
  useEffect(() => {
    if (user && user.role !== 'super_admin' && user.role !== 'manager') {
      router.replace('/')
    }
  }, [user, router])

  return (
    <section className="mt-8">
      <div>
        <h1 className="text-3xl font-semibold text-black mb-2">Agents (B2B)</h1>
        <p className="font-medium text-slate-500">
          Following are the list of agents. You can manage them here.
        </p>

        <Button
          theme={buttonTheme.button}
          color="default"
          className="mt-4"
          onClick={() => {
            router.push('/agents/create')
          }}
        >
          Create Agent
        </Button>
      </div>

      <SearchForm
        searchForm={searchForm}
        handleSearch={handleSearchSubmit}
        setSearchForm={setSearchForm}
      />

      <DataTable
        agents={searchForm.searching ? [] : agents.data}
        isLoading={isLoadingInitial}
        setModal={setAgentModal}
        setAgent={setSelectedAgent}
      />

      {!isLoadingInitial && (
        <Pagination
          currentPage={agents.current_page}
          lastPage={agents.last_page}
          limit={
            searchParams.get('limit')
              ? Number(searchParams.get('limit'))
              : PaginationConstant.MIN_DATA_PER_PAGE
          }
          from={agents.from}
          to={agents.to}
          total={agents.total}
          handlePageChange={handlePageChange}
          handleLimitChange={handleLimitChange}
        />
      )}

      <ModalDeleteAgent
        isOpen={agentModal.isOpened && agentModal.type === 'delete'}
        agent={selectedAgent}
        isDeleting={agentModal.processing && agentModal.type === 'delete'}
        onClose={() => setAgentModal({ ...agentModal, isOpened: false })}
        onConfirm={handleConfirmDelete}
      />
    </section>
  )
}
