// Icons
import CopyBlueD from "@/components/icons/CopyBlueD";
import DownloadBlue from "@/components/icons/DownloadBlue";
import WhatsappBlueD from "@/components/icons/WhatsappBlueD";
import TelegramBlueD from "@/components/icons/TelegramBlueD";
import LinkedingBlueD from "@/components/icons/LinkedingBlueD";

// Packages
import { useState } from "react";
import { toPng } from "html-to-image";
import html2canvas from "html2canvas";
import jsPDF from "jspdf";
import { Button } from "@mui/material";
import { toast } from "react-toastify";

const VAZIR_WEIGHTS = [
  [400, "Vazirmatn-RD-FD-Regular.ttf"],
  [500, "Vazirmatn-RD-FD-Medium.ttf"],
  [600, "Vazirmatn-RD-FD-SemiBold.ttf"],
  [700, "Vazirmatn-RD-FD-Bold.ttf"],
  [800, "Vazirmatn-RD-FD-ExtraBold.ttf"],
];

let vazirEmbedCssPromise;
const getVazirEmbedCss = () => {
  vazirEmbedCssPromise ??= Promise.all(
    VAZIR_WEIGHTS.map(async ([weight, file]) => {
      const res = await fetch(`/fonts/vazir/${file}`);
      const blob = await res.blob();
      const dataUrl = await new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = () => resolve(reader.result);
        reader.onerror = reject;
        reader.readAsDataURL(blob);
      });
      return `@font-face{font-family:vazir;src:url(${dataUrl});font-weight:${weight};}`;
    })
  ).then((faces) => faces.join("\n"));
  return vazirEmbedCssPromise;
};

const waitForImages = async (element) => {
  const imgs = Array.from(element.querySelectorAll("img"));
  await Promise.all(
    imgs.map((img) => {
      if (img.complete && img.naturalWidth !== 0) {
        return img.decode?.().catch(() => {}) ?? Promise.resolve();
      }
      return new Promise((resolve) => {
        img.onload = () => resolve();
        img.onerror = () => resolve();
      });
    })
  );
};

function List({ hiddenRef, data, qrReady }) {
  const [downloading, setDownloading] = useState(false);

  const handleDownloadPDF = async () => {
    const element = hiddenRef.current;
    if (!element || downloading) return;

    if (!qrReady) {
      toast.info("در حال آماده‌سازی پوستر، لحظه‌ای صبر کنید...");
      return;
    }

    setDownloading(true);
    try {
      await waitForImages(element);

      let imgData;
      let pxWidth;
      let pxHeight;

      try {
        const fontEmbedCSS = await getVazirEmbedCss();
        const options = {
          pixelRatio: 2,
          backgroundColor: "#ffffff",
          style: { opacity: "1" },
          fontEmbedCSS,
        };
        imgData = await toPng(element, options);
        pxWidth = element.offsetWidth * 2;
        pxHeight = element.offsetHeight * 2;
      } catch {
        const canvas = await html2canvas(element, {
          backgroundColor: "#ffffff",
          useCORS: true,
          scale: 2,
          imageTimeout: 15000,
        });
        imgData = canvas.toDataURL("image/png");
        pxWidth = canvas.width;
        pxHeight = canvas.height;
      }

      const imgWidth = 210;
      const pxPerMm = pxWidth / imgWidth;
      const imgHeight = pxHeight / pxPerMm;

      const pdf = new jsPDF({
        orientation: "portrait",
        unit: "mm",
        format: [imgWidth, imgHeight],
      });

      pdf.addImage(imgData, "PNG", 0, 0, imgWidth, imgHeight);
      const safeName = (data?.name ?? "doctor").replace(/[\\/:*?"<>|]+/g, "-");
      pdf.save(`poster-${safeName}.pdf`);
    } catch {
      toast.error("ساخت پوستر ناموفق بود، دوباره تلاش کنید");
    } finally {
      setDownloading(false);
    }
  };

  const getShareUrl = () =>
    typeof window !== "undefined" ? window.location.href : "";

  const getShareText = () =>
    data?.name ? `معرفی ${data.name} در نوبت 724` : "معرفی پزشک در نوبت 724";

  const openShareWindow = (url) => {
    if (typeof window !== "undefined") {
      window.open(url, "_blank", "noopener,noreferrer");
    }
  };

  const handleWhatsapp = () => {
    const text = encodeURIComponent(`${getShareText()}\n${getShareUrl()}`);
    openShareWindow(`https://wa.me/?text=${text}`);
  };

  const handleTelegram = () => {
    const url = encodeURIComponent(getShareUrl());
    const text = encodeURIComponent(getShareText());
    openShareWindow(`https://t.me/share/url?url=${url}&text=${text}`);
  };

  const handleLinkedin = () => {
    const url = encodeURIComponent(getShareUrl());
    openShareWindow(
      `https://www.linkedin.com/sharing/share-offsite/?url=${url}`
    );
  };

  const handleCopyLink = async () => {
    try {
      await navigator.clipboard.writeText(getShareUrl());
      toast.success("لینک کپی شد");
    } catch {
      toast.error("کپی لینک ناموفق بود");
    }
  };

  const listIcons = [
    { name: "واتساپ", icon: <WhatsappBlueD />, onClick: handleWhatsapp },
    { name: "تلگرام", icon: <TelegramBlueD />, onClick: handleTelegram },
    { name: "لینکدین", icon: <LinkedingBlueD />, onClick: handleLinkedin },
    { name: "کپی لینک", icon: <CopyBlueD />, onClick: handleCopyLink },
    {
      name: "دانلود",
      icon: <DownloadBlue />,
      onClick: handleDownloadPDF,
      disabled: downloading,
    },
  ];

  return (
    <>
      <ul className="flex items-center mx-[60px] sm:mx-[86px] md:mx-[112px] lg:mx-[140px] justify-center mt-[8px] md:mt-[12px] lg:mt-[16px] gap-[24px] sm:gap-[26px] md:gap-[29px] lg:gap-[32px]">
        {listIcons.map((item, idx) => (
          <li
            key={idx}
            className="flex flex-col justify-center items-center w-fit gap-[2px]"
          >
            <Button
              className=" !p-[0px] !bg-[#EAECFA] !rounded-full !min-w-0 grid place-items-center !w-[24px] sm:!w-[28px] md:!w-[32px] lg:!w-[36px] !h-[24px] sm:!h-[28px] md:!h-[32px] lg:!h-[36px] "
              onClick={item.onClick}
              aria-label={item.name}
              variant="text"
              disabled={item.disabled}
            >
              <div
                className="grid place-items-center w-full-icon !w-[16px] md:!w-[17px] lg:!w-[18px] !h-[16px] md:!h-[17px] lg:!h-[18px]"
              >
                {item.icon}
              </div>
            </Button>
            <span className="text-[#525252] text-[10px] md:text-[11px] lg:text-[12px]">
              {item.name}
            </span>
          </li>
        ))}
      </ul>
    </>
  );
}

export default List;
