import { useEffect, useMemo, useRef, useState } from 'react';
import QRCode from 'qrcode';

// ── Palettes & layout styles ────────────────────────────────────────────────

export interface QRPalette {
    key: string;
    label: string;
    bg: string;        // page background
    panel: string;     // QR panel background
    ink: string;       // primary text
    muted: string;     // secondary text
    accent: string;    // ornament + highlight
}

export const CARD_PALETTES: QRPalette[] = [
    { key: 'ivory-sage',   label: 'Ivory & Sage',     bg: '#FAF9F7', panel: '#FFFFFF', ink: '#1C1C1C', muted: '#5e6e62', accent: '#7d9a85' },
    { key: 'dusty-rose',   label: 'Dusty Rose',       bg: '#FBF4F4', panel: '#FFFFFF', ink: '#3a1c20', muted: '#8a5060', accent: '#C8A2A6' },
    { key: 'navy-gold',    label: 'Navy & Gold',      bg: '#F4F2E9', panel: '#FFFFFF', ink: '#0f1a3a', muted: '#4a5570', accent: '#b8832a' },
    { key: 'lavender',     label: 'Lavender Dreams',  bg: '#F4EEFB', panel: '#FFFFFF', ink: '#26143c', muted: '#6a4e90', accent: '#9070c0' },
    { key: 'terracotta',   label: 'Terracotta',       bg: '#FAEDE5', panel: '#FFFFFF', ink: '#3a1a10', muted: '#885030', accent: '#b85040' },
    { key: 'midnight',     label: 'Midnight Garden',  bg: '#10122a', panel: '#1a1d40', ink: '#f0eeff', muted: '#a8a0d0', accent: '#9b6dd6' },
    { key: 'champagne',    label: 'Champagne',        bg: '#FEFAEF', panel: '#FFFFFF', ink: '#231a08', muted: '#7d6a3e', accent: '#a88030' },
    { key: 'ocean',        label: 'Ocean Breeze',     bg: '#EDF5F8', panel: '#FFFFFF', ink: '#0a2030', muted: '#436880', accent: '#4a8aa8' },
    { key: 'forest',       label: 'Forest Green',     bg: '#EEF4EB', panel: '#FFFFFF', ink: '#0b1f10', muted: '#4a6852', accent: '#3f7a4a' },
    { key: 'blush-cream',  label: 'Blush & Cream',    bg: '#FFF5F0', panel: '#FFFFFF', ink: '#2a1018', muted: '#9a5070', accent: '#e07aaa' },
];

export type QRCardStyle = 'classic' | 'minimal' | 'bold';

export const QR_CARD_STYLES: { key: QRCardStyle; label: string }[] = [
    { key: 'classic', label: 'Classic' },
    { key: 'minimal', label: 'Minimal' },
    { key: 'bold',    label: 'Bold'    },
];

// ── Dialog ──────────────────────────────────────────────────────────────────

interface Props {
    open: boolean;
    onClose: () => void;
    url: string;                  // the URL the QR code points to
    coupleNames: string;          // "Emma & James"
    eventDate?: string;           // optional pre-formatted date string
    cardType: 'seat' | 'photo';
}

