import { useCopyToClipboard } from '@/hooks/use-copy-to-clipboard';
import { useTranslation } from '@/hooks/use-translation';
import { Head, router, usePage } from '@inertiajs/react';
import { Check, Copy, Download, FileText, MapPin, UtensilsCrossed, Wifi } from 'lucide-react';

interface WifiNetwork {
    ssid: string;
    password: string;
    label: string;
}

interface EntryInstructions {
    maps_url: string;
    lockbox_code: string;
    residence_code: string;
    floor: string;
    apartment_number: string;
    notes: string;
    wifi: WifiNetwork[];
}

interface MediaItem {
    id: number;
    url: string;
    kind: string | null;
    mime_type: string | null;
    original_name: string | null;
}

/**
 * TL-305 — pourquoi le lien ne s'ouvre plus (le serveur n'envoie alors aucune
 * instruction) : lien de logement d'une heure échu, séjour terminé depuis plus
 * d'un jour, réservation annulée, ou demande pas encore acceptée.
 */
type ClosedReason = 'hour' | 'stay' | 'cancelled' | 'pending';

/** Clé de traduction et repli français, titre puis texte, par motif. */
const CLOSED_TEXT: Record<ClosedReason, { title: [string, string]; body: [string, string] }> = {
    hour: {
        title: ['expired_title', 'Ce lien a expiré'],
        body: ['expired_body', 'Pour votre sécurité, ce lien ne fonctionne qu’une heure. Contactez-nous et nous vous en envoyons un nouveau.'],
    },
    stay: {
        title: ['expired_title', 'Ce lien a expiré'],
        body: ['expired_body_stay', 'Ce lien était valable jusqu’au lendemain de votre départ. Besoin d’aide ? Contactez-nous.'],
    },
    cancelled: {
        title: ['cancelled_title', 'Réservation annulée'],
        body: ['cancelled_body', 'Cette réservation a été annulée : ce lien ne donne plus accès aux instructions.'],
    },
    pending: {
        title: ['pending_title', 'Réservation pas encore confirmée'],
        body: ['pending_body', 'Les instructions d’entrée seront accessibles dès que votre réservation sera confirmée.'],
    },
};

interface InstructionsProps {
    propertyName: string;
    guestName: string | null;
    checkIn: string | null;
    checkOut: string | null;
    instructions: EntryInstructions;
    media: MediaItem[];
    lang: string;
    /**
     * TL-305 — lien fermé, aucune instruction n'est envoyée. `hour` : lien de
     * logement d'une heure échu ; `stay` : passé 23:59 le lendemain du départ ;
     * `cancelled` : réservation annulée ; `pending` : demande pas encore
     * acceptée. Null : lien valable.
     */
    expired?: ClosedReason | null;
    /** Menu du snack The Landlord (PDF), tous logements ; null quand le lien est fermé. */
    snackMenuUrl?: string | null;
    // Contrainte `PageProps` d'Inertia : les props d'une page sont un
    // dictionnaire ouvert (la locale et les traductions partagées arrivent en
    // plus de celles-ci). Sans cette signature, usePage<InstructionsProps>() ne
    // compile pas — c'est le patron des pages récentes du projet.
    [key: string]: unknown;
}

const LANGUAGES: Array<{ code: string; label: string }> = [
    { code: 'fr', label: 'Français' },
    { code: 'en', label: 'English' },
    { code: 'ar', label: 'العربية' },
];

/**
 * Bouton « Copier » d'un code. Défini hors du composant de page pour ne pas être
 * remonté à chaque rendu (le clic perdrait le focus).
 */
