"use client";

import React from "react";
import { useModal } from "@/hook/use-modal";
import { Modal } from "@/components/modal";
import dynamic from "next/dynamic";
import { buildUrlQueryParams } from "@/utils/build-url-query-params";
import { useSearch } from "@/context/search";
import { useRouter } from "next/navigation";
import { useSettings } from "@/hook/use-settings";
import { DateSelect } from "@/components/search-field-core/date-select";
import dayjs from "@/utils/dayjs";
import { formatSearchDate, parseSearchDate } from "@/utils/jalali";
import { TimeSelect } from "@/components/search-field-core/time-select";
import { Types } from "@/context/search/search.reducer";
import { Button } from "@/components/button";
import { useTranslation } from "react-i18next";
import { Popover } from "@headlessui/react";

interface SearchFieldCoreProps {
  children: (options: {
    openServices: () => void;
    openPlaceModal: () => void;
    handleSearch: (searchOption: { scroll?: boolean; replace?: boolean }) => void;
    renderDateSelectPanel: () => React.ReactNode;
    renderTimeSelectPanel: (options: { withButton?: boolean }) => React.ReactNode;
  }) => React.ReactNode;
}

const ServiceSelect = dynamic(() =>
  import("./service-select").then((component) => ({ default: component.ServiceSelect }))
);
const PlaceSelect = dynamic(() =>
  import("./place-select").then((component) => ({ default: component.PlaceSelect }))
);

export const SearchFieldCore = ({ children }: SearchFieldCoreProps) => {
  const [isServicesModalOpen, openServicesModal, closeServicesModal] = useModal();
  const [isPlaceModalOpen, openPlaceModal, closePlaceModal] = useModal();
  const router = useRouter();
  const { state, dispatch } = useSearch();
  const { settings } = useSettings();
  const { t } = useTranslation();

  const parsedSearchDate = parseSearchDate(state.date.query);

  const handleSearch = ({ scroll, replace }: { scroll?: boolean; replace?: boolean }) => {
    const rawLat = state.location.geolocation?.latitude ?? settings?.latitude;
    const rawLng = state.location.geolocation?.longitude ?? settings?.longitude;
    const latNum = typeof rawLat === "number" ? rawLat : parseFloat(String(rawLat ?? ""));
    const lngNum = typeof rawLng === "number" ? rawLng : parseFloat(String(rawLng ?? ""));
    const hasValidCoords = Number.isFinite(latNum) && Number.isFinite(lngNum);

    const url = buildUrlQueryParams("/search", {
      date: parsedSearchDate?.isValid()
        ? parsedSearchDate.format("YYYY-MM-DD")
        : state.date.query,
      category_id: state.category.categoryId,
      revenue: state.category.query,
      timeFrom: state.searchTime.time?.from,
      timeTo: state.searchTime.time?.to,
      ...(hasValidCoords
        ? { latitude: String(latNum), longitude: String(lngNum) }
        : {}),
      location: state.location.query,
    });
    if (replace) {
      router.replace(url, { scroll });
    } else {
      router.push(url, { scroll });
    }
  };

  const renderDateSelectPanel = () => (
    <DateSelect
      value={parsedSearchDate?.isValid() ? parsedSearchDate.toDate() : undefined}
      onChange={(value) => {
        dispatch({
          type: Types.SetDate,
          payload: formatSearchDate(value),
        });
      }}
    />
  );

  const renderTimeSelectPanel = ({ withButton }: { withButton?: boolean }) => (
    <div className="flex flex-col gap-4">
      <div className="flex items-center gap-4">
        <TimeSelect
          value={
            state.searchTime.time
              ? dayjs(state.searchTime.time.from, "HH:mm").toDate()
              : undefined
          }
          label="from"
          onChange={(value: Date) => {
            dispatch({
              type: Types.SetTime,
              payload: {
                from: dayjs(value).format("HH:mm"),
                to: dayjs(value).add(1, "hour").format("HH:mm"),
              },
            });
          }}
          showPastTime={
            parsedSearchDate?.isValid()
              ? parsedSearchDate.isSame(dayjs(), "day")
              : undefined
          }
        />
        <TimeSelect
          label="to"
          onChange={(value) => {
            dispatch({
              type: Types.SetTime,
              payload: {
                from:
                  state.searchTime.time?.from ||
                  dayjs(value).subtract(1, "hour").format("HH:mm"),
                to: dayjs(value).format("HH:mm"),
              },
            });
          }}
          value={
            state.searchTime.time?.to
              ? dayjs(state.searchTime.time.to, "HH:mm").toDate()
              : undefined
          }
          showPastTime={
            parsedSearchDate?.isValid()
              ? parsedSearchDate.isSame(dayjs(), "day")
              : undefined
          }
        />
      </div>
      {withButton && (
        <Popover.Button as={Button} size="small" color="black" fullWidth>
          {t("search")}
        </Popover.Button>
      )}
    </div>
  );

  return (
    <>
      {children({
        openServices: openServicesModal,
        openPlaceModal,
        handleSearch,
        renderDateSelectPanel,
        renderTimeSelectPanel,
      })}
      <Modal isOpen={isServicesModalOpen} onClose={closeServicesModal}>
        <ServiceSelect closeModal={closeServicesModal} onSelect={closeServicesModal} />
      </Modal>
      <Modal isOpen={isPlaceModalOpen} onClose={closePlaceModal}>
        <PlaceSelect closeModal={closePlaceModal} onSelect={closePlaceModal} />
      </Modal>
    </>
  );
};
