'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 buttonTheme from '@/lib/themes/button'
import Pagination from '@/lib/components/Pagination'
import { constructSearchURL } from '@/lib/utils/url'
import { useAuth } from '@/lib/context/AuthContext'
import * as travelPartnerServices from '@/lib/services/travel-partner-services'
import { TravelPartner } from '@/lib/types/partner'
import { SearchFormProps } from './types'
import SearchForm from './partials/SearchForm'
import DataTable from './partials/DataTable'
import ModalDeleteTravelPartner from './partials/ModalDeleteTravelPartner'

export default function MainContent() {
  const router = useRouter()
  const searchParams = useSearchParams()
  const [selectedTravelPartner, setSelectedTravelPartner] =
    useState<TravelPartner | null>(null)
  const [travelPartners, setTravelPartners] = useState<
    Pagination<TravelPartner>
  >(paginationDefaultData)
  const [refreshTrigger, setRefreshTrigger] = useState(0)
  const [searchForm, setSearchForm] = useState<SearchFormProps>({
    searching: false,
    params: {
      search: searchParams.get('search') || '',
      partner_category: searchParams.get('partner_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,
      has_links: searchParams.get('has_links')
        ? searchParams.get('has_links') === 'true'
        : undefined,
      merchant_id: searchParams.get('merchant_id')
        ? Number(searchParams.get('merchant_id'))
        : undefined,
    },
  })
  const [isLoadingInitial, setIsLoadingInitial] = useState(true)
  const [travelPartnerModel, setTravelPartnerModal] = useState<
    ModalState<TravelPartner>
  >({
    isOpened: false,
    processing: false,
    type: 'delete',
    data: null,
  })
  const { user } = useAuth()

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

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

    try {
      await travelPartnerServices.deleteTravelPartner(selectedTravelPartner.id)

      const updatedTravelPartners =
        (await travelPartnerServices.getTravelPartners({
          search: searchParams.get('search') || '',
          partner_category: searchParams.get('partner_category') || '',
          guest_market: searchParams.get('guest_market') || '',
          page: Number(searchParams.get('page') ?? 1),
          limit: Number(
            searchParams.get('limit') ?? PaginationConstant.MIN_DATA_PER_PAGE,
          ),
          has_links: searchParams.get('has_links')
            ? searchParams.get('has_links') === 'true'
            : undefined,
          merchant_id: searchParams.get('merchant_id')
            ? Number(searchParams.get('merchant_id'))
            : undefined,
        })) as Pagination<TravelPartner>

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

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

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

      setTravelPartners(updatedTravelPartners)
      setSelectedTravelPartner(null)
      setTravelPartnerModal({
        ...travelPartnerModel,
        type: 'delete',
        isOpened: false,
        processing: false,
      })

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

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

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

    const newUrl = constructSearchURL('/travel-partners', {
      ...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('/travel-partners', {
          ...searchForm.params,
          page: 1,
        }),
      )
    }

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

    // Directly pass the updated state value
    return router.push(
      constructSearchURL('/travel-partners', {
        ...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('/travel-partners', {
          ...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('/travel-partners', {
        ...searchForm.params,
        page: 1,
        limit,
      }),
    )
  }

  useEffect(() => {
    setIsLoadingInitial(true)

    travelPartnerServices
      .getTravelPartners({
        search: searchParams.get('search') || '',
        partner_category: searchParams.get('partner_category') || '',
        guest_market: searchParams.get('guest_market') || '',
        page: Number(searchParams.get('page') ?? 1),
        limit: Number(
          searchParams.get('limit') ?? PaginationConstant.MIN_DATA_PER_PAGE,
        ),
        has_links: searchParams.get('has_links')
          ? searchParams.get('has_links') === 'true'
          : undefined,
        merchant_id: searchParams.get('merchant_id')
          ? Number(searchParams.get('merchant_id'))
          : undefined,
      })
      .then((data) => {
        setTravelPartners(data as Pagination<TravelPartner>)
      })
      .catch(() => {
        toast.error('Failed to load travel partners. 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">
          Travel Partners
        </h1>
        <p className="font-medium text-slate-500">
          Following are the list of travel partners. You can manage them here.
        </p>

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

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

      <DataTable
        travelPartners={searchForm.searching ? [] : travelPartners.data}
        isLoading={isLoadingInitial}
        setModal={setTravelPartnerModal}
        setTravelPartner={setSelectedTravelPartner}
      />

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

      <ModalDeleteTravelPartner
        isOpen={
          travelPartnerModel.isOpened && travelPartnerModel.type === 'delete'
        }
        travelPartner={selectedTravelPartner}
        isDeleting={
          travelPartnerModel.processing && travelPartnerModel.type === 'delete'
        }
        onClose={() =>
          setTravelPartnerModal({ ...travelPartnerModel, isOpened: false })
        }
        onConfirm={handleConfirmDelete}
      />
    </section>
  )
}
