@extends('layouts.app')

@section('main_class', 'video-view-page')
@php
    $metaTitle = $shareTitle ?? $video->title;
    $metaDesc  = $shareDescription ?? $video->description;
    $metaUrl   = $video->share_url;
@endphp
@section('title', $metaTitle . ' | ' . config('app.name'))

@push('head')
<meta property="og:title"       content="{{ $metaTitle }}">
<meta property="og:description" content="{{ Str::limit(strip_tags($metaDesc ?? config('app.name') . ' — watch now'), 200) }}">
<meta property="og:image"        content="{{ route('videos.ogImage', $video) }}">
<meta property="og:image:width"  content="1200">
<meta property="og:image:height" content="630">
<meta property="og:url"         content="{{ $metaUrl }}">
<meta property="og:type"        content="video.other">
<meta property="og:site_name"   content="{{ config('app.name') }}">
<meta name="twitter:card"       content="summary_large_image">
<meta name="twitter:title"      content="{{ $metaTitle }}">
<meta name="twitter:description" content="{{ Str::limit(strip_tags($metaDesc ?? ''), 200) }}">
<meta name="twitter:image"      content="{{ route('videos.ogImage', $video) }}">
@endpush

@section('extra_styles')
    <style>
        /* Video Section */
        .yt-video-section {
            flex: 1;
            min-width: 0;
        }

        /* Video Player */
        .video-container {
            position: relative;
            aspect-ratio: 16/9;
            background: #000;
            border-radius: 12px;
            overflow: hidden;
            max-height: 70vh;
            display: flex;
            justify-content: center;
            align-items: center;
            width: 100%;
        }

        .video-container.portrait,
        .video-container.square,
        .video-container.ultrawide {
            margin: 0 auto;
            width: auto;
        }

        .video-container.portrait {
            aspect-ratio: 9/16;
            max-width: 50vh;
        }

        .video-container.square {
            aspect-ratio: 1/1;
            max-width: 70vh;
        }

        .video-container.ultrawide {
            aspect-ratio: 21/9;
            max-width: 100%;
        }

        .video-container video {
            width: 100%;
            height: 100%;
            object-fit: contain;
        }

        /* Playlist Navigation Controls */
        .playlist-controls {
            position: absolute;
            bottom: 60px;
            left: 50%;
            transform: translateX(-50%);
            display: flex;
            align-items: center;
            gap: 12px;
            background: rgba(0, 0, 0, 0.8);
            padding: 8px 16px;
            border-radius: 24px;
            z-index: 10;
            opacity: 0;
            transition: opacity 0.3s ease;
        }

        .video-container:hover .playlist-controls,
        .playlist-controls.visible {
            opacity: 1;
        }

        .playlist-nav-btn {
            background: transparent;
            border: none;
            color: white;
            cursor: pointer;
            padding: 8px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: background 0.2s ease;
        }

        .playlist-nav-btn:hover {
            background: rgba(255, 255, 255, 0.2);
        }

        .playlist-nav-btn:disabled {
            opacity: 0.3;
            cursor: not-allowed;
        }

        .playlist-nav-btn:disabled:hover {
            background: transparent;
        }

        .playlist-nav-btn i {
            font-size: 20px;
        }

        .playlist-nav-label {
            font-size: 12px;
            color: #aaa;
            max-width: 120px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        /* Autoplay Toggle */
        .autoplay-toggle {
            display: flex;
            align-items: center;
            gap: 8px;
            padding: 0 8px;
            border-left: 1px solid rgba(255, 255, 255, 0.2);
        }

        .autoplay-toggle label {
            font-size: 12px;
            color: #aaa;
            cursor: pointer;
            white-space: nowrap;
        }

        .autoplay-switch {
            position: relative;
            width: 36px;
            height: 20px;
        }

        .autoplay-switch input {
            opacity: 0;
            width: 0;
            height: 0;
        }

        .autoplay-slider {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #666;
            transition: 0.3s;
            border-radius: 20px;
        }

        .autoplay-slider:before {
            position: absolute;
            content: "";
            height: 14px;
            width: 14px;
            left: 3px;
            bottom: 3px;
            background-color: white;
            transition: 0.3s;
            border-radius: 50%;
        }

        .autoplay-switch input:checked+.autoplay-slider {
            background-color: var(--brand-red);
        }

        .autoplay-switch input:checked+.autoplay-slider:before {
            transform: translateX(16px);
        }

        /* Keyboard hint */
        .keyboard-hint {
            position: absolute;
            bottom: 10px;
            right: 10px;
            font-size: 10px;
            color: rgba(255, 255, 255, 0.5);
            background: rgba(0, 0, 0, 0.6);
            padding: 4px 8px;
            border-radius: 4px;
        }

        /* Video Info */
        .video-title {
            font-size: 20px;
            font-weight: 500;
            margin: 16px 0 8px;
            line-height: 1.3;
        }

        .video-stats-row {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding-bottom: 12px;
            border-bottom: 1px solid var(--border-color);
            flex-wrap: wrap;
            gap: 12px;
        }

        .video-stats-left {
            display: flex;
            align-items: center;
            gap: 16px;
            color: var(--text-secondary);
        }

        .video-actions {
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .action-btn,
        .comments-section .action-btn {
            border: none;
            border-radius: 8px;
            padding: 8px 14px;
            font-size: 0.82rem;
            font-weight: 500;
            cursor: pointer;
            background: var(--bg-secondary);
            border: 1px solid var(--border-color);
            color: var(--text-primary);
            display: flex;
            align-items: center;
            gap: 6px;
            transition: all 0.2s ease;
        }

        .action-btn:hover,
        .comments-section .action-btn:hover {
            background: var(--border-color);
            transform: translateY(-1px);
        }

        .action-btn:active,
        .comments-section .action-btn:active {
            transform: translateY(0);
        }

        .action-btn svg,
        .action-btn i,
        .comments-section .action-btn svg,
        .comments-section .action-btn i {
            flex-shrink: 0;
        }

        .action-btn.comment-btn {
            background: var(--brand-red);
            color: white;
            border-color: var(--brand-red);
        }


        /* Description */
        .video-description {
            background: var(--bg-secondary);
            border-radius: 12px;
            padding: 16px;
            margin-top: 16px;
        }

        .description-text {
            white-space: pre-wrap;
            font-size: 14px;
            line-height: 1.5;
        }

        /* Sidebar */
        .yt-sidebar-container {
            width: 400px;
            flex-shrink: 0;
        }

        .sidebar-video-card {
            display: flex;
            gap: 8px;
            margin-bottom: 8px;
            cursor: pointer;
            border-radius: 8px;
            padding: 4px;
            transition: background .15s;
        }

        .sidebar-video-card.current-video {
            background: rgba(239,68,68,.12);
            border-left: 3px solid #ef4444;
        }

        .sidebar-video-card.rec-next-up {
            border-left: 3px solid var(--brand-red);
        }

        .sidebar-video-card.rec-next-up .sidebar-title::before {
            content: '▶ ';
            color: var(--brand-red);
            font-size: 10px;
        }

        .sidebar-thumb {
            width: 168px;
            aspect-ratio: 16/9;
            border-radius: 8px;
            overflow: hidden;
            background: #1a1a1a;
            flex-shrink: 0;
        }

        .sidebar-thumb img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }

        .sidebar-info {
            flex: 1;
            min-width: 0;
        }

        .sidebar-title {
            font-size: 14px;
            font-weight: 500;
            margin-bottom: 4px;
            display: -webkit-box;
            -webkit-line-clamp: 2;
            -webkit-box-orient: vertical;
            overflow: hidden;
        }

        .sidebar-meta {
            font-size: 12px;
            color: var(--text-secondary);
        }

        /* Responsive */
        @media (max-width: 1300px) {
            .yt-sidebar-container {
                width: 300px;
            }
        }

        @media (max-width: 991px) {
            .yt-main {
                margin-left: 0;
                flex-direction: column;
            }

            .yt-sidebar-container {
                width: 100%;
            }

            .sidebar-video-card {
                flex-direction: column;
            }

            .sidebar-thumb {
                width: 100%;
            }

            .video-layout-container {
                flex-direction: column !important;
            }

            .yt-video-section {
                width: 100% !important;
                flex: none !important;
            }

            .yt-sidebar-container {
                width: 100% !important;
                margin-top: 16px;
            }
        }

        @media (max-width: 576px) {
            .video-stats-row {
                flex-direction: column;
                align-items: flex-start;
            }

            .video-actions {
                width: 100%;
                overflow-x: auto;
                justify-content: flex-start;
            }

            .video-container {
                max-height: 50vh !important;
                border-radius: 0 !important;
            }

            .video-container video {
                object-fit: contain !important;
            }

            .video-title {
                font-size: 16px !important;
                margin: 12px 0 6px !important;
            }

            .channel-row {
                flex-direction: column;
                align-items: flex-start !important;
                gap: 12px;
            }

            .channel-info {
                width: 100%;
            }

            .subscribe-btn {
                width: 100%;
            }

            .video-description {
                padding: 12px !important;
            }

            .comment-form {
                flex-direction: column !important;
                align-items: stretch !important;
                gap: 12px !important;
            }

            .comment-form>div {
                flex-direction: column !important;
                align-items: stretch !important;
                gap: 12px !important;
                width: 100% !important;
            }

            .comment-form textarea {
                height: 80px !important;
                width: 100% !important;
            }

            .comment-form button {
                align-self: flex-end !important;
                width: auto !important;
                padding: 8px 20px !important;
            }
        }
    </style>
@endsection

@section('content')

    <!-- Video Layout Container -->
    <div class="video-layout-container" style="display: flex; gap: 24px; max-width: 1800px; margin: 0 auto;">

        <!-- Video Section -->
        <div class="yt-video-section">
            {{-- Generic video: always a single video track (mp4/HLS), GPU-encoded server-side --}}
            <x-video-player :video="$video"
                :next-video="$nextVideo ?? null"
                :previous-video="$previousVideo ?? null"
                :playlist="$playlist ?? null"
                :playlist-videos="$playlistVideos ?? null" />

            <!-- Video Title with Film Icon (Generic Type) -->
            @php $titleLangFlag = \App\Data\Languages::flag($video->language); @endphp
            <h1 class="video-title" style="display: flex; align-items: center; gap: 10px; margin: 8px 0 6px;">
                <i class="bi bi-film" style="color: #ef4444; flex-shrink:0;"></i>
                <span class="fi fi-{{ $titleLangFlag ?: 'xx' }}" id="videoTitleFlag" style="width:22px;height:16px;border-radius:2px;display:{{ $titleLangFlag ? 'inline-block' : 'none' }};flex-shrink:0;"></span>
                <span id="videoTitleText" data-primary-title="{{ $video->title }}">{{ $video->title }}</span>
            </h1>

            <!-- Stats Row - Hidden, shown in description box -->
            <div class="video-stats-row" style="display: none;">
                <div class="video-stats-left">
                    <span>{{ number_format($video->view_count) }} views</span>
                    <span>•</span>
                    <span>{{ $video->created_at->format('M d, Y') }}</span>
                </div>
            </div>

            <!-- Channel Row - All in one line -->
            <x-channel-row :video="$video" />

            @include('videos.partials.description-box', ['video' => $video])

            <x-video-comments :video="$video" />

        </div>

        <!-- Sidebar - Up Next / Recommendations -->
        <div class="yt-sidebar-container" style="display: flex; flex-direction: column; gap: 16px;">
            @if ($playlist && $playlistVideos && $playlistVideos->count() > 0)
                <h3 style="font-size: 16px; font-weight: 500; margin-bottom: 8px;">
                    <i class="bi bi-collection-play" style="margin-right: 8px;"></i>
                    {{ $playlist->name }}
                    <span
                        style="font-weight: 400; color: var(--text-secondary); font-size: 14px;">({{ $playlistVideos->count() }}
                        videos)</span>
                </h3>

                {{-- Playlist controls --}}
                <div class="pl-controls-bar">
                    <button class="pl-ctrl-btn" id="plPrevBtn" title="Previous" onclick="window.plPrev()">
                        <i class="bi bi-skip-start-fill"></i>
                    </button>
                    <button class="pl-ctrl-btn" id="plNextBtn" title="Next" onclick="window.plNext()">
                        <i class="bi bi-skip-end-fill"></i>
                    </button>
                    <div class="pl-ctrl-divider"></div>
                    <button class="pl-ctrl-btn" id="plShuffleBtn" title="Shuffle" onclick="plToggleShuffle()">
                        <i class="bi bi-shuffle"></i>
                    </button>
                    <button class="pl-ctrl-btn" id="plLoopBtn" title="Loop" onclick="plToggleLoop()">
                        <i class="bi bi-repeat"></i>
                    </button>
                    <button class="pl-ctrl-btn pl-ctrl-autoplay" id="plAutoplayBtn" title="Autoplay" onclick="plToggleAutoplay()">
                        <i class="bi bi-play-circle"></i>
                        <span class="pl-autoplay-label">Autoplay</span>
                    </button>
                    <div class="pl-ctrl-divider"></div>
                    <button class="pl-ctrl-btn" id="plShareBtn" title="Share playlist"
                        onclick="openShareModal('{{ route('playlists.showByToken', $playlist->share_token) }}','{{ addslashes($playlist->name) }}','{{ route('playlists.recordShare', $playlist) }}','','')">
                        <i class="bi bi-share"></i>
                    </button>
                </div>

                <script>
                (function () {
                var PL_ID      = '{{ $playlist->share_token }}';
                var PL_CURRENT = {{ $video->id }};
                var PL_VIDEOS  = {!! $playlistVideos->map(fn($v) => ['id' => $v->id, 'url' => route('videos.show', $v).'?playlist='.$playlist->share_token])->values()->toJson() !!};

                function plGet(k,d){ var v=localStorage.getItem('pl_'+k+'_'+PL_ID); return v!==null?v:d; }
                function plSet(k,v){ localStorage.setItem('pl_'+k+'_'+PL_ID,v); }

                var plAutoplay     = plGet('autoplay','1');
                var plLoop         = plGet('loop','off');
                var plShuffle      = plGet('shuffle','0');
                var plTransiting   = false;

                // ── shuffle helpers ──────────────────────────────────────
                function plShuffleOrder(){ var o=PL_VIDEOS.map(function(_,i){return i;}); for(var i=o.length-1;i>0;i--){var j=Math.floor(Math.random()*(i+1));var t=o[i];o[i]=o[j];o[j]=t;} localStorage.setItem('pl_shuffleOrder_'+PL_ID,JSON.stringify(o)); return o; }
                function plGetOrder(){ var r=localStorage.getItem('pl_shuffleOrder_'+PL_ID); if(r){try{return JSON.parse(r);}catch(e){}} return null; }

                // ── compute adjacent URLs from current state ──────────────
                function plAdj(curId) {
                    var idx = PL_VIDEOS.findIndex(function(v){ return v.id===curId; });
                    if (plShuffle==='1') {
                        var ord=plGetOrder()||plShuffleOrder();
                        var pos=ord.indexOf(idx);
                        var prevPos=pos>0?pos-1:(plLoop==='all'?ord.length-1:-1);
                        var nextPos=pos<ord.length-1?pos+1:(plLoop==='all'?0:-1);
                        return { prev: prevPos>=0?PL_VIDEOS[ord[prevPos]].url:'', next: nextPos>=0?PL_VIDEOS[ord[nextPos]].url:'' };
                    }
                    return {
                        prev: idx>0?PL_VIDEOS[idx-1].url:'',
                        next: idx<PL_VIDEOS.length-1?PL_VIDEOS[idx+1].url:(plLoop==='all'?PL_VIDEOS[0].url:'')
                    };
                }

                // ── time formatter ───────────────────────────────────────
                function plFmt(s){ var m=Math.floor(s/60),ss=Math.floor(s%60); return m+':'+(ss<10?'0':'')+ss; }

                // ── SPA transition — load new video source + update UI ────
                async function plTransitionTo(url, pushHist) {
                    if (!url || plTransiting) return;
                    plTransiting = true;
                    if (window._spaScrollToVideo) window._spaScrollToVideo();
                    try {
                        var m = url.match(/\/videos\/([^/?#]+)/);
                        if (!m) { window.location.href=url; return; }
                        var qs = url.indexOf('?')!==-1 ? url.substring(url.indexOf('?')) : '';
                        var resp;
                        try { resp = await fetch('/videos/'+m[1]+'/player-data'+qs); }
                        catch(e) { window.location.href=url; return; }
                        if (!resp.ok) { window.location.href=url; return; }
                        var d;
                        try { d = await resp.json(); }
                        catch(e) { window.location.href=url; return; }

                        // Different player type? Fall back to hard nav so the
                        // correct type view (music/match) handles playback.
                        if (d.type && d.type !== 'generic') { window.location.href = url; return; }

                        // preserve volume/muted across source swap
                        var vid = document.getElementById('videoPlayer');
                        var _savedVol = vid ? vid.volume : null;
                        var _savedMuted = vid ? vid.muted : null;

                        // swap video source (HLS preferred, MP4 fallback)
                        try { if (window._ytpLoadSource) window._ytpLoadSource(d.hls_url, d.stream_url); }
                        catch(e) { console.warn('_ytpLoadSource', e); }

                        if (vid && _savedVol !== null) { vid.volume = _savedVol; vid.muted = _savedMuted; }

                        // reset progress bar
                        var pl=document.getElementById('ytpPlayed'),sc=document.getElementById('ytpScrubber');
                        var cu=document.getElementById('ytpCurrent'),dr=document.getElementById('ytpDuration');
                        if(pl) pl.style.width='0%';
                        if(sc) sc.style.left='0%';
                        if(cu) cu.textContent='0:00';
                        if(dr&&d.duration) dr.textContent=plFmt(d.duration);

                        // update page title
                        var ts=document.getElementById('videoTitleText');
                        if(ts){ ts.textContent=d.title; ts.dataset.primaryTitle=d.title; }
                        document.title=d.title+' | {{ config("app.name") }}';

                        // update loop state on video element
                        if(vid) vid.loop=(plLoop==='one');

                        // update state
                        PL_CURRENT = d.id;
                        try { plRender(); plHighlight(d.id, true); } catch(e) { console.warn('plRender', e); }

                        // history
                        if(pushHist!==false) history.pushState({plVideoId:d.id,url:url},'',url);

                        // async: swap description + comments from fetched page
                        plSwapContent(url);
                    } catch(e) {
                        console.warn('plTransitionTo',e);
                    } finally {
                        plTransiting=false;
                    }
                }

                // ── background page swap: description + comments ──────────
                async function plSwapContent(url) {
                    try {
                        var resp = await fetch(url, {headers:{'Accept':'text/html','X-Requested-With':'XMLHttpRequest'}});
                        var html = await resp.text();
                        var doc  = new DOMParser().parseFromString(html,'text/html');

                        // swap description box
                        var nv=doc.getElementById('vdbWrap'), ov=document.getElementById('vdbWrap');
                        if(nv&&ov){ ov.innerHTML=nv.innerHTML; requestAnimationFrame(function(){ if(window._vdbCheckOverflow)_vdbCheckOverflow(); }); }

                        // swap channel row
                        var nc=doc.querySelector('.channel-row'), oc=document.querySelector('.channel-row');
                        if(nc&&oc) oc.innerHTML=nc.innerHTML;

                        // swap comments (HTML + re-run its init script)
                        var ny=doc.getElementById('ytcSection'), oy=document.getElementById('ytcSection');
                        if(ny&&oy) {
                            oy.innerHTML=ny.innerHTML;
                            var ytcScript=Array.from(doc.querySelectorAll('script')).find(function(s){return s.textContent.includes('const YTC =');});
                            if(ytcScript){
                                var ns=document.createElement('script');
                                ns.textContent=ytcScript.textContent;
                                document.body.appendChild(ns);
                                document.body.removeChild(ns);
                            }
                        }
                    } catch(e){ console.warn('plSwapContent',e); }
                }

                // ── sidebar highlight ────────────────────────────────────
                function plHighlight(activeId, scroll) {
                    document.querySelectorAll('.sidebar-video-card[data-pl-id]').forEach(function(c){
                        c.classList.toggle('current-video', parseInt(c.dataset.plId)===activeId);
                    });
                    if(scroll) {
                        // Scroll only inside the sidebar list container — never the page —
                        // so focus stays on the player when the track changes.
                        var active = document.querySelector('.sidebar-video-card.current-video');
                        if (!active) return;
                        var list = active.closest('.recommended-videos-list') || active.parentElement;
                        if (list) {
                            var lr = list.getBoundingClientRect();
                            var ar = active.getBoundingClientRect();
                            var delta = (ar.top + ar.height/2) - (lr.top + lr.height/2);
                            list.scrollTo({ top: list.scrollTop + delta, behavior: 'smooth' });
                        }
                    }
                }

                // ── render control button states ─────────────────────────
                function plRender(){
                    var adj=plAdj(PL_CURRENT);
                    var sb=document.getElementById('plShuffleBtn'),lb=document.getElementById('plLoopBtn');
                    var ab=document.getElementById('plAutoplayBtn'),nb=document.getElementById('plNextBtn'),pb=document.getElementById('plPrevBtn');
                    if(sb){ sb.classList.toggle('pl-ctrl-active',plShuffle==='1'); sb.title='Shuffle: '+(plShuffle==='1'?'On':'Off'); }
                    if(lb){
                        lb.classList.remove('pl-ctrl-active');
                        if(plLoop==='all'){ lb.classList.add('pl-ctrl-active'); lb.innerHTML='<i class="bi bi-repeat"></i>'; lb.title='Loop: All'; }
                        else if(plLoop==='one'){ lb.classList.add('pl-ctrl-active'); lb.innerHTML='<i class="bi bi-repeat-1"></i>'; lb.title='Loop: One'; }
                        else { lb.innerHTML='<i class="bi bi-repeat"></i>'; lb.title='Loop: Off'; }
                    }
                    if(ab){ ab.classList.toggle('pl-ctrl-active',plAutoplay==='1'); ab.title='Autoplay: '+(plAutoplay==='1'?'On':'Off'); }
                    if(nb) nb.disabled=!adj.next;
                    if(pb) pb.disabled=!adj.prev;
                    // In-player prev/next buttons
                    document.querySelectorAll('.ytp-prev-btn').forEach(function(b){ b.disabled=!adj.prev; b.style.opacity=adj.prev?'':'0.4'; });
                    document.querySelectorAll('.ytp-next-btn').forEach(function(b){ b.disabled=!adj.next; b.style.opacity=adj.next?'':'0.4'; });
                }

                // ── public API ────────────────────────────────────────────
                window.plGoTo = function(url){ if(url) plTransitionTo(url); };
                window.plNext = function(){ var a=plAdj(PL_CURRENT); if(a.next) plTransitionTo(a.next); };
                window.plPrev = function(){ var a=plAdj(PL_CURRENT); if(a.prev) plTransitionTo(a.prev); };

                // hook into video player: intercept next/prev and ended
                window._ytpNavOverride = {
                    next: function(_url){ window.plNext(); },
                    prev: function(_url){ window.plPrev(); }
                };
                window._plOnVideoEnd = function(){ if(plLoop==='one') return; if(plAutoplay==='1') window.plNext(); };

                window.plToggleShuffle  = function(){ plShuffle=plShuffle==='1'?'0':'1'; plSet('shuffle',plShuffle); if(plShuffle==='1') plShuffleOrder(); else localStorage.removeItem('pl_shuffleOrder_'+PL_ID); plRender(); };
                window.plToggleLoop     = function(){ var s=['off','all','one']; var i=s.indexOf(plLoop); plLoop=s[(i+1)%s.length]; plSet('loop',plLoop); plRender(); var v=document.getElementById('videoPlayer'); if(v) v.loop=(plLoop==='one'); };
                window.plToggleAutoplay = function(){ plAutoplay=plAutoplay==='1'?'0':'1'; plSet('autoplay',plAutoplay); plRender(); };

                // ── browser back/forward ──────────────────────────────────
                window.addEventListener('popstate', function(e){ if(e.state&&e.state.url) plTransitionTo(e.state.url, false); });

                // ── init ──────────────────────────────────────────────────
                function plInit(){
                    var v=document.getElementById('videoPlayer');
                    if(v&&plLoop==='one') v.loop=true;
                    plRender();
                    plHighlight(PL_CURRENT, false);
                }
                if(document.readyState==='loading') document.addEventListener('DOMContentLoaded',plInit); else plInit();
                })();
                </script>

                <div class="recommended-videos-list">
                    @foreach ($playlistVideos as $index => $playlistVideo)
                        @php $isCurrentTrack = $playlistVideo->id === $video->id; @endphp
                        <div class="sidebar-video-card{{ $isCurrentTrack ? ' current-video' : '' }}"
                            data-pl-id="{{ $playlistVideo->id }}"
                            onclick="plGoTo('{{ route('videos.show', $playlistVideo) }}?playlist={{ $playlist->share_token }}')"
                            style="cursor:pointer;">
                                <div class="sidebar-thumb" style="position: relative;">
                                    @if ($playlistVideo->thumbnail)
                                        <img src="{{ route('media.thumbnail', $playlistVideo->thumbnail) }}"
                                            alt="{{ $playlistVideo->title }}">
                                    @else
                                        <img src="https://picsum.photos/seed/{{ $playlistVideo->id }}/320/180"
                                            alt="{{ $playlistVideo->title }}">
                                    @endif
                                    @if ($playlistVideo->duration)
                                        <span
                                            class="yt-video-duration">{{ gmdate('i:s', $playlistVideo->duration) }}</span>
                                    @endif
                                    @if ($playlistVideo->is_shorts)
                                        <span class="yt-shorts-badge"
                                            style="position: absolute; top: 8px; left: 8px; font-size: 10px; padding: 2px 6px;">
                                            <i class="bi bi-collection-play-fill"></i> SHORTS
                                        </span>
                                    @endif
                                    <!-- Playlist position indicator -->
                                    <span
                                        style="position: absolute; bottom: 4px; left: 4px; background: rgba(0,0,0,0.8); color: white; padding: 2px 6px; border-radius: 4px; font-size: 12px; font-weight: 500;">
                                        {{ $index + 1 }}
                                    </span>
                                </div>
                                <div class="sidebar-info">
                                    <div class="sidebar-title">
                                        <i class="bi {{ match ($playlistVideo->type) {'music' => 'bi-music-note','match' => 'bi-trophy',default => 'bi-film'} }}"
                                            style="color: #ef4444; margin-right: 4px; font-size: 12px;"></i>
                                        {{ Str::limit($playlistVideo->title, 60) }}
                                    </div>
                                    <div class="sidebar-meta">
                                        <div>{{ $playlistVideo->user->name ?? 'Unknown' }}</div>
                                        <div>{{ number_format($playlistVideo->view_count) }} views •
                                            {{ $playlistVideo->created_at->diffForHumans() }}</div>
                                    </div>
                                </div>
                            </div>
                    @endforeach
                </div>
                @if ($playlist->canEdit(Auth::user()))
                    <a href="{{ route('playlists.show', $playlist->id) }}" class="action-btn" style="margin-top: 12px;">
                        <i class="bi bi-pencil"></i> <span>Edit Playlist</span>
                    </a>
                @endif
            @else
                <div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:12px;">
                    <h3 style="font-size:16px; font-weight:500; margin:0;">Up Next</h3>
                    <button id="recAutoplayBtn" class="pl-ctrl-btn pl-ctrl-autoplay" title="Autoplay" onclick="recToggleAutoplay()" style="margin-left:auto;">
                        <i class="bi bi-play-circle"></i>
                        <span class="pl-autoplay-label">Autoplay</span>
                    </button>
                </div>

                <script>
                (function () {
                var recTransiting = false;
                var recAutoplay   = localStorage.getItem('ytpAutoplay_solo') !== '0';

                // persists across sidebar swaps so already-autoplayed videos are not repeated
                window._recWatched = window._recWatched || new Set();

                function recFmt(s){ var m=Math.floor(s/60),ss=Math.floor(s%60); return m+':'+(ss<10?'0':'')+ss; }

                function recNextUnwatched() {
                    var cards = document.querySelectorAll('#recList .sidebar-video-card[data-rec-url]');
                    for (var i = 0; i < cards.length; i++) {
                        if (!window._recWatched.has(cards[i].dataset.recUrl)) return cards[i];
                    }
                    return null;
                }

                function recRender() {
                    var btn = document.getElementById('recAutoplayBtn');
                    if (!btn) return;
                    btn.classList.toggle('pl-ctrl-active', recAutoplay);
                    btn.title = 'Autoplay: ' + (recAutoplay ? 'On' : 'Off');
                    // highlight the first unwatched card as "next up"
                    var cards = document.querySelectorAll('#recList .sidebar-video-card');
                    var nextUp = recNextUnwatched() || cards[0];
                    cards.forEach(function(c){ c.style.opacity = ''; c.classList.remove('rec-next-up'); });
                    if (recAutoplay && nextUp) { nextUp.style.opacity = '1'; nextUp.classList.add('rec-next-up'); }
                }

                async function recTransitionTo(url, pushHist) {
                    if (recTransiting) return;
                    recTransiting = true;
                    if (window._spaScrollToVideo) window._spaScrollToVideo();
                    try {
                        var dataUrl = url.split('?')[0] + '/player-data';
                        var resp = await fetch(dataUrl, { headers: { 'X-Requested-With': 'XMLHttpRequest' } });
                        if (!resp.ok) { window.location.href = url; return; }
                        var d = await resp.json();

                        // Different player type? Hard-nav so the correct view loads.
                        if (d.type && d.type !== 'generic') { window.location.href = url; return; }

                        // preserve volume/muted across source swap
                        var vid = document.getElementById('videoPlayer');
                        var _savedVol = vid ? vid.volume : null;
                        var _savedMuted = vid ? vid.muted : null;

                        if (window._ytpLoadSource) window._ytpLoadSource(d.hls_url, d.stream_url);

                        if (vid && _savedVol !== null) { vid.volume = _savedVol; vid.muted = _savedMuted; }

                        // reset progress bar
                        var pl=document.getElementById('ytpPlayed'),sc=document.getElementById('ytpScrubber');
                        var cu=document.getElementById('ytpCurrent'),dr=document.getElementById('ytpDuration');
                        if(pl) pl.style.width='0%'; if(sc) sc.style.left='0%';
                        if(cu) cu.textContent='0:00'; if(dr&&d.duration) dr.textContent=recFmt(d.duration);

                        // update title
                        var ts = document.getElementById('videoTitleText');
                        if (ts) { ts.textContent = d.title; ts.dataset.primaryTitle = d.title; }
                        document.title = d.title + ' | {{ config("app.name") }}';

                        if (pushHist !== false) history.pushState({ url: url }, '', url);

                        recSwapContent(url);
                    } catch(e) {
                        console.warn('recTransitionTo', e);
                        window.location.href = url;
                    } finally {
                        recTransiting = false;
                    }
                }

                async function recSwapContent(url) {
                    try {
                        var resp = await fetch(url, { headers: { 'X-Requested-With': 'XMLHttpRequest' } });
                        if (!resp.ok) return;
                        var html = await resp.text();
                        var parser = new DOMParser();
                        var doc = parser.parseFromString(html, 'text/html');

                        var newVdb = doc.getElementById('vdbWrap');
                        var oldVdb = document.getElementById('vdbWrap');
                        if (newVdb && oldVdb) { oldVdb.innerHTML = newVdb.innerHTML; requestAnimationFrame(function(){ if(window._vdbCheckOverflow)_vdbCheckOverflow(); }); }

                        var newCh = doc.querySelector('.channel-row');
                        var oldCh = document.querySelector('.channel-row');
                        if (newCh && oldCh) oldCh.outerHTML = newCh.outerHTML;

                        var newYtc = doc.getElementById('ytcSection');
                        var oldYtc = document.getElementById('ytcSection');
                        if (newYtc && oldYtc) {
                            oldYtc.innerHTML = newYtc.innerHTML;
                            var s = oldYtc.querySelector('script');
                            if (s) { var ns = document.createElement('script'); ns.textContent = s.textContent; s.replaceWith(ns); }
                        }

                        var newSidebar = doc.querySelector('.yt-sidebar-container');
                        var oldSidebar = document.querySelector('.yt-sidebar-container');
                        if (newSidebar && oldSidebar) {
                            oldSidebar.innerHTML = newSidebar.innerHTML;
                            oldSidebar.querySelectorAll('script').forEach(function(s){
                                var ns = document.createElement('script'); ns.textContent = s.textContent; s.replaceWith(ns);
                            });
                        }
                    } catch(e) { console.warn('recSwapContent', e); }
                }

                // user manually picks a video — reset watch history so next autoplay starts fresh
                window.recGoTo = function(url) {
                    if (!url) return;
                    window._recWatched = new Set();
                    recTransitionTo(url);
                };
                window.recToggleAutoplay = function() {
                    recAutoplay = !recAutoplay;
                    localStorage.setItem('ytpAutoplay_solo', recAutoplay ? '1' : '0');
                    recRender();
                };

                // autoplay: mark current video watched, then play first unwatched rec card
                window._plOnVideoEnd = function() {
                    if (!recAutoplay) return;
                    window._recWatched.add(window.location.href);
                    var next = recNextUnwatched();
                    if (next) {
                        recTransitionTo(next.dataset.recUrl);
                    } else {
                        // all recommendations watched — notify and restart the cycle
                        showToast('All recommendations watched — starting over', 'info');
                        window._recWatched = new Set();
                        var first = document.querySelector('#recList .sidebar-video-card[data-rec-url]');
                        if (first) recTransitionTo(first.dataset.recUrl);
                    }
                };

                window.addEventListener('popstate', function(e) { if (e.state && e.state.url) recTransitionTo(e.state.url, false); });

                if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', recRender); else recRender();
                })();
                </script>

                @if ($recommendedVideos && $recommendedVideos->count() > 0)
                    <div class="recommended-videos-list" id="recList">
                        @foreach ($recommendedVideos as $recVideo)
                            <div class="sidebar-video-card"
                                data-rec-url="{{ route('videos.show', $recVideo) }}"
                                onclick="recGoTo('{{ route('videos.show', $recVideo) }}')"
                                style="cursor:pointer;">
                                <div class="sidebar-thumb" style="position: relative;">
                                    @if ($recVideo->thumbnail)
                                        <img src="{{ route('media.thumbnail', $recVideo->thumbnail) }}"
                                            alt="{{ $recVideo->title }}">
                                    @else
                                        <img src="https://picsum.photos/seed/{{ $recVideo->id }}/320/180"
                                            alt="{{ $recVideo->title }}">
                                    @endif
                                    @if ($recVideo->duration)
                                        <span class="yt-video-duration">{{ gmdate('i:s', $recVideo->duration) }}</span>
                                    @endif
                                    @if ($recVideo->is_shorts)
                                        <span class="yt-shorts-badge"
                                            style="position: absolute; top: 8px; left: 8px; font-size: 10px; padding: 2px 6px;">
                                            <i class="bi bi-collection-play-fill"></i> SHORTS
                                        </span>
                                    @endif
                                </div>
                                <div class="sidebar-info">
                                    <div class="sidebar-title">
                                        @php $recFlag = \App\Data\Languages::flag($recVideo->language); @endphp
                                        <i class="bi {{ match ($recVideo->type) {'music' => 'bi-music-note','match' => 'bi-trophy',default => 'bi-film'} }}"
                                            style="color: #ef4444; margin-right: 4px; font-size: 12px;"></i>
                                        @if($recFlag)<span class="fi fi-{{ $recFlag }}" style="display:inline-block;width:16px;height:12px;border-radius:2px;vertical-align:middle;margin-right:4px;"></span>@endif
                                        {{ Str::limit($recVideo->title, 60) }}
                                    </div>
                                    <div class="sidebar-meta">
                                        <div>{{ $recVideo->user->name ?? 'Unknown' }}</div>
                                        <div>{{ number_format($recVideo->view_count) }} views •
                                            {{ $recVideo->created_at->diffForHumans() }}</div>
                                    </div>
                                </div>
                            </div>
                        @endforeach
                    </div>
                @else
                    <div class="text-secondary" id="recList">No recommendations available yet. Check back later!</div>
                @endif
            @endif
        </div>

    </div>

    @include('layouts.partials.edit-video-modal')

    @if (Session::has('openEditModal') && Session::get('openEditModal'))
        @auth
            <script>
                document.addEventListener('DOMContentLoaded', function() {
                    openEditVideoModal('{{ $video->getRouteKey() }}');
                });
            </script>
        @endauth
    @endif

@endsection
