'use client';

import { useEffect, useMemo, useState } from 'react';
import { createPortal } from 'react-dom';
import Image from 'next/image';
import { AnimatePresence, motion } from 'framer-motion';
import { Bot, Copy, Download, ExternalLink, Loader2, QrCode, X } from 'lucide-react';
import QRCode from 'qrcode';
import { useToast } from './ToastProvider';

interface QRCodeModalProps {
  isOpen: boolean;
  onClose: () => void;
  url: string;
  title?: string | null;
}

export default function QRCodeModal({ isOpen, onClose, url, title }: QRCodeModalProps) {
  const toast = useToast();
  const [qrDataUrl, setQrDataUrl] = useState('');
  const [qrSvg, setQrSvg] = useState('');
  const [isGenerating, setIsGenerating] = useState(false);
  const [isCopyingImage, setIsCopyingImage] = useState(false);
  const [error, setError] = useState('');

  const safeFileName = useMemo(() => {
    const baseName = (title || url)
      .toLowerCase()
      .replace(/https?:\/\//g, '')
      .replace(/[^a-z0-9-_]+/g, '-')
      .replace(/^-+|-+$/g, '')
      .slice(0, 50);

    return baseName || 'link';
  }, [title, url]);

  useEffect(() => {
    if (!isOpen || !url) return;

    let isMounted = true;

    const generateQr = async () => {
      setIsGenerating(true);
      setError('');

      try {
        const options = {
          width: 640,
          margin: 2,
          color: {
            dark: '#0b1120',
            light: '#ffffff',
          },
        };

        const [dataUrl, svg] = await Promise.all([
          QRCode.toDataURL(url, options),
          QRCode.toString(url, { ...options, type: 'svg' }),
        ]);

        if (!isMounted) return;
        setQrDataUrl(dataUrl);
        setQrSvg(svg);
      } catch {
        if (!isMounted) return;
        setError('Не удалось сгенерировать QR-код');
        setQrDataUrl('');
        setQrSvg('');
      } finally {
        if (isMounted) {
          setIsGenerating(false);
        }
      }
    };

    void generateQr();

    return () => {
      isMounted = false;
    };
  }, [isOpen, url]);

  useEffect(() => {
    if (!isOpen) return;

    const previousOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => {
      document.body.style.overflow = previousOverflow;
    };
  }, [isOpen]);

  const handleDownload = () => {
    if (!qrDataUrl) return;

    const a = document.createElement('a');
    a.href = qrDataUrl;
    a.download = `qr-${safeFileName}.png`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  };

  const handleDownloadSvg = () => {
    if (!qrSvg) return;

    const blob = new Blob([qrSvg], { type: 'image/svg+xml;charset=utf-8' });
    const blobUrl = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = blobUrl;
    a.download = `qr-${safeFileName}.svg`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(blobUrl);
  };

  const handleCopyUrl = async () => {
    try {
      await navigator.clipboard.writeText(url);
      toast.success('Ссылка скопирована');
    } catch {
      toast.error('Не удалось скопировать ссылку');
    }
  };

  const handleCopyImage = async () => {
    if (!qrDataUrl) return;

    const canCopyImage =
      typeof window !== 'undefined' &&
      typeof ClipboardItem !== 'undefined' &&
      !!navigator.clipboard?.write;

    if (!canCopyImage) {
      toast.error('Копирование изображения не поддерживается в этом браузере');
      return;
    }

    setIsCopyingImage(true);

    try {
      const parts = qrDataUrl.split(',');
      if (parts.length !== 2) {
        throw new Error('Invalid data URL');
      }

      const mimeMatch = parts[0].match(/data:(.*?);base64/);
      const mimeType = mimeMatch?.[1] || 'image/png';
      const byteString = atob(parts[1]);
      const byteArray = new Uint8Array(byteString.length);

      for (let index = 0; index < byteString.length; index += 1) {
        byteArray[index] = byteString.charCodeAt(index);
      }

      const blob = new Blob([byteArray], { type: mimeType });
      await navigator.clipboard.write([
        new ClipboardItem({
          [mimeType]: blob,
        }),
      ]);
      toast.success('QR-код скопирован как изображение');
    } catch {
      toast.error('Не удалось скопировать QR-код как изображение');
    } finally {
      setIsCopyingImage(false);
    }
  };

  if (!isOpen) return null;

  const modalContent = (
    <AnimatePresence>
      <motion.div
        className="fixed inset-0 z-[1000] flex items-center justify-center p-4"
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        exit={{ opacity: 0 }}
      >
        <motion.button
          type="button"
          aria-label="Закрыть"
          className="absolute inset-0 bg-black/70 backdrop-blur-sm"
          onClick={onClose}
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
        />

        <motion.div
          initial={{ opacity: 0, y: 18, scale: 0.98 }}
          animate={{ opacity: 1, y: 0, scale: 1 }}
          exit={{ opacity: 0, y: 10, scale: 0.98 }}
          transition={{ duration: 0.2, ease: 'easeOut' }}
          className="relative z-10 w-full max-w-md overflow-hidden rounded-[1.5rem] border border-white/10 bg-[#0A0A0A]/95 shadow-[0_24px_80px_rgba(0,0,0,0.65)] backdrop-blur-xl"
        >
          <div className="relative border-b border-white/10 px-5 py-4">
            <div className="pointer-events-none absolute -right-10 -top-10 h-36 w-36 rounded-full bg-violet-500/10 blur-3xl" />
            <div className="relative z-10 flex items-start justify-between gap-3">
              <div className="min-w-0">
                <div className="mb-2 inline-flex items-center gap-2 rounded-full border border-violet-500/30 bg-violet-500/10 px-2.5 py-1 text-[10px] uppercase tracking-[0.14em] text-violet-300">
                  <Bot className="h-3.5 w-3.5" />
                  QR-код
                </div>
                <h3 className="text-lg font-semibold text-white">QR-код ссылки</h3>
                <p className="mt-1 break-all text-xs text-gray-400">{url}</p>
              </div>
              <button
                type="button"
                onClick={onClose}
                className="inline-flex h-9 w-9 items-center justify-center rounded-xl border border-white/10 bg-white/[0.03] text-gray-400 transition-colors hover:bg-white/[0.08] hover:text-white"
                aria-label="Закрыть"
              >
                <X className="h-4 w-4" />
              </button>
            </div>
          </div>

          <div className="space-y-4 p-5">
            <div className="flex min-h-[300px] items-center justify-center rounded-2xl border border-white/10 bg-black/45 p-4">
              {isGenerating ? (
                <div className="inline-flex items-center gap-2 text-gray-300">
                  <Loader2 className="h-5 w-5 animate-spin text-violet-300" />
                  <span className="text-sm">Генерируем QR-код...</span>
                </div>
              ) : error ? (
                <p className="text-sm text-red-300">{error}</p>
              ) : (
                <Image
                  src={qrDataUrl}
                  alt="QR code"
                  width={260}
                  height={260}
                  className="h-auto w-full max-w-[260px] rounded-xl border border-white/10 bg-white p-2"
                  unoptimized
                />
              )}
            </div>

            <div className="grid grid-cols-1 gap-2 sm:grid-cols-2">
              <button
                type="button"
                onClick={handleDownload}
                disabled={!qrDataUrl || isGenerating}
                className="inline-flex items-center justify-center gap-2 rounded-xl bg-gradient-to-r from-fuchsia-500 to-violet-600 px-4 py-2.5 text-sm font-medium text-white transition-all hover:brightness-110 disabled:cursor-not-allowed disabled:opacity-60"
              >
                <Download className="h-4 w-4" />
                Скачать PNG
              </button>
              <button
                type="button"
                onClick={handleDownloadSvg}
                disabled={!qrSvg || isGenerating}
                className="inline-flex items-center justify-center gap-2 rounded-xl border border-white/10 bg-white/[0.04] px-4 py-2.5 text-sm font-medium text-white transition-colors hover:bg-white/[0.1] disabled:cursor-not-allowed disabled:opacity-60"
              >
                <Download className="h-4 w-4" />
                Скачать SVG
              </button>
              <button
                type="button"
                onClick={handleCopyImage}
                disabled={!qrDataUrl || isGenerating || isCopyingImage}
                className="inline-flex items-center justify-center gap-2 rounded-xl border border-white/10 bg-white/[0.04] px-4 py-2.5 text-sm font-medium text-gray-200 transition-colors hover:bg-white/[0.1] hover:text-white disabled:cursor-not-allowed disabled:opacity-60"
              >
                {isCopyingImage ? (
                  <>
                    <Loader2 className="h-4 w-4 animate-spin" />
                    Копирование...
                  </>
                ) : (
                  <>
                    <QrCode className="h-4 w-4" />
                    Копировать QR
                  </>
                )}
              </button>
              <button
                type="button"
                onClick={handleCopyUrl}
                className="inline-flex items-center justify-center gap-2 rounded-xl border border-white/10 bg-white/[0.04] px-4 py-2.5 text-sm font-medium text-gray-200 transition-colors hover:bg-white/[0.1] hover:text-white"
              >
                <Copy className="h-4 w-4" />
                Копировать URL
              </button>
            </div>

            <a
              href={url}
              target="_blank"
              rel="noopener noreferrer"
              className="inline-flex w-full items-center justify-center gap-2 rounded-xl border border-blue-500/25 bg-blue-500/15 px-4 py-2.5 text-sm font-medium text-blue-200 transition-colors hover:bg-blue-500/25"
            >
              <ExternalLink className="h-4 w-4" />
              Открыть ссылку
            </a>
          </div>
        </motion.div>
      </motion.div>
    </AnimatePresence>
  );

  if (typeof document === 'undefined') {
    return modalContent;
  }

  return createPortal(modalContent, document.body);
}
