import dynamic from "next/dynamic";
import type { AnnuncioRicercaWPosition } from "~/server/controllers/annunci.controller";
import { api } from "~/utils/api";
import { LoadingPage } from "~/components/loading";
import { Status500 } from "~/components/status-page";
import { useTranslation } from "~/providers/I18nProvider";
import { AnimatePresence, motion } from "framer-motion";
import Image from "next/image";
import { formatCurrency } from "~/lib/utils";
import { handleConsegna } from "~/lib/annuncio_details";
import {
  Fragment,
  memo,
  useState,
  type Dispatch,
  type SetStateAction,
} from "react";
import { useRicerca } from "~/providers/RicercaProvider";

const Map = dynamic(() => import("~/components/map/Map"), {
  ssr: false,
});

export const MapSection = () => {
  const { comune, consegna, tipo } = useRicerca();
  const [selected, setSelected] = useState<AnnuncioRicercaWPosition | null>(
    null,
  );

  return (
    <div className="relative z-50 flex h-[60vh] w-full items-center justify-center sm:h-[65vh]">
      <MapDisplay
        selectTipo={tipo}
        selectComune={comune}
        selectConsegna={consegna}
        setSelected={setSelected}
      />
      <SelectedComp selected={selected} />
    </div>
  );
};

const MapDisplay = memo(
  ({
    selectTipo,
    selectComune,
    selectConsegna,
    setSelected,
  }: {
    selectTipo: string;
    selectComune: string;
    selectConsegna: number | null;
    setSelected: Dispatch<SetStateAction<AnnuncioRicercaWPosition | null>>;
  }) => {
    const { data, isLoading } = api.annunci.getMapping.useQuery({
      tipologia: selectTipo,
      comune: selectComune,
      consegna: selectConsegna || undefined,
    });

    if (isLoading) return <LoadingPage />;
    if (!data) return <Status500 />;

    const posizioni = data
      .map((a) => {
        if (a.lat_secondario && a.lon_secondario) {
          return {
            pos: {
              lat: parseFloat(a.lat_secondario),
              lng: parseFloat(a.lon_secondario),
            },
            onClick: () => setSelected(a),
            markerTxt: `€ ${a.prezzo / 1e2}`,
          };
        }
        return undefined;
      })
      .filter((a) => a !== undefined);

    return (
      <Map
        isGroup
        groupData={posizioni}
        posix={{ pos: { lat: 45.764718, lng: 11.73067 } }}
        width="100%"
        height="100%"
        zoom={13}
        scrollWheelZoom
        markerType="price"
        onMapClick={() => setSelected(null)}
      />
    );
  },
);

MapDisplay.displayName = "MapDisplay";

const SelectedComp = memo(
  ({ selected }: { selected: AnnuncioRicercaWPosition | null }) => {
    const { t } = useTranslation();

    return (
      <Fragment>
        <AnimatePresence initial={false}>
          {selected && (
            <motion.a
              aria-label="Visualizza Dettagli Annuncio"
              href={`/annuncio/${selected.codice}`}
              target="_blank"
              className="group absolute right-0 bottom-0 left-0 z-20 mx-2 mb-2 flex flex-col gap-2 rounded-md bg-white p-4 ring-neutral-500 hover:ring-1"
              initial={{ opacity: 0, scale: 0 }}
              animate={{ opacity: 1, scale: 1 }}
              exit={{ opacity: 0, scale: 0 }}
              transition={{
                duration: 0.1,
                scale: { type: "spring", visualDuration: 0.1, bounce: 0.2 },
              }}
              key={selected.id}
            >
              <div className="flex gap-2">
                {selected.url_immagini && selected.url_immagini[0] ? (
                  <Image
                    src={selected.url_immagini[0]}
                    width={500}
                    height={500}
                    className="size-24 rounded-md object-cover sm:size-40"
                    alt="a"
                  />
                ) : (
                  <div className="size-20 bg-gray-200 sm:size-40" />
                )}
                <div className="flex flex-col sm:gap-2 sm:text-lg">
                  <h6 className="font-semibold underline-offset-2 group-hover:underline">
                    {selected.codice}
                  </h6>
                  <h3 className="text-sm sm:text-base">{selected.titolo_it}</h3>
                  <div className="flex gap-2">
                    <h3 className="font-semibold">
                      {formatCurrency(selected.prezzo / 1e2)}
                    </h3>
                    <h3>{selected.mq}mq</h3>
                  </div>
                  <p>
                    {handleConsegna({
                      consegna: selected.consegna,
                      consegna_da: t.card.consegna_da,
                      mesi: t.preferenze.mesi,
                      subito: t.card.consegna_subito,
                      aggiornamento: t.card.in_aggiornamento,
                    })}
                  </p>
                </div>
              </div>
            </motion.a>
          )}
        </AnimatePresence>
      </Fragment>
    );
  },
);
SelectedComp.displayName = "SelectedComp";