function CopyButton({
    value,
    copied,
    copyLabel,
    copiedLabel,
    onCopy,
}: {
    value: string;
    copied: boolean;
    copyLabel: string;
    copiedLabel: string;
    onCopy: (value: string) => void;
}) {
    return (
        <button
            type="button"
            onClick={() => onCopy(value)}
            aria-label={copied ? copiedLabel : copyLabel}
            className="inline-flex shrink-0 items-center gap-1.5 rounded-md border border-gray-300 bg-white px-3 py-2 text-sm font-medium text-gray-700 transition hover:bg-gray-50 active:bg-gray-100"
        >
            {copied ? <Check className="h-4 w-4 text-emerald-600" /> : <Copy className="h-4 w-4" />}
            <span className={copied ? 'text-emerald-700' : undefined}>{copied ? copiedLabel : copyLabel}</span>
        </button>
    );
}

export default function InstructionsShow() {
    const {
        propertyName,
        guestName,
        checkIn,
        checkOut,
        instructions,
        media,
        lang,
        expired = null,
        snackMenuUrl = null,
    } = usePage<InstructionsProps>().props;
    const { t } = useTranslation();

    // Clé du dernier champ copié : sert à afficher « Copié » ~2s sur CE bouton.
    // Presse-papiers absent (origine HTTP simple) ou refusé : le clic ne fait
    // rien, la page ne casse pas.
    const { copiedKey, copy: copyText } = useCopyToClipboard();
    const copy = (key: string, value: string) => copyText(value, key);

    const copyLabel = t('instructions', 'copy', 'Copier');
    const copiedLabel = t('instructions', 'copied', 'Copié');

    const copyProps = (copyKey: string) => ({
        copied: copiedKey === copyKey,
        copyLabel,
        copiedLabel,
        onCopy: (value: string) => copy(copyKey, value),
    });

    const bigCodes: Array<{ key: string; label: string; value: string }> = [
        { key: 'lockbox_code', label: t('instructions', 'lockbox_code', 'Code boîtier'), value: instructions.lockbox_code },
        { key: 'residence_code', label: t('instructions', 'residence_code', 'Code résidence'), value: instructions.residence_code },
    ].filter((code) => code.value !== '');

    const smallFacts: Array<{ key: string; label: string; value: string }> = [
        { key: 'floor', label: t('instructions', 'floor', 'Étage'), value: instructions.floor },
        { key: 'apartment_number', label: t('instructions', 'apartment_number', 'Appartement'), value: instructions.apartment_number },
    ].filter((fact) => fact.value !== '');

    // Seules les adresses http(s) deviennent un lien : la règle `url` de Laravel
    // laisse passer des schémas arbitraires, et cette page est publique.
    const hasMaps = /^https?:\/\//i.test(instructions.maps_url);
    const hasCodes = bigCodes.length > 0 || smallFacts.length > 0;
    const hasWifi = instructions.wifi.length > 0;
    const hasNotes = instructions.notes !== '';
    const hasMedia = media.length > 0;
    const isEmpty = !hasMaps && !hasCodes && !hasWifi && !hasNotes && !hasMedia;

    return (
        <>
            <Head title={t('instructions', 'head_title', "Instructions d'arrivée")} />

            <div dir={lang === 'ar' ? 'rtl' : 'ltr'} lang={lang} className="min-h-screen bg-gray-50 px-3 py-4 sm:px-4 sm:py-8">
                <div className="mx-auto w-full max-w-[800px] space-y-4">
                    {/* 0 — Onglets de langue : rechargent les props sur la même page.
                        Toujours en LTR : l'ordre FR · EN · AR ne bouge pas en arabe. */}
                    <div dir="ltr" className="grid grid-cols-3 gap-1 rounded-lg bg-white p-1 shadow-sm">
                        {LANGUAGES.map((option) => (
                            <button
                                key={option.code}
                                type="button"
                                onClick={() =>
                                    router.get(
                                        window.location.pathname,
                                        { lang: option.code },
                                        { preserveScroll: true, preserveState: true, replace: true },
                                    )
                                }
                                aria-pressed={lang === option.code}
                                className={`rounded-md px-3 py-2 text-sm font-semibold transition ${
                                    lang === option.code ? 'bg-emerald-600 text-white' : 'text-gray-600 hover:bg-gray-100'
                                }`}
                            >
                                {option.label}
                            </button>
                        ))}
                    </div>

                    {/* 1 — En-tête : logement, voyageur, séjour */}
                    <header className="rounded-lg bg-white p-4 shadow-sm sm:p-6">
                        <div className="mb-4 flex justify-center">
                            <img src="/Logo.png" alt="The Landlord" className="h-12 w-auto sm:h-16" />
                        </div>
                        <p className="text-center text-xs font-semibold tracking-wide text-emerald-700 uppercase">
                            {t('instructions', 'title', "Instructions d'arrivée")}
                        </p>
                        <h1 className="mt-1 text-center text-xl leading-tight font-bold text-gray-900 sm:text-2xl">
                            <bdi>{propertyName}</bdi>
                        </h1>
                        {guestName && (
                            <p className="mt-2 text-center text-base text-gray-700">
                                <bdi>{guestName}</bdi>
                            </p>
                        )}
                        {(checkIn || checkOut) && (
                            <p className="mt-3 text-center text-sm text-gray-600">
                                <span className="text-gray-500">{t('instructions', 'stay', 'Séjour')} : </span>
                                <span dir="ltr" className="font-medium text-gray-900">
                                    {checkIn ?? '—'} → {checkOut ?? '—'}
                                </span>
                            </p>
                        )}
                        <p className="mt-3 text-center text-sm text-gray-500">
                            {t('instructions', 'subtitle', "Tout ce qu'il vous faut pour entrer dans le logement.")}
                        </p>
                    </header>

                    {/* 2 — Itinéraire */}
                    {hasMaps && (
                        <a
                            href={instructions.maps_url}
                            target="_blank"
                            rel="noopener noreferrer"
                            className="flex w-full items-center justify-center gap-2 rounded-lg bg-emerald-600 px-4 py-4 text-base font-semibold text-white shadow-sm transition hover:bg-emerald-700 active:bg-emerald-800"
                        >
                            <MapPin className="h-5 w-5" />
                            {t('instructions', 'open_maps', "Voir l'itinéraire")}
                        </a>
                    )}

                    {/* 3 — Codes d'accès : lisibles à bout de bras sur un téléphone */}
                    {hasCodes && (
                        <section className="rounded-lg bg-white p-4 shadow-sm sm:p-6">
                            <h2 className="mb-3 text-base font-semibold text-gray-900">{t('instructions', 'codes_section', "Codes d'accès")}</h2>
                            <div className="space-y-3">
                                {bigCodes.map((code) => (
                                    <div key={code.key} className="rounded-lg border border-gray-200 bg-gray-50 p-3">
                                        <p className="mb-1 text-xs font-medium tracking-wide text-gray-500 uppercase">{code.label}</p>
                                        <div className="flex flex-wrap items-center justify-between gap-3">
                                            <span className="font-mono text-3xl leading-none font-bold tracking-widest break-all text-gray-900 sm:text-4xl">
                                                <bdi dir="ltr">{code.value}</bdi>
                                            </span>
                                            <CopyButton value={code.value} {...copyProps(code.key)} />
                                        </div>
                                    </div>
                                ))}
                            </div>
                            {smallFacts.length > 0 && (
                                <div className="mt-3 grid grid-cols-2 gap-3">
                                    {smallFacts.map((fact) => (
                                        <div key={fact.key} className="rounded-lg border border-gray-200 p-3">
                                            <p className="mb-1 text-xs font-medium tracking-wide text-gray-500 uppercase">{fact.label}</p>
                                            <p className="text-lg font-semibold break-words text-gray-900">
                                                <bdi>{fact.value}</bdi>
                                            </p>
                                        </div>
                                    ))}
                                </div>
                            )}
                        </section>
                    )}

                    {/* 4 — WiFi */}
                    {hasWifi && (
                        <section className="rounded-lg bg-white p-4 shadow-sm sm:p-6">
                            <h2 className="mb-3 flex items-center gap-2 text-base font-semibold text-gray-900">
                                <Wifi className="h-4 w-4 text-gray-500" />
                                {t('instructions', 'wifi_section', 'WiFi')}
                            </h2>
                            <div className="space-y-3">
                                {instructions.wifi.map((network, index) => (
                                    <div key={`wifi-${index}`} className="rounded-lg border border-gray-200 p-3">
                                        {network.label !== '' && (
                                            <p className="mb-2 text-sm font-medium text-gray-700">
                                                <bdi>{network.label}</bdi>
                                            </p>
                                        )}
                                        {network.ssid !== '' && (
                                            <div className="mb-2 flex flex-wrap items-center justify-between gap-2">
                                                <div className="min-w-0">
                                                    <p className="text-xs font-medium tracking-wide text-gray-500 uppercase">
                                                        {t('instructions', 'wifi_ssid', 'Nom du réseau (SSID)')}
                                                    </p>
                                                    <p className="font-mono text-base break-all text-gray-900">
                                                        <bdi dir="ltr">{network.ssid}</bdi>
                                                    </p>
                                                </div>
                                                <CopyButton value={network.ssid} {...copyProps(`wifi-ssid-${index}`)} />
                                            </div>
                                        )}
                                        {network.password !== '' && (
                                            <div className="flex flex-wrap items-center justify-between gap-2">
                                                <div className="min-w-0">
                                                    <p className="text-xs font-medium tracking-wide text-gray-500 uppercase">
                                                        {t('instructions', 'wifi_password', 'Mot de passe')}
                                                    </p>
                                                    <p className="font-mono text-lg font-semibold break-all text-gray-900">
                                                        <bdi dir="ltr">{network.password}</bdi>
                                                    </p>
                                                </div>
                                                <CopyButton value={network.password} {...copyProps(`wifi-password-${index}`)} />
                                            </div>
                                        )}
                                    </div>
                                ))}
                            </div>
                        </section>
                    )}

                    {/* 5 — Notes : en production, c'est ICI que tout se trouve
                        (WiFi, codes, lien Maps, étage) — les champs structurés
                        sont le plus souvent vides. D'où la mise en avant. */}
                    {hasNotes && (
                        <section className="rounded-lg border-2 border-emerald-200 bg-white p-4 shadow-sm sm:p-6">
                            <h2 className="mb-3 text-lg font-bold text-gray-900">
                                {t('instructions', 'notes_section', 'À lire avant votre arrivée')}
                            </h2>
                            <div className="text-base leading-relaxed break-words text-gray-800">
                                {/* Une ligne = un îlot bidi : sur la page arabe, « 2eme étage » ou
                                    « Code : #0937 » gardent leur ordre, quelle que soit leur langue. */}
                                {instructions.notes.split(/\r?\n/).map((line, index) => (
                                    <div key={`note-${index}`} className="whitespace-pre-wrap">
                                        {/* Espace insécable sur une ligne vide : garde sa hauteur même
                                            sur les navigateurs sans l'unité CSS `lh` (vieux iPhone). */}
                                        <bdi>{line === '' ? ' ' : line}</bdi>
                                    </div>
                                ))}
                            </div>
                        </section>
                    )}

                    {/* 6 — Médias : preload="metadata" obligatoire, ce sont des mp4 lourds */}
                    {hasMedia && (
                        <section className="rounded-lg bg-white p-4 shadow-sm sm:p-6">
                            <h2 className="mb-3 text-base font-semibold text-gray-900">
                                {t('instructions', 'media_section', 'Vidéos et photos de guidage')}
                            </h2>
                            <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
                                {media.map((item) =>
                                    item.kind === 'video' ? (
                                        <video key={item.id} controls preload="metadata" className="w-full rounded">
                                            <source src={item.url} type={item.mime_type ?? undefined} />
                                            {t('instructions', 'video_fallback', 'Votre navigateur ne peut pas lire cette vidéo.')}
                                        </video>
                                    ) : item.kind === 'image' ? (
                                        <img
                                            key={item.id}
                                            src={item.url}
                                            loading="lazy"
                                            alt={item.original_name ?? t('instructions', 'image_alt', 'Photo de guidage')}
                                            className="w-full rounded border border-gray-200 object-cover"
                                        />
                                    ) : (
                                        <a
                                            key={item.id}
                                            href={item.url}
                                            target="_blank"
                                            rel="noopener noreferrer"
                                            className="flex items-center gap-2 rounded-lg border border-gray-200 p-3 text-sm font-medium text-emerald-700 transition hover:bg-gray-50"
                                        >
                                            <Download className="h-4 w-4 shrink-0" />
                                            <bdi className="min-w-0 break-all">
                                                {item.original_name ?? t('instructions', 'download', 'Télécharger')}
                                            </bdi>
                                        </a>
                                    ),
                                )}
                            </div>
                        </section>
                    )}

                    {/* 6b — Snack The Landlord : le menu PDF tel quel (le prix de livraison
                        n'est écrit qu'à cet endroit, jamais recopié ici). Absent si le lien est fermé. */}
                    {snackMenuUrl && (
                        <section className="rounded-lg bg-white p-4 shadow-sm sm:p-6">
                            <h2 className="mb-1 flex items-center gap-2 text-base font-semibold text-gray-900">
                                <UtensilsCrossed className="h-5 w-5 text-emerald-600" aria-hidden="true" />
                                {t('instructions', 'snack_title', 'Snack The Landlord')}
                            </h2>
                            <p className="mb-3 text-sm leading-relaxed text-gray-600">
                                {t('instructions', 'snack_body', 'Petit-déjeuner, salades et plats, livrés dans votre logement.')}
                            </p>
                            <a
                                href={snackMenuUrl}
                                target="_blank"
                                rel="noopener noreferrer"
                                className="inline-flex items-center gap-2 rounded-md bg-emerald-600 px-4 py-2 text-sm font-semibold text-white transition hover:bg-emerald-700"
                            >
                                <FileText className="h-4 w-4" aria-hidden="true" />
                                {t('instructions', 'snack_open', 'Voir le menu')}
                            </a>
                        </section>
                    )}

                    {/* 7a — Lien fermé : le serveur n'a rien envoyé, on dit pourquoi. */}
                    {expired && (
                        <section className="rounded-lg bg-white p-6 text-center shadow-sm">
                            <h2 className="text-base font-semibold text-gray-900">
                                {t('instructions', CLOSED_TEXT[expired].title[0], CLOSED_TEXT[expired].title[1])}
                            </h2>
                            <p className="mt-2 text-sm leading-relaxed text-gray-600">
                                {t('instructions', CLOSED_TEXT[expired].body[0], CLOSED_TEXT[expired].body[1])}
                            </p>
                        </section>
                    )}

                    {/* 7b — État vide : honnête, jamais une page blanche */}
                    {isEmpty && !expired && (
                        <section className="rounded-lg bg-white p-6 text-center shadow-sm">
                            <h2 className="text-base font-semibold text-gray-900">
                                {t('instructions', 'empty_title', 'Instructions bientôt disponibles')}
                            </h2>
                            <p className="mt-2 text-sm leading-relaxed text-gray-600">
                                {t(
                                    'instructions',
                                    'empty_body',
                                    "Les instructions d'arrivée ne sont pas encore disponibles pour ce logement. Contactez-nous et nous vous les transmettons tout de suite.",
                                )}
                            </p>
                        </section>
                    )}

                    <footer className="pb-6 text-center text-xs leading-relaxed text-gray-500">
                        <p className="font-semibold text-gray-700">The Landlord</p>
                        <p>
                            <a href="mailto:contact@thelandlord.tn" dir="ltr" className="underline">
                                contact@thelandlord.tn
                            </a>
                            {' · '}
                            <a href="tel:+21658595900" dir="ltr" className="underline">
                                +216 58 59 59 00
                            </a>
                        </p>
                    </footer>
                </div>
            </div>
        </>
    );
}