export function QRCardDialog({ open, onClose, url, coupleNames, eventDate, cardType }: Props) {
    const [paletteKey, setPaletteKey] = useState<string>('ivory-sage');
    const [style, setStyle] = useState<QRCardStyle>('classic');
    const [copied, setCopied] = useState(false);
    const canvasRef = useRef<HTMLCanvasElement>(null);

    function copyLink() {
        navigator.clipboard.writeText(url);
        setCopied(true);
        setTimeout(() => setCopied(false), 2000);
    }

    const palette = useMemo(
        () => CARD_PALETTES.find((p) => p.key === paletteKey) ?? CARD_PALETTES[0],
        [paletteKey],
    );

    useEffect(() => {
        if (!open || !canvasRef.current) return;
        drawCard(canvasRef.current, { url, coupleNames, eventDate, cardType, palette, style })
            .catch((err) => console.error('QR card render failed:', err));
    }, [open, url, coupleNames, eventDate, cardType, palette, style]);

    function download() {
        const canvas = canvasRef.current;
        if (!canvas) return;
        const link = document.createElement('a');
        link.download = `${cardType === 'seat' ? 'seat-finder' : 'photo-share'}-qr.png`;
        link.href = canvas.toDataURL('image/png');
        link.click();
    }

    if (!open) return null;

    return (
        <div className="fixed inset-0 z-50 bg-foreground/40 backdrop-blur-sm flex items-center justify-center p-4">
            <div className="bg-card rounded-3xl shadow-2xl border border-border w-full max-w-3xl max-h-[90vh] overflow-y-auto">
                <header className="flex items-baseline justify-between p-6 border-b border-border sticky top-0 bg-card/95 backdrop-blur z-10">
                    <div>
                        <p className="text-[11px] font-medium tracking-[0.22em] uppercase text-primary mb-1.5">
                            QR card
                        </p>
                        <h2 className="font-serif text-[1.6rem] tracking-tight">
                            {cardType === 'seat' ? 'Seat-finder card' : 'Photo-share card'}
                        </h2>
                    </div>
                    <button
                        onClick={onClose}
                        className="text-foreground/55 hover:text-foreground transition-colors p-1.5 -m-1.5"
                        aria-label="Close"
                    >
                        <svg className="w-4 h-4" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
                            <path d="m4 4 8 8M12 4l-8 8" />
                        </svg>
                    </button>
                </header>

                <div className="grid lg:grid-cols-[1fr_1.1fr] gap-6 p-6">
                    {/* Pickers */}
                    <div className="space-y-6">
                        <div>
                            <p className="text-[12px] font-medium text-muted-foreground mb-2.5">Colour palette</p>
                            <div className="grid grid-cols-5 gap-2">
                                {CARD_PALETTES.map((p) => {
                                    const active = paletteKey === p.key;
                                    return (
                                        <button
                                            key={p.key}
                                            type="button"
                                            onClick={() => setPaletteKey(p.key)}
                                            title={p.label}
                                            className={`relative aspect-square rounded-xl border transition-all overflow-hidden ${
                                                active ? 'border-foreground shadow-[0_6px_18px_-10px_rgba(0,0,0,0.35)] scale-[1.04]' : 'border-border hover:border-foreground/30'
                                            }`}
                                            style={{ backgroundColor: p.bg }}
                                        >
                                            <span className="absolute inset-2 rounded-md" style={{ backgroundColor: p.accent, opacity: 0.85 }} />
                                            <span className="absolute bottom-1 left-1 right-1 text-[8px] text-center font-medium truncate" style={{ color: p.ink }}>
                                                {p.label.split(' ')[0]}
                                            </span>
                                        </button>
                                    );
                                })}
                            </div>
                        </div>

                        <div>
                            <p className="text-[12px] font-medium text-muted-foreground mb-2.5">Layout style</p>
                            <div className="grid grid-cols-3 gap-2">
                                {QR_CARD_STYLES.map((s) => {
                                    const active = style === s.key;
                                    return (
                                        <button
                                            key={s.key}
                                            type="button"
                                            onClick={() => setStyle(s.key)}
                                            className={`px-3 py-2.5 rounded-xl border text-[13px] transition-all ${
                                                active ? 'border-foreground bg-foreground/[0.04]' : 'border-border hover:border-foreground/30'
                                            }`}
                                        >
                                            {s.label}
                                        </button>
                                    );
                                })}
                            </div>
                        </div>

                        <button onClick={download} className="btn-charcoal w-full">
                            Download PNG
                        </button>

                        {/* Direct sharing link — for guests who can't scan the printed card. */}
                        <div>
                            <p className="text-[12px] font-medium text-muted-foreground mb-2">Direct link</p>
                            <div className="flex items-stretch gap-2">
                                <input
                                    type="text"
                                    readOnly
                                    value={url}
                                    onFocus={(e) => e.currentTarget.select()}
                                    className="flex-1 min-w-0 border border-border rounded-lg px-3 py-2 text-[12.5px] text-foreground/80 bg-muted/30 truncate"
                                    aria-label="Direct sharing link"
                                />
                                <button
                                    type="button"
                                    onClick={copyLink}
                                    className="shrink-0 border border-border rounded-lg px-3.5 py-2 text-[12.5px] font-medium hover:border-foreground/30 transition-colors"
                                >
                                    {copied ? 'Copied' : 'Copy'}
                                </button>
                            </div>
                            <p className="text-[11.5px] text-muted-foreground mt-1.5 leading-relaxed">
                                Share this link directly — guests who can’t scan the card can open it in any browser to{' '}
                                {cardType === 'seat' ? 'find their seat' : 'add their photos'}.
                            </p>
                        </div>

                        <p className="text-[11.5px] text-muted-foreground leading-relaxed">
                            Print this card and place it at the entrance. Guests scan with their phone camera to{' '}
                            {cardType === 'seat' ? 'find their table' : 'upload photos to your gallery'}.
                        </p>
                    </div>

                    {/* Preview */}
                    <div className="flex items-center justify-center bg-muted/30 rounded-2xl p-4 min-h-[400px]">
                        <canvas
                            ref={canvasRef}
                            width={CARD_W}
                            height={CARD_H}
                            className="w-full h-auto max-h-[460px] rounded-lg shadow-[0_20px_40px_-20px_rgba(0,0,0,0.25)]"
                            style={{ aspectRatio: `${CARD_W} / ${CARD_H}` }}
                        />
                    </div>
                </div>
            </div>
        </div>
    );
}

