import {
  Armchair,
  Bath,
  BedDouble,
  Building2,
  Car,
  Copy,
  Edit,
  ExternalLink,
  Ruler,
  Share2,
} from "lucide-react";
import type { GetStaticPaths, GetStaticPropsContext, NextPage } from "next";
import Head from "next/head";
import Link from "next/link";
import { IconMatrix, type IconType } from "~/components/IconComponents";
import FailedAnnuncioLoading, { LoadingPage } from "~/components/loading";
import { Button, buttonVariants } from "~/components/ui/button";
import {
  type CaratteristicheFiltered,
  filteredCaratteristiche,
} from "~/hooks/schedaAnnuncioUtils";
import { cn } from "~/lib/utils";
import { generateSSGHelper } from "~/server/utils/ssgHelper";
import { api } from "~/utils/api";
import { useTranslation } from "~/providers/I18nProvider";
import { useSession } from "~/providers/SessionProvider";
import { AnnuncioInteractions } from "~/components/annuncio-interactions/annuncio_interactions";
import { CarouselAnnuncio } from "~/components/annuncio_card";
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "~/components/ui/accordion";
import { AnnuncioContext } from "~/providers/AnnuncioProvider";
import { MappaDialogFullscreen } from "~/components/MapDialog";
import { handleConsegna } from "~/lib/annuncio_details";
import { PricingComponent } from "~/components/prezzi";
import type { AnnunciWithCoverImage } from "~/server/controllers/annunci.controller";
import { useMediaQuery } from "~/hooks/use-media-query";
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "~/components/ui/dialog";
import { Label } from "~/components/ui/label";
import Input from "~/components/custom_ui/input";
import toast from "react-hot-toast";
import { VideoPlayer } from "~/components/videoPlayer";
import { TouchProvider } from "~/components/custom_ui/HybridTooltip";
import InformationBubble from "~/components/InformationBubble";
import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum";
import { useEffect, useState } from "react";

type AnnuncioProps = {
  cod: string;
  flag: string;
};
const AnnuncioDettaglio: NextPage<AnnuncioProps> = ({
  cod,
  flag,
}: AnnuncioProps) => {
  const session = useSession();
  const { locale } = useTranslation();

  const [url, setUrl] = useState("");
  useEffect(() => {
    if (typeof window !== "undefined") {
      setUrl(window.location.href);
    }
  }, []);

  const { data, isLoading } = api.annunci.getAnnuncio.useQuery(
    {
      cod: cod,
    },
    { refetchOnMount: false },
  );

  const isDesktop = useMediaQuery("(min-width: 768px)");

  if (isLoading || session.status === "pending") return <LoadingPage />;
  if (
    (!isLoading && !data) ||
    session.status === "error" ||
    (data && data.stato === "Sospeso")
  ) {
    return <FailedAnnuncioLoading />;
  }
  if (!isLoading && data) {
    const titolo = (locale === "it" ? data.titolo_it : data.titolo_en) || "";
    const description = (locale === "it" ? data.desc_it : data.desc_en) || "";

    const filteredCaratt = data.caratteristiche
      ? filteredCaratteristiche(data.caratteristiche)
      : null;

    return (
      <AnnuncioContext.Provider value={data}>
        <TouchProvider>
          <main>
            <Head>
              <title>{`${cod} | ${titolo}`}</title>
              {data.titolo_it && (
                <meta
                  property="og:title"
                  content={data.titolo_it}
                  key="title"
                />
              )}
              {data.coverImage && (
                <meta
                  property="og:image"
                  content={data.coverImage}
                  key="image"
                />
              )}

              {typeof window !== "undefined" && (
                <meta property="og:url" content={url} />
              )}
              <meta property="og:site_name" content="Infoalloggi.it" />
            </Head>
            <div className="mx-auto w-full px-2 sm:px-8">
              <CarouselAnnuncio immagini={data.url_immagini} />

              <div className="flex flex-col sm:py-8 md:flex-row-reverse md:gap-2">
                <div className="mb-6 flex flex-col md:mb-0 md:w-1/3">
                  <div className="flex w-full flex-col flex-nowrap items-center justify-center gap-6">
                    <CardInfos data={data} />
                    {session.user?.isAdmin ? (
                      <Link
                        href={`/area-riservata/admin/edit-annuncio/${data.id}`}
                        className={cn(
                          "flex w-full flex-row gap-4",
                          buttonVariants({ variant: "default" }),
                        )}
                      >
                        <Edit className="size-5" /> Modifica annuncio
                      </Link>
                    ) : (
                      <AnnuncioInteractions
                        session={session}
                        disabled={flag === "true"}
                      />
                    )}
                    {data.tipo &&
                      (data.tipo == "Transitorio" ||
                        data.tipo == "Stabile") && (
                        <>
                          <Pricing
                            tipologia={
                              data.tipo == "Transitorio"
                                ? TipologiaPosizioneEnum.Transitorio
                                : TipologiaPosizioneEnum.Stabile
                            }
                            isDesktop={isDesktop}
                          />
                        </>
                      )}
                  </div>
                </div>
                <div className="mx-2 md:w-2/3">
                  <TestiAnnuncio
                    titolo={titolo}
                    description={description}
                    filteredCaratt={filteredCaratt}
                  />
                </div>
              </div>
              <AnnuncioFooter
                tipo={data.tipo}
                comune={data.comune}
                consegna={data.consegna}
                url_video={data.url_video || []}
                first_image={
                  data.url_immagini && data.url_immagini[0]
                    ? data.url_immagini[0]
                    : ""
                }
              />
            </div>
          </main>
        </TouchProvider>
      </AnnuncioContext.Provider>
    );
  }
  return <div>Errore</div>;
};

