import { useForm, router } from '@inertiajs/react';
import AppLayout from '@/layouts/AppLayout';
import { useState } from 'react';
import { useTranslator } from '@/lib/i18n';

interface Item {
    id: string;
    title?: string;
    notes?: string;
    image_url?: string;
    media_type: 'image' | 'video';
    video_url?: string;
}

interface Props {
    wedding: any;
    items: Item[];
}

// ── Video URL helpers ───────────────────────────────────────────────────────
//
// Accepts the URL formats users actually paste from YouTube / TikTok / Vimeo
// and returns an embeddable URL. YouTube embeds use youtube-nocookie.com so
// they aren't blocked by overzealous tracking-blockers on guest devices.

function youtubeId(url: string): string | null {
    // /watch?v=XXX, /shorts/XXX, /live/XXX, /embed/XXX, youtu.be/XXX
    const m =
        url.match(/(?:youtube\.com\/(?:watch\?v=|shorts\/|live\/|embed\/)|youtu\.be\/)([\w-]{11})/i);
    return m ? m[1] : null;
}

function vimeoId(url: string): string | null {
    const m = url.match(/vimeo\.com\/(?:video\/|channels\/[^/]+\/)?(\d{6,})/i);
    return m ? m[1] : null;
}

function tiktokId(url: string): string | null {
    const m = url.match(/tiktok\.com\/(?:@[\w.-]+\/video\/|embed\/v\d\/)(\d{10,})/i);
    return m ? m[1] : null;
}

function toEmbedUrl(url?: string | null): string | null {
    if (!url) return null;
    const yt = youtubeId(url);
    if (yt) return `https://www.youtube-nocookie.com/embed/${yt}`;
    const vm = vimeoId(url);
    if (vm) return `https://player.vimeo.com/video/${vm}`;
    const tt = tiktokId(url);
    if (tt) return `https://www.tiktok.com/embed/v2/${tt}`;
    return null;
}

function toThumbnailUrl(url?: string | null): string | null {
    if (!url) return null;
    const yt = youtubeId(url);
    if (yt) return `https://i.ytimg.com/vi/${yt}/hqdefault.jpg`;
    return null; // TikTok/Vimeo thumbnails aren't fetchable cross-origin without an API.
}

// ── Component ───────────────────────────────────────────────────────────────