// ── Canvas rendering ────────────────────────────────────────────────────────

const CARD_W = 600;
const CARD_H = 850;  // ~A5 aspect

async function drawCard(
    canvas: HTMLCanvasElement,
    opts: {
        url: string;
        coupleNames: string;
        eventDate?: string;
        cardType: 'seat' | 'photo';
        palette: QRPalette;
        style: QRCardStyle;
    },
) {
    const { url, coupleNames, eventDate, cardType, palette, style } = opts;
    const ctx = canvas.getContext('2d');
    if (!ctx) return;

    // Background
    ctx.fillStyle = palette.bg;
    ctx.fillRect(0, 0, CARD_W, CARD_H);

    // Outer border line (Classic only)
    if (style === 'classic') {
        ctx.strokeStyle = palette.accent;
        ctx.lineWidth = 1.5;
        ctx.strokeRect(28, 28, CARD_W - 56, CARD_H - 56);
        drawCornerOrnaments(ctx, palette.accent, 28, 28, CARD_W - 56, CARD_H - 56);
    } else if (style === 'bold') {
        // Solid header band
        ctx.fillStyle = palette.accent;
        ctx.fillRect(0, 0, CARD_W, 120);
    }

    // Eyebrow / kicker
    const isDark = palette.bg === '#10122a';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'top';

    if (style === 'bold') {
        ctx.fillStyle = '#ffffff';
        ctx.font = '600 14px Inter, system-ui, sans-serif';
        ctx.letterSpacing = '0.22em' as any; // Not all browsers — falls back gracefully.
        ctx.fillText((cardType === 'seat' ? 'FIND YOUR SEAT' : 'SHARE YOUR PHOTOS'), CARD_W / 2, 50);

        ctx.font = "italic 28px 'Playfair Display', Georgia, serif";
        ctx.fillText(coupleNames, CARD_W / 2, 78);
    } else {
        const kickerY = style === 'minimal' ? 80 : 96;
        ctx.fillStyle = palette.accent;
        ctx.font = '600 14px Inter, system-ui, sans-serif';
        ctx.fillText((cardType === 'seat' ? 'FIND YOUR SEAT' : 'SHARE YOUR PHOTOS'), CARD_W / 2, kickerY);

        ctx.fillStyle = palette.ink;
        ctx.font = "italic 44px 'Playfair Display', Georgia, serif";
        ctx.fillText(coupleNames, CARD_W / 2, kickerY + 32);

        if (eventDate) {
            ctx.fillStyle = palette.muted;
            ctx.font = '400 14px Inter, system-ui, sans-serif';
            ctx.fillText(eventDate, CARD_W / 2, kickerY + 96);
        }
    }

    // QR code — generated via the `qrcode` lib, drawn into the panel
    const qrSize = style === 'minimal' ? 320 : 280;
    const qrY = style === 'bold' ? 200 : (eventDate ? 280 : 250);
    const qrX = (CARD_W - qrSize) / 2;

    // Panel behind QR
    const panelPad = 24;
    const panelRadius = 16;
    ctx.fillStyle = palette.panel;
    if (!isDark && style !== 'minimal') {
        ctx.shadowColor = 'rgba(0,0,0,0.08)';
        ctx.shadowBlur = 24;
        ctx.shadowOffsetY = 6;
    }
    roundRect(ctx, qrX - panelPad, qrY - panelPad, qrSize + panelPad * 2, qrSize + panelPad * 2, panelRadius);
    ctx.fill();
    ctx.shadowColor = 'transparent';
    ctx.shadowBlur = 0;
    ctx.shadowOffsetY = 0;

    // QR via qrcode lib → ImageBitmap
    const qrDataUrl = await QRCode.toDataURL(url, {
        errorCorrectionLevel: 'H',
        margin: 0,
        width: qrSize,
        color: {
            dark: palette.ink,
            light: palette.panel,
        },
    });
    const qrImg = await loadImage(qrDataUrl);
    ctx.drawImage(qrImg, qrX, qrY, qrSize, qrSize);

    // Footer text
    const footerY = qrY + qrSize + panelPad + 36;
    ctx.fillStyle = palette.muted;
    ctx.font = '400 14px Inter, system-ui, sans-serif';
    ctx.textAlign = 'center';
    ctx.fillText(
        cardType === 'seat'
            ? 'Scan with your phone camera'
            : 'Scan to upload photos & videos',
        CARD_W / 2,
        footerY,
    );

    ctx.fillStyle = palette.ink;
    ctx.font = "italic 16px 'Playfair Display', Georgia, serif";
    ctx.fillText(
        cardType === 'seat'
            ? 'and find your table.'
            : 'no app needed.',
        CARD_W / 2,
        footerY + 22,
    );

    // Brand mark
    if (!isDark) {
        ctx.fillStyle = palette.muted;
        ctx.font = '400 10px Inter, system-ui, sans-serif';
        ctx.textAlign = 'center';
        ctx.fillText('POWERED  BY  WEDFLOW', CARD_W / 2, CARD_H - 36);
    } else {
        ctx.fillStyle = palette.muted;
        ctx.font = '400 10px Inter, system-ui, sans-serif';
        ctx.textAlign = 'center';
        ctx.fillText('POWERED  BY  WEDFLOW', CARD_W / 2, CARD_H - 36);
    }
}