export async function getStaticProps(
  context: GetStaticPropsContext<{ cod: string }>,
) {
  const ssg = generateSSGHelper();
  const cod = context.params?.cod;
  if (typeof cod !== "string") throw new Error("no cod");
  await ssg.annunci.getAnnuncio.prefetch({ cod: cod });
  const flag = await ssg.settings.GetFlagValue.fetch({
    id: "ANNUNCIO_INTERACTIONS_DISABLED",
  });
  return {
    props: {
      trpcState: ssg.dehydrate(),
      cod,
      flag,
    },
    revalidate: 1,
  };
}

export const getStaticPaths: GetStaticPaths = async () => {
  return {
    paths: [],
    fallback: "blocking",
  };
};

export default AnnuncioDettaglio;

const Pricing = ({
  isDesktop,
  tipologia,
}: {
  isDesktop: boolean;
  tipologia: TipologiaPosizioneEnum;
}) => {
  const { t } = useTranslation();

  const { data: prezziario, isLoading } =
    api.prezziario.getPrezziPerTipologia.useQuery({
      tipologia,
    });

  if (isLoading) return <LoadingPage />;
  if (!prezziario) return null;

  const cta =
    tipologia == TipologiaPosizioneEnum.Transitorio
      ? t.pricing_cmp.cta_breve
      : t.pricing_cmp.cta_stabile;
  const opzioni =
    tipologia == TipologiaPosizioneEnum.Transitorio
      ? [
          t.pricing_cmp.breve_option1,
          t.pricing_cmp.breve_option2,
          t.pricing_cmp.breve_option3,
          t.pricing_cmp.breve_option4,
          t.pricing_cmp.breve_option5,
        ]
      : [t.pricing_cmp.stabile_option1, t.pricing_cmp.stabile_option2];

  const style =
    tipologia == TipologiaPosizioneEnum.Transitorio
      ? "border-rose-400 bg-rose-400"
      : "border-indigo-400 bg-indigo-400";

  const pricing = prezziario.saldi.map((s) => ({
    downPayment: prezziario.acconto.prezzo_cent / 100,
    secondPayment: s.prezzo_cent / 100,
  }));

  if (isDesktop) {
    return (
      <PricingComponent
        cta={cta}
        pricingData={pricing}
        opzioni={opzioni}
        statico={true}
        className={cn(
          style,
          "[&_[data-role=amount]]:text-2xl xl:[&_[data-role=amount]]:text-3xl [&_[data-role=title]]:text-2xl xl:[&_[data-role=title]]:text-3xl [&_[data-role=wrapper]]:flex-wrap lg:[&_[data-role=wrapper]]:flex-nowrap",
        )}
        title={
          tipologia == TipologiaPosizioneEnum.Transitorio
            ? t.prezzi.titolo_transitori
            : t.prezzi.titolo_stabile
        }
        tipo={tipologia}
      />
    );
  } else {
    return (
      <Accordion type="single" collapsible className="w-full">
        <AccordionItem value="item-1">
          <AccordionTrigger className="px-1 text-xl font-semibold">
            {t.pricing_cmp.cta_costo}
          </AccordionTrigger>
          <AccordionContent className="flex justify-center">
            <PricingComponent
              cta={cta}
              pricingData={pricing}
              opzioni={opzioni}
              statico={true}
              className={cn(style)}
              title={
                tipologia == TipologiaPosizioneEnum.Transitorio
                  ? t.prezzi.titolo_transitori
                  : t.prezzi.titolo_stabile
              }
              tipo={tipologia}
            />
          </AccordionContent>
        </AccordionItem>
      </Accordion>
    );
  }
};