export default function Inspiration({ wedding, items }: Props) {
    const t = useTranslator();
    const [showAdd, setShowAdd] = useState(false);
    const [playingId, setPlayingId] = useState<string | null>(null);
    const [uploading, setUploading] = useState(false);
    const [uploadError, setUploadError] = useState<string | null>(null);

    const form = useForm({
        title: '',
        notes: '',
        image_url: '',
        media_type: 'image' as 'image' | 'video',
        video_url: '',
    });

    function closeAdd() {
        setShowAdd(false);
        setUploadError(null);
        form.reset();
        form.clearErrors();
    }

    function handleAdd(e: React.FormEvent) {
        e.preventDefault();
        form.post(`/weddings/${wedding.id}/inspiration`, {
            onSuccess: () => { setUploadError(null); form.reset(); setShowAdd(false); },
            preserveScroll: true,
        });
    }

    async function handleUpload(e: React.ChangeEvent<HTMLInputElement>) {
        const file = e.target.files?.[0];
        if (!file) return;
        setUploadError(null);
        setUploading(true);
        try {
            const fd = new FormData();
            fd.append('image', file);
            const res = await fetch(`/weddings/${wedding.id}/inspiration/upload`, {
                method: 'POST',
                headers: { 'X-CSRF-TOKEN': (document.querySelector('meta[name=csrf-token]') as HTMLMetaElement)?.content ?? '' },
                body: fd,
            });
            if (!res.ok) {
                // 422 = too large / not an image; 419 = expired session; 5xx = server.
                setUploadError(
                    res.status === 422
                        ? 'That image is too large (max 15 MB) or not a supported format.'
                        : res.status === 419
                            ? 'Your session expired — please refresh the page and try again.'
                            : 'Upload failed. Please try again.',
                );
                return;
            }
            const data = await res.json().catch(() => null);
            if (data?.url) {
                form.setData('image_url', data.url);
            } else {
                setUploadError('Upload failed — the server did not return an image.');
            }
        } catch {
            setUploadError('Upload failed. Check your connection and try again.');
        } finally {
            setUploading(false);
        }
    }

    return (
        <AppLayout wedding={wedding}>
            <div className="max-w-6xl mx-auto px-4 sm:px-6 py-10">
                {/* Editorial header */}
                <div className="flex items-baseline justify-between flex-wrap gap-4 mb-10">
                    <div>
                        <p className="text-[11px] font-medium tracking-[0.22em] uppercase text-primary mb-2">
                            Moodboard
                        </p>
                        <h1 className="font-serif text-[2.2rem] sm:text-[2.6rem] tracking-[-0.022em] leading-[1.05]">
                            Inspiration <em className="italic text-primary">board</em>
                        </h1>
                    </div>
                    <button
                        onClick={() => setShowAdd(true)}
                        className="btn-charcoal !py-2.5 !px-4 !text-[13.5px]"
                    >
                        + {t('inspiration.add')}
                    </button>
                </div>

                {items.length === 0 ? (
                    <div className="text-center py-20">
                        <div className="w-14 h-14 rounded-2xl bg-muted border border-border mx-auto mb-5 flex items-center justify-center">
                            <SparklesIcon className="w-6 h-6 text-foreground/60" />
                        </div>
                        <p className="font-serif text-[1.5rem] tracking-tight mb-2">{t('inspiration.empty_title')}</p>
                        <p className="text-[14px] text-muted-foreground">{t('inspiration.empty_sub')}</p>
                    </div>
                ) : (
                    <div className="columns-2 md:columns-3 lg:columns-4 gap-3 space-y-3">
                        {items.map((item) => (
                            <InspirationCard
                                key={item.id}
                                item={item}
                                playing={playingId === item.id}
                                onPlay={() => setPlayingId(item.id)}
                                onClosePlay={() => setPlayingId(null)}
                                onRemove={() => {
                                    if (confirm('Remove this item?')) {
                                        router.delete(`/weddings/${wedding.id}/inspiration/${item.id}`, { preserveScroll: true });
                                    }
                                }}
                            />
                        ))}
                    </div>
                )}
            </div>

            {showAdd && (
                <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-foreground/40 backdrop-blur-sm">
                    <div className="bg-card rounded-3xl p-7 w-full max-w-md shadow-2xl border border-border max-h-[90vh] overflow-y-auto">
                        <div className="flex items-center justify-between mb-5">
                            <div>
                                <p className="text-[11px] font-medium tracking-[0.22em] uppercase text-primary mb-1.5">
                                    New item
                                </p>
                                <h2 className="font-serif text-[1.6rem] tracking-tight">{t('inspiration.add')}</h2>
                            </div>
                            <button
                                onClick={closeAdd}
                                className="text-foreground/55 hover:text-foreground transition-colors p-1.5 -m-1.5"
                            >
                                <XIcon className="w-4 h-4" />
                            </button>
                        </div>

                        <form onSubmit={handleAdd} className="space-y-4">
                            <div>
                                <label className="block text-[12px] font-medium text-muted-foreground mb-2">
                                    Type
                                </label>
                                <div className="grid grid-cols-2 gap-2">
                                    {(['image', 'video'] as const).map((kind) => {
                                        const active = form.data.media_type === kind;
                                        return (
                                            <button
                                                key={kind}
                                                type="button"
                                                onClick={() => form.setData('media_type', kind)}
                                                className={`py-2.5 rounded-xl border text-[13.5px] font-medium tracking-tight transition-all ${
                                                    active
                                                        ? 'border-foreground bg-foreground/[0.04]'
                                                        : 'border-border hover:border-foreground/30'
                                                }`}
                                            >
                                                {kind === 'image' ? 'Image' : 'Video'}
                                            </button>
                                        );
                                    })}
                                </div>
                            </div>

                            {form.data.media_type === 'image' ? (
                                <div>
                                    <label className="block text-[12px] font-medium text-muted-foreground mb-1.5">
                                        Upload image
                                    </label>
                                    <input
                                        type="file"
                                        accept="image/*"
                                        onChange={handleUpload}
                                        disabled={uploading}
                                        className="w-full text-[13.5px] file:mr-3 file:px-3 file:py-2 file:rounded-lg file:border file:border-border file:bg-card file:text-foreground file:text-[12.5px] file:cursor-pointer file:hover:bg-foreground/[0.04] disabled:opacity-50"
                                    />
                                    {uploading && (
                                        <p className="text-[11.5px] text-muted-foreground mt-2">{t('common.uploading')}</p>
                                    )}
                                    {uploadError && (
                                        <p className="text-[11.5px] text-danger mt-2">{uploadError}</p>
                                    )}
                                    {form.data.image_url && !uploading && (
                                        <img src={form.data.image_url} className="mt-3 w-full h-36 object-cover rounded-xl border border-border" alt="" />
                                    )}
                                    <p className="text-[11px] text-muted-foreground mt-2">{t('inspiration.or_paste_url')}</p>
                                    <input
                                        type="url"
                                        value={form.data.image_url}
                                        onChange={(e) => form.setData('image_url', e.target.value)}
                                        placeholder="https://…"
                                        className="input mt-1"
                                    />
                                    {form.errors.image_url && (
                                        <p className="text-[11.5px] text-danger mt-1.5">{form.errors.image_url}</p>
                                    )}
                                </div>
                            ) : (
                                <div>
                                    <label className="block text-[12px] font-medium text-muted-foreground mb-1.5">
                                        Video URL (YouTube, Vimeo, TikTok)
                                    </label>
                                    <input
                                        type="url"
                                        value={form.data.video_url}
                                        onChange={(e) => form.setData('video_url', e.target.value)}
                                        placeholder="https://youtube.com/watch?v=…"
                                        className="input"
                                    />
                                    {form.data.video_url && !toEmbedUrl(form.data.video_url) && (
                                        <p className="text-[11.5px] text-danger mt-1.5">
                                            That doesn't look like a YouTube, Vimeo, or TikTok URL.
                                        </p>
                                    )}
                                    {form.errors.video_url && (
                                        <p className="text-[11.5px] text-danger mt-1.5">{form.errors.video_url}</p>
                                    )}
                                </div>
                            )}

                            <div>
                                <label className="block text-[12px] font-medium text-muted-foreground mb-1.5">{t('inspiration.item_title')}</label>
                                <input
                                    type="text"
                                    value={form.data.title}
                                    onChange={(e) => form.setData('title', e.target.value)}
                                    className="input"
                                    placeholder={t('inspiration.title_placeholder')}
                                />
                            </div>
                            <div>
                                <label className="block text-[12px] font-medium text-muted-foreground mb-1.5">{t('inspiration.notes')}</label>
                                <textarea
                                    value={form.data.notes}
                                    onChange={(e) => form.setData('notes', e.target.value)}
                                    className="input"
                                    rows={2}
                                />
                            </div>
                            <div className="flex gap-3 pt-1">
                                <button
                                    type="button"
                                    onClick={closeAdd}
                                    className="btn-outline flex-1"
                                >
                                    {t('common.cancel')}
                                </button>
                                <button
                                    type="submit"
                                    disabled={form.processing || uploading}
                                    className="btn-charcoal flex-1"
                                >
                                    {form.processing ? 'Adding…' : t('common.add')}
                                </button>
                            </div>
                        </form>
                    </div>
                </div>
            )}
        </AppLayout>
    );
}