// ── Helpers ─────────────────────────────────────────────────────────────────

function roundRect(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, r: number) {
    ctx.beginPath();
    ctx.moveTo(x + r, y);
    ctx.lineTo(x + w - r, y);
    ctx.quadraticCurveTo(x + w, y, x + w, y + r);
    ctx.lineTo(x + w, y + h - r);
    ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
    ctx.lineTo(x + r, y + h);
    ctx.quadraticCurveTo(x, y + h, x, y + h - r);
    ctx.lineTo(x, y + r);
    ctx.quadraticCurveTo(x, y, x + r, y);
    ctx.closePath();
}

function drawCornerOrnaments(ctx: CanvasRenderingContext2D, color: string, x: number, y: number, w: number, h: number) {
    ctx.strokeStyle = color;
    ctx.fillStyle = color;
    ctx.lineWidth = 1.5;

    // Four little corner "flourishes" via quadratic curves.
    const corners: [number, number, number, number][] = [
        // x,y, dx, dy — direction the curve grows
        [x, y, 1, 1],
        [x + w, y, -1, 1],
        [x, y + h, 1, -1],
        [x + w, y + h, -1, -1],
    ];

    for (const [cx, cy, dx, dy] of corners) {
        // Inner curved arc
        ctx.beginPath();
        ctx.moveTo(cx + dx * 14, cy);
        ctx.quadraticCurveTo(cx + dx * 24, cy + dy * 6, cx + dx * 24, cy + dy * 24);
        ctx.lineTo(cx, cy + dy * 24);
        ctx.quadraticCurveTo(cx + dx * 6, cy + dy * 24, cx + dx * 14, cy);
        ctx.stroke();
        // Center dot
        ctx.beginPath();
        ctx.arc(cx + dx * 19, cy + dy * 19, 1.6, 0, Math.PI * 2);
        ctx.fill();
    }
}

function loadImage(src: string): Promise<HTMLImageElement> {
    return new Promise((resolve, reject) => {
        const img = new Image();
        img.onload = () => resolve(img);
        img.onerror = reject;
        img.src = src;
    });
}