const TestiAnnuncio = ({
  titolo,
  description,
  filteredCaratt,
}: {
  titolo: string;
  description: string;
  filteredCaratt:
    | {
        text: string;
        icon: IconType;
        value: string | null;
      }[]
    | null;
}) => {
  function replaceWithBr(text: string) {
    return text.replace(/\n/g, "<br />");
  }
  return (
    <>
      <h1 className="text-3xl font-bold uppercase">{titolo}</h1>
      <h1
        className="py-6"
        dangerouslySetInnerHTML={{
          __html: replaceWithBr(description),
        }}
      />
      {filteredCaratt && (
        <CaratteristicheAccordion filteredCaratt={filteredCaratt} />
      )}
    </>
  );
};

const CaratteristicheAccordion = ({
  filteredCaratt,
}: {
  filteredCaratt: CaratteristicheFiltered;
}) => {
  return (
    <Accordion
      className="my-5"
      type="single"
      collapsible
      defaultValue="altre-caratt"
    >
      <AccordionItem value="altre-caratt">
        <AccordionTrigger>Altre caratteristiche</AccordionTrigger>
        <AccordionContent>
          {Object.entries(filteredCaratt).map(([key, scheda_value]) => {
            const { text, icon, value } = scheda_value;
            if (value === null) return null;
            return (
              <div
                key={key}
                className="flex flex-row items-center gap-2 text-base"
              >
                <IconMatrix type={icon} className="size-4" />
                {text}: {value}
              </div>
            );
          })}
        </AccordionContent>
      </AccordionItem>
    </Accordion>
  );
};

const CardInfos = ({ data }: { data: AnnunciWithCoverImage }) => {
  const { t } = useTranslation();

  return (
    <Card className="relative w-full">
      <CardHeader>
        <CardTitle className="text-center text-3xl font-bold md:pl-8 lg:pl-0">
          Codice {data.codice}
        </CardTitle>
      </CardHeader>
      <CardContent className="flex flex-col gap-4 p-4 py-0">
        <div className="grid grid-cols-2 gap-2 font-semibold">
          <div className="relative">
            <div className="rounded-md bg-neutral-100 p-2 text-center">
              {data.prezzo && (data.prezzo / 1e2).toFixed(2).replace(".", ",")}{" "}
              €/mese
            </div>
            {data.prezzo && (
              <InformationBubble
                icon="euro"
                iconClassName="h-[19.5px] w-[19.5px] bg-orange-500 text-white rounded-full"
              >
                <div>
                  <span className="text-sm font-semibold">
                    Prezzo al giorno
                  </span>
                  <div className="text-muted-foreground text-sm">
                    {(data.prezzo / 1e2 / 30).toFixed(2).replace(".", ",")} €/gg
                  </div>
                </div>
              </InformationBubble>
            )}
          </div>
          <div className="relative">
            <div className="rounded-md bg-neutral-100 p-2 text-center">
              Affitto {data.tipo}{" "}
            </div>
            {data.tipo == "Transitorio" && (
              <InformationBubble
                href="/guida#faq-transitori"
                target="_blank"
                txt="Più informazioni sugli affitti transitori"
              />
            )}
          </div>
        </div>
        <div className="flex flex-col gap-2">
          <h3 className="px-2">Fornitura:</h3>
          <div className="grid grid-cols-2 gap-2">
            <div className="flex justify-center gap-2 rounded-md bg-neutral-100 p-2">
              <BedDouble />
              {data.numero_camere && data.numero_camere
                ? data.numero_camere > 1
                  ? `${data.numero_camere} ${t.card.camere2}`
                  : `${data.numero_camere} ${t.card.camere1}`
                : "N/A"}
            </div>
            <div className="flex justify-center gap-2 rounded-md bg-neutral-100 p-2">
              <Bath />
              <span>{data.numero_bagni} bagni</span>
            </div>
            <div className="flex justify-center gap-2 rounded-md bg-neutral-100 p-2">
              <Armchair />
              {data.caratteristiche?.Scheda_Arredi || ""}
            </div>
            <div className="flex justify-center gap-2 rounded-md bg-neutral-100 p-2">
              <Car />
              <span>{data.numero_postiauto} posti auto</span>
            </div>
          </div>
        </div>
        <div className="flex flex-col gap-2">
          <h3 className="px-2">Dati immobile:</h3>
          <div className="grid grid-cols-2 gap-2">
            <div className="flex justify-center gap-2 rounded-md bg-neutral-100 p-2">
              <Ruler />
              <span>
                {data.mq} m<sup>2</sup>
              </span>
            </div>

            <div className="flex justify-center gap-2 rounded-md bg-neutral-100 p-2">
              <Building2 />
              <span>
                {data.piano && data.piano === "0"
                  ? "piano terra"
                  : `${data.piano}° piano`}
              </span>
            </div>
          </div>
        </div>
        <div className="text-center text-base font-bold text-neutral-700">
          {data.stato === "Trattativa" ? (
            "Annuncio in aggiornamento"
          ) : (
            <>
              Disponibilità:{" "}
              <span className="text-red-500">
                {handleConsegna({
                  consegna: data.consegna,
                  consegna_da: t.card.consegna_da,
                  mesi: t.preferenze.mesi,
                  subito: t.card.consegna_subito,
                  aggiornamento: t.card.in_aggiornamento,
                })}
              </span>
            </>
          )}
        </div>
        <div className="flex flex-row justify-around gap-4">
          <MappaDialogFullscreen
            lat={data.lat_secondario}
            long={data.lon_secondario}
          />

          <ShareComponent />
        </div>
      </CardContent>
    </Card>
  );
};

