{{--
    Live invoice preview for the Master Control Invoice tab.

    This is NOT a mock-up. It renders the exact blades the printer renders
    (resources/views/invoices/print/{a4,thermal80}.blade.php) against a
    worst-case sample sale, so a landlord approving what they see here has
    approved the real document. Both stocks are shown because a tenant runs
    both: A4 in the office, the 80mm roll at the counter.

    The layouts are sized in millimetres — right for paper, far too wide for a
    form column — so each is scaled to fit. `transform: scale()` is used rather
    than `zoom` deliberately: it is a purely visual scale that cannot reflow the
    document, so nothing re-wraps between what is previewed and what prints.
--}}
<div
    class="fi-inv-preview"
    x-data="{
        paper: 'a4',
        pad: 24,
        max: { a4: 1, thermal80: 1.9 },
        view: {
            a4: { scale: 1, height: 0, offset: 0 },
            thermal80: { scale: 1, height: 0, offset: 0 },
        },

        fit(name) {
            const stage = this.$refs[name + 'Stage'];
            const doc = this.$refs[name + 'Doc'];

            if (! stage || ! doc) return;

            const natural = doc.offsetWidth;
            const avail = stage.clientWidth - this.pad;

            if (natural <= 0 || avail <= 0) return;

            const scale = Math.max(0.25, Math.min(this.max[name], avail / natural));
            const height = Math.round(doc.offsetHeight * scale + this.pad);
            const offset = Math.round(Math.max(0, (avail - natural * scale) / 2));
            const view = this.view[name];

            // Guard the assignment: the observer below watches the stage, whose
            // height this sets.
            if (view.scale === scale && view.height === height && view.offset === offset) return;

            view.scale = scale;
            view.height = height;
            view.offset = offset;
        },

        fitAll() {
            this.fit('a4');
            this.fit('thermal80');
        },

        init() {
            this.$nextTick(() => this.fitAll());

            const observer = new ResizeObserver(() => this.fitAll());

            for (const name of ['a4', 'thermal80']) {
                observer.observe(this.$refs[name + 'Stage']);
                observer.observe(this.$refs[name + 'Doc']);
            }

            // Web fonts and the logo land after first paint and change the height.
            window.setTimeout(() => this.fitAll(), 400);
        },
    }"
>
    <div class="mb-2 flex flex-wrap items-center justify-between gap-2">
        <p class="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
            Live preview — the real print
        </p>

        <div class="flex items-center gap-0.5 rounded-lg bg-gray-100 p-0.5 dark:bg-white/5">
            @foreach (['a4' => 'A4', 'thermal80' => '80 mm'] as $key => $label)
                <button
                    type="button"
                    x-on:click="paper = @js($key)"
                    x-bind:class="paper === @js($key)
                        ? 'bg-white text-gray-900 shadow-sm dark:bg-white/10 dark:text-white'
                        : 'text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white'"
                    class="rounded-md px-2.5 py-1 text-xs font-medium transition"
                >{{ $label }}</button>
            @endforeach

            <span
                class="ml-1.5 pr-1.5 text-[11px] tabular-nums text-gray-400"
                x-text="Math.round(view[paper].scale * 100) + '%'"
            ></span>
        </div>
    </div>

    {{--
        Both stocks stay in the layout at all times; the inactive one is hidden
        with `visibility` rather than `display` so it can still be measured. A
        stage that reports zero width can't be scaled to fit.
    --}}
    <div class="fi-inv-preview__frame">
        <div
            class="fi-inv-preview__stage"
            x-ref="a4Stage"
            x-bind:class="paper === 'a4' ? 'is-active' : ''"
            x-bind:style="'height: ' + view.a4.height + 'px'"
        >
            <div
                class="fi-inv-preview__doc"
                x-ref="a4Doc"
                x-bind:style="'transform: scale(' + view.a4.scale + '); margin-left: ' + view.a4.offset + 'px'"
            >
                <div class="fi-inv-preview__sheet">
                    @include('invoices.print.a4', ['doc' => $doc, 'preview' => true])
                </div>
            </div>
        </div>

        <div
            class="fi-inv-preview__stage"
            x-ref="thermal80Stage"
            x-bind:class="paper === 'thermal80' ? 'is-active' : ''"
            x-bind:style="'height: ' + view.thermal80.height + 'px'"
        >
            <div
                class="fi-inv-preview__doc"
                x-ref="thermal80Doc"
                x-bind:style="'transform: scale(' + view.thermal80.scale + '); margin-left: ' + view.thermal80.offset + 'px'"
            >
                <div class="fi-inv-preview__sheet fi-inv-preview__sheet--roll">
                    @include('invoices.print.thermal80', ['doc' => $doc, 'preview' => true])
                </div>
            </div>
        </div>
    </div>

    <p class="mt-1.5 text-[11px] leading-relaxed text-gray-500 dark:text-gray-400">
        A worst-case sample sale: mixed VAT rates, line and invoice discounts, a
        voucher, redeemed loyalty points, a bundle, serial and batch tracking,
        packaging add-on lines, and a part-settled split tender including an uncleared
        cheque. If the letterhead survives this, it survives anything.
    </p>

    <style>
        .fi-inv-preview__frame { position: relative; overflow: hidden; border-radius: 0.75rem;
            border: 1px solid rgb(229 231 235); background: rgb(243 244 246); }
        .dark .fi-inv-preview__frame { border-color: rgb(255 255 255 / 0.1); background: rgb(3 7 18); }

        .fi-inv-preview__stage { position: absolute; top: 0; left: 0; width: 100%;
            visibility: hidden; overflow: hidden; padding: 12px; }
        .fi-inv-preview__stage.is-active { position: relative; visibility: visible; }

        .fi-inv-preview__doc { transform-origin: top left; width: max-content; }
        .fi-inv-preview__sheet { background: #fff; box-shadow: 0 1px 3px rgb(0 0 0 / 0.18); }
        /* An 80mm roll is 80mm of paper with a ~4mm unprintable margin each side;
           the sheet shows the stock, the layout inside shows the printable 72mm. */
        .fi-inv-preview__sheet--roll { padding: 0 4mm; }
    </style>
</div>