function InspirationCard({
    item,
    playing,
    onPlay,
    onClosePlay,
    onRemove,
}: {
    item: Item;
    playing: boolean;
    onPlay: () => void;
    onClosePlay: () => void;
    onRemove: () => void;
}) {
    const t = useTranslator();
    const isVideo = item.media_type === 'video' && item.video_url;
    const embedUrl = isVideo ? toEmbedUrl(item.video_url) : null;
    const ytThumb = isVideo ? toThumbnailUrl(item.video_url) : null;

    return (
        <div className="break-inside-avoid bg-card border border-border rounded-2xl overflow-hidden group">
            {/* Media */}
            {isVideo ? (
                playing && embedUrl ? (
                    <div className="relative aspect-video bg-foreground">
                        <iframe
                            src={embedUrl + '?autoplay=1'}
                            className="absolute inset-0 w-full h-full"
                            allow="autoplay; encrypted-media; picture-in-picture"
                            allowFullScreen
                            title={item.title ?? 'Video'}
                        />
                        <button
                            onClick={onClosePlay}
                            className="absolute top-2 right-2 bg-background/90 text-foreground rounded-full p-1.5"
                            aria-label="Close"
                        >
                            <XIcon className="w-3.5 h-3.5" />
                        </button>
                    </div>
                ) : (
                    <button
                        onClick={onPlay}
                        className="relative w-full aspect-video bg-foreground/85 flex items-center justify-center overflow-hidden"
                        title={t('inspiration.play_video')}
                    >
                        {ytThumb && (
                            <img
                                src={ytThumb}
                                alt=""
                                className="absolute inset-0 w-full h-full object-cover opacity-80 group-hover:opacity-95 transition-opacity"
                            />
                        )}
                        <div className="relative w-14 h-14 rounded-full bg-background/95 flex items-center justify-center shadow-lg">
                            <svg className="w-5 h-5 text-foreground ml-0.5" viewBox="0 0 24 24" fill="currentColor">
                                <path d="M8 5v14l11-7z" />
                            </svg>
                        </div>
                        {!embedUrl && (
                            <span className="absolute bottom-1.5 left-1.5 right-1.5 text-[10px] text-background/80 text-center">
                                Embed unavailable — link only
                            </span>
                        )}
                    </button>
                )
            ) : item.image_url ? (
                <img src={item.image_url} alt={item.title ?? ''} className="w-full object-cover" />
            ) : (
                <div className="aspect-square bg-muted flex items-center justify-center text-muted-foreground text-[12px]">
                    No image
                </div>
            )}

            {/* Body */}
            {(item.title || item.notes) && (
                <div className="px-3.5 pt-3">
                    {item.title && (
                        <p className="font-serif text-[14.5px] tracking-tight leading-tight">{item.title}</p>
                    )}
                    {item.notes && (
                        <p className="text-[12.5px] text-muted-foreground mt-1 leading-[1.55]">{item.notes}</p>
                    )}
                </div>
            )}
            <div className="px-3.5 pt-2 pb-3 flex items-center justify-between">
                {isVideo && item.video_url && (
                    <a
                        href={item.video_url}
                        target="_blank"
                        rel="noreferrer"
                        className="text-[11px] text-muted-foreground hover:text-foreground transition-colors"
                    >
                        Open ↗
                    </a>
                )}
                <button
                    onClick={onRemove}
                    className="text-[11px] text-muted-foreground hover:text-danger transition-colors ml-auto"
                >
                    {t('common.remove')}
                </button>
            </div>
        </div>
    );
}

function SparklesIcon({ className = '' }: { className?: string }) {
    return (
        <svg className={className} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round">
            <path d="M12 4v4M12 16v4M4 12h4M16 12h4M6 6l2.5 2.5M15.5 15.5L18 18M6 18l2.5-2.5M15.5 8.5L18 6" />
        </svg>
    );
}

function XIcon({ className = '' }: { className?: string }) {
    return (
        <svg className={className} 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>
    );
}