const ShareComponent = () => {
  const { t } = useTranslation();

  const [link, setLink] = useState("");

  useEffect(() => {
    if (typeof window !== "undefined") {
      setLink(window.location.href);
    }
  }, []);
  const handleCopyLink = async () => {
    if (navigator.clipboard && navigator.clipboard.writeText) {
      try {
        await navigator.clipboard.writeText(link);
        toast(t.share.copiato, { icon: "📋" });
      } catch (err) {
        console.error("Failed to copy: ", err);
      }
    } else {
      // Fallback for browsers that do not support navigator.clipboard.writeText
      const textArea = document.createElement("textarea");
      textArea.value = link;
      document.body.appendChild(textArea);
      textArea.select();
      try {
        document.execCommand("copy");
        toast(t.share.copiato, { icon: "📋" });
      } catch (err) {
        console.error("Failed to copy: ", err);
      }
      document.body.removeChild(textArea);
    }
  };

  return (
    <Dialog>
      <DialogTrigger asChild>
        <Button variant="outline">
          <Share2 className="size-5" />
        </Button>
      </DialogTrigger>
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <DialogTitle>{t.share.condividi}</DialogTitle>
          <DialogDescription>{t.share.descrizione}</DialogDescription>
        </DialogHeader>
        <div className="flex items-center space-x-2">
          <div className="grid flex-1 gap-2">
            <Label htmlFor="link" className="sr-only">
              Link
            </Label>
            <Input id="link" defaultValue={link} readOnly />
          </div>
          <Button
            type="submit"
            size="sm"
            className="px-3"
            onClick={async () => await handleCopyLink()}
          >
            <span className="sr-only">Copy</span>
            <Copy />
          </Button>
        </div>
      </DialogContent>
    </Dialog>
  );
};

const AnnuncioFooter = ({
  tipo,
  comune,
  consegna,
  url_video,
  first_image,
}: {
  tipo: string | null;
  comune: string | null;
  consegna: number | null;
  url_video: string[];
  first_image: string;
}) => {
  return (
    <div className="flex flex-col gap-2">
      <p className="px-2 text-lg font-semibold">Video:</p>
      <div className="flex flex-col flex-wrap gap-4 sm:flex-row sm:gap-2 sm:px-2">
        {url_video.map((video) => {
          if (!video) return null;
          if (video.includes("youtu")) {
            return null;
            /*return (
              <iframe
                title="video"
                className={cn("h-96 w-auto rounded-md")}
                src={video}
                //src={`https://www.youtube-nocookie.com/embed/${video.split(/[/ ]+/).pop()}`}
                allow=" autoplay; encrypted-media"
                allowFullScreen
                key={`ytplayer-${video}`}
              />
            );*/
          } else {
            return (
              <VideoPlayer
                key={`videoplayer-${video}`}
                coverImage={first_image}
                videoSrc={video}
                className="h-96 max-w-96"
              />
            );
          }
        })}
      </div>

      <Link
        href={{
          pathname: "/annunci",
          query: {
            tipo: tipo,
            comune: comune,
            consegna: consegna,
          },
        }}
        target="_blank"
        className={cn(
          buttonVariants({ variant: "default" }),
          "my-10 flex flex-row items-center gap-2 bg-purple-500 text-center text-xl",
        )}
      >
        Cerca annunci simili <ExternalLink className="size-6" />
      </Link>
    </div>
  );
};
