@extends('frontend.layouts.app')
@php
    $__epTitle   = $anime->title . ' ' . $seasonModel->season_number . '. Sezon ' . $ep->episode_number . '. Bölüm İzle';
    $__epDesc    = $anime->title . ' ' . $seasonModel->season_number . '. sezon ' . $ep->episode_number . '. bölümünü Türkçe altyazılı ve dublajlı ücretsiz izle — Animexe.';
    $__epImgUrl  = $anime->coverUrl ?? url('/logo.jpg');
    $__noindexWp = \App\Models\Setting::get('seo_noindex_watch', '0') === '1';
    $__domain    = rtrim(\App\Models\Setting::get('seo_canonical_domain', config('app.url')), '/');
@endphp
@section('title', $__epTitle . ' - Türkçe | Animexe')
@section('meta_description', $__epDesc)
@section('meta_keywords', $anime->title . ' izle, ' . $anime->title . ' ' . $ep->episode_number . '. bölüm izle, türkçe anime izle, animexe')
@section('robots', $__noindexWp ? 'noindex, nofollow' : 'index, follow')
@section('og_title', $__epTitle . ' - Türkçe | Animexe')
@section('og_description', $__epDesc)
@section('og_image', $__epImgUrl)
@section('schema')
@if(\App\Models\Setting::get('seo_enable_schema','1') === '1')
<script type="application/ld+json">
{
  "@@context":"https://schema.org",
  "@@type":"VideoObject",
  "name":"{{ addslashes($__epTitle) }}",
  "description":"{{ addslashes($__epDesc) }}",
  "thumbnailUrl":"{{ $__epImgUrl }}",
  "uploadDate":"{{ ($ep->created_at ?? now())->toIso8601String() }}",
  "contentUrl":"{{ $__domain }}{{ route('watch', [$anime->slug, $seasonModel->season_number, $ep->episode_number], false) }}",
  "embedUrl":"{{ $__domain }}{{ route('watch', [$anime->slug, $seasonModel->season_number, $ep->episode_number], false) }}",
  "partOfSeries":{"@@type":"TVSeries","name":"{{ addslashes($anime->title) }}","url":"{{ $__domain }}{{ route('anime.show', $anime->slug, false) }}"},
  "partOfSeason":{"@@type":"TVSeason","seasonNumber":{{ $seasonModel->season_number }}},
  "episodeNumber":{{ $ep->episode_number }},
  "inLanguage":"tr",
  "publisher":{"@@type":"Organization","name":"Animexe","logo":{"@@type":"ImageObject","url":"{{ url('/logo.jpg') }}"}}
}
</script>
@endif
@endsection
@push('styles')
{{-- CDN preconnect: HLS segment bağlantıları için önceden bağlan --}}
<link rel="preconnect" href="https://u.aniziumserver.sbs" crossorigin>
<link rel="dns-prefetch" href="https://u.aniziumserver.sbs">
<style>
body{background:var(--bg)}
#pg{padding-top:0}
#topnav{background:rgba(6,6,13,.88) !important;backdrop-filter:blur(16px) !important}

.pw{display:flex;max-width:1400px;margin:0 auto;padding-top:var(--nav-h);min-height:calc(100vh - var(--nav-h))}
.pw-main{flex:1;min-width:0;background:#020208;position:relative}
.pw-side{width:340px;flex-shrink:0;background:linear-gradient(180deg,rgba(10,10,22,.98),rgba(6,6,14,.99));border-left:1px solid rgba(0,245,255,.12);display:flex;flex-direction:column;height:calc(100vh - var(--nav-h));position:sticky;top:var(--nav-h);overflow:hidden;box-shadow:-8px 0 40px rgba(0,0,0,.35)}

/* ── Video wrap ───────────────────────────────────────────────── */
.vw{position:relative;width:100%;aspect-ratio:16/9;background:#000;cursor:pointer;user-select:none;touch-action:manipulation;-webkit-tap-highlight-color:transparent;overflow:hidden}
/* vd-clip: video'yu saran overflow:hidden katmanı — zoom taşmasını keser, menüleri etkilemez */
#vd-clip{position:absolute;inset:0;overflow:hidden}
#vd{width:100%;height:100%;display:block;background:#000;object-fit:contain;transition:transform .25s ease,object-fit 0s}

/* ── Ambiyans Işığı ──────────────────────────────────── */
/* Canvas .vw dışında, .pw-main içinde — videonun arkasında hale efekti verir */
#ambi-canvas{
  position:absolute;top:0;left:0;
  width:100%;aspect-ratio:16/9;
  pointer-events:none;opacity:0;
  transition:opacity .7s ease;
  filter:blur(72px) saturate(3) brightness(.7);
  transform:scale(1.08);transform-origin:top center;
  z-index:0;
}
.pw-main.ambi-on #ambi-canvas{opacity:.9}
/* .vw z-index:15 ile canvas'ın (0) ve eb-tabs'ın (10) üstünde durur; vmenu/backdrop bu stacking context içinde kalsa bile eb-tabs'ı geçer */
.vw{position:relative;z-index:15}

/* Ayarlar (gear) — her zaman görünür; portrait'te label gizlenir */
@media(orientation:portrait){.set-btn-wrap #qlbl{display:none!important}}

/* ── NicoNico yorum girişi (video altında) ───────────────────── */
#nico-input-row{display:flex;gap:8px;align-items:center;padding:6px 12px;background:rgba(0,0,0,.6);border-top:1px solid rgba(255,255,255,.06);flex-shrink:0;transition:opacity .3s,max-height .3s,padding .3s;max-height:52px;overflow:hidden}
#nico-input-row.ctrls-hidden{opacity:0;max-height:0;padding-top:0;padding-bottom:0;border-top:none;pointer-events:none}
#nico-input{flex:1;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.12);border-radius:8px;padding:6px 12px;color:#fff;font-size:.82rem;font-family:inherit;outline:none}
#nico-input::placeholder{color:rgba(255,255,255,.3)}
#nico-color-pick{width:26px;height:26px;border-radius:6px;border:1px solid rgba(255,255,255,.2);cursor:pointer;flex-shrink:0;padding:0}
#nico-send-btn{padding:6px 14px;border-radius:8px;border:none;background:rgba(0,245,255,.15);color:var(--accent2);font-size:.82rem;font-weight:700;font-family:inherit;cursor:pointer;flex-shrink:0;transition:background .15s}
#nico-send-btn:hover{background:rgba(0,245,255,.28)}
/* NicoNico toggle & filter */
#nico-toggle-btn{padding:5px 11px;border-radius:8px;border:1px solid rgba(0,245,255,.2);background:rgba(0,245,255,.05);color:rgba(0,245,255,.45);font-size:.76rem;font-weight:700;cursor:pointer;flex-shrink:0;font-family:inherit;transition:all .15s;white-space:nowrap}
#nico-toggle-btn.on{background:rgba(0,245,255,.14);color:var(--accent2);border-color:rgba(0,245,255,.45)}
.nico-filter-chip{display:flex;align-items:center;gap:4px;padding:5px 10px;border-radius:15px;border:1px solid rgba(255,255,255,.1);background:none;color:rgba(255,255,255,.35);font-size:.72rem;font-weight:700;cursor:pointer;flex-shrink:0;font-family:inherit;transition:all .15s;white-space:nowrap}
.nico-filter-chip.on{border-color:rgba(0,245,255,.4);background:rgba(0,245,255,.1);color:var(--accent2)}
/* Nico kapalıyken input alanlarını gizle — sadece toggle butonu görünür */
#nico-input-row.nico-off #nico-input,#nico-input-row.nico-off #nico-color-pick,#nico-input-row.nico-off #nico-send-btn,#nico-input-row.nico-off .nico-filter-chip{display:none}
/* Overlay rozetleri kontroller ile birlikte gizle */
#firstwatch-badge,#party-fab{transition:opacity .35s,visibility .35s}
.vw.ctrls-off #firstwatch-badge,.vw.ctrls-off #party-fab{opacity:0;visibility:hidden}

/* ── Ruh Hali Motoru ─────────────────────────────────────── */
#mood-overlay{position:absolute;inset:0;z-index:80;background:rgba(5,5,14,.94);backdrop-filter:blur(20px);display:none;align-items:center;justify-content:center;flex-direction:column;padding:24px;text-align:center}
#mood-overlay.on{display:flex}
.mood-title{font-size:1.1rem;font-weight:900;margin-bottom:6px}
.mood-sub{font-size:.8rem;color:rgba(255,255,255,.4);margin-bottom:20px}
.mood-emojis{display:flex;flex-wrap:wrap;gap:10px;justify-content:center;margin-bottom:24px}
.mood-btn{background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.1);border-radius:14px;padding:12px 16px;cursor:pointer;font-size:.88rem;font-family:inherit;color:#fff;transition:all .18s;min-width:100px;display:flex;flex-direction:column;align-items:center;gap:4px}
.mood-btn:hover{background:rgba(255,255,255,.13);border-color:rgba(255,255,255,.3);transform:scale(1.04)}
.mood-btn .me{font-size:1.8rem}
.mood-btn .ml{font-size:.72rem;color:rgba(255,255,255,.5)}
.mood-results{display:none;width:100%;max-width:600px}
.mood-results-title{font-size:.8rem;color:rgba(255,255,255,.4);margin-bottom:12px}
.mood-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.mood-anime-card{background:rgba(255,255,255,.05);border-radius:12px;overflow:hidden;text-decoration:none;transition:transform .15s}
.mood-anime-card:hover{transform:scale(1.03)}
.mood-anime-card img{width:100%;aspect-ratio:2/3;object-fit:cover;display:block}
.mood-anime-card .mac-t{padding:6px 8px;font-size:.72rem;color:#fff;font-weight:700;line-height:1.2}
.mood-close{background:none;border:1px solid rgba(255,255,255,.15);border-radius:10px;padding:8px 20px;color:rgba(255,255,255,.45);font-size:.8rem;cursor:pointer;font-family:inherit;margin-top:16px;transition:all .15s}
.mood-close:hover{color:#fff;border-color:rgba(255,255,255,.4)}

/* ── Spoiler Kutu Paneli (sidebar) ───────────────────────── */
.ps-tabs{display:flex;border-bottom:1px solid rgba(255,255,255,.07);flex-shrink:0}
.ps-tab{flex:1;padding:10px;border:none;background:none;color:rgba(255,255,255,.35);font-size:.75rem;font-weight:700;cursor:pointer;font-family:inherit;border-bottom:2px solid transparent;transition:all .15s}
.ps-tab.on{color:#fff;border-bottom-color:var(--accent2)}
.ps-tab-content{display:none;flex:1;overflow-y:auto;flex-direction:column}
.ps-tab-content.on{display:flex}
#sb-panel{padding:12px;gap:8px}
.sb-item{background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.07);border-radius:10px;padding:12px;position:relative}
.sb-item.is-spoiler{border-color:rgba(255,159,10,.2);background:rgba(255,159,10,.03)}
.sb-spoiler-mask{position:absolute;inset:0;background:rgba(10,8,20,.9);border-radius:10px;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:.78rem;color:rgba(255,159,10,.8);font-weight:700;z-index:2;backdrop-filter:blur(4px)}
.sb-body{font-size:.83rem;line-height:1.5;color:rgba(255,255,255,.82);margin-bottom:8px;word-break:break-word}
.sb-meta{display:flex;align-items:center;gap:8px;font-size:.7rem;color:rgba(255,255,255,.3)}
.sb-like-btn{background:none;border:1px solid rgba(255,255,255,.1);border-radius:20px;padding:2px 10px;color:rgba(255,255,255,.35);cursor:pointer;font-size:.7rem;font-family:inherit;display:inline-flex;align-items:center;gap:4px;transition:all .15s}
.sb-like-btn:hover,.sb-like-btn.on{background:rgba(255,45,125,.1);border-color:rgba(255,45,125,.3);color:#ff2d7d}
.sb-form{padding:10px 12px;border-top:1px solid rgba(255,255,255,.06);flex-shrink:0}
.sb-inp{width:100%;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.1);border-radius:8px;padding:8px 12px;color:#fff;font-size:.82rem;font-family:inherit;resize:none;outline:none;box-sizing:border-box}
.sb-send{width:100%;margin-top:7px;padding:8px;border:none;border-radius:8px;background:rgba(255,45,125,.15);color:#ff2d7d;font-weight:700;font-size:.8rem;cursor:pointer;font-family:inherit;transition:background .15s}
.sb-send:hover{background:rgba(255,45,125,.28)}

/* ── Watch Party Modal ───────────────────────────────────────── */
#party-modal-bg{display:none;position:fixed;inset:0;background:rgba(0,0,0,.75);z-index:9000;align-items:center;justify-content:center}
#party-modal-bg.open{display:flex}
#party-modal{background:#0e0e1a;border:1px solid rgba(255,45,125,.25);border-radius:20px;width:100%;max-width:420px;overflow:hidden}

/* ── Prediction item ─────────────────────────────────────────── */
.pred-item{background:rgba(255,255,255,.04);border:1px solid rgba(255,159,10,.12);border-radius:10px;padding:11px 13px}
.pred-item.correct{border-color:rgba(50,220,100,.4);background:rgba(50,220,100,.06)}
.pred-item.wrong{border-color:rgba(255,80,80,.3);background:rgba(255,80,80,.04);opacity:.6}
.pred-vote-btn{background:none;border:1px solid rgba(255,159,10,.3);border-radius:20px;padding:3px 12px;font-size:.74rem;color:#ff9f0a;cursor:pointer;transition:all .15s}
.pred-vote-btn.voted{background:rgba(255,159,10,.15)}

/* ── Intro overlay ────────────────────────────────────────────── */
#intro-overlay{position:absolute;inset:0;z-index:60;background:#000;display:flex;align-items:center;justify-content:center}
#intro-overlay.hidden{display:none}
#intro-vd{width:100%;height:100%;object-fit:contain;display:block}
#intro-skip{
  position:absolute;bottom:20px;right:16px;
  padding:8px 18px;border-radius:8px;border:1px solid rgba(255,255,255,.3);
  background:rgba(0,0,0,.65);backdrop-filter:blur(10px);
  color:#fff;font-size:.82rem;font-weight:700;cursor:pointer;
  font-family:inherit;transition:background .15s,border-color .15s;
  display:none
}
#intro-skip:hover{background:rgba(255,255,255,.15);border-color:rgba(255,255,255,.6)}
#intro-skip.visible{display:block}
#intro-timer{color:rgba(255,255,255,.5);font-weight:400}

/* Zoom slider */
.zoom-row{padding:8px 12px 4px;display:none}
.zoom-row.on{display:block}
.zoom-slider{-webkit-appearance:none;appearance:none;width:100%;height:3px;border-radius:2px;background:rgba(255,255,255,.18);outline:none;cursor:pointer}
.zoom-slider::-webkit-slider-thumb{-webkit-appearance:none;width:14px;height:14px;border-radius:50%;background:var(--accent2);cursor:pointer;box-shadow:0 0 8px rgba(0,245,255,.5)}
.zoom-slider::-moz-range-thumb{width:14px;height:14px;border-radius:50%;background:var(--accent2);border:none;cursor:pointer}
.zoom-meta{display:flex;justify-content:space-between;font-size:.66rem;color:#444;margin-top:5px}

/* Buffer spinner (mid-play only) */
.vs{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;z-index:6;opacity:0;pointer-events:none;transition:opacity .2s}
.vs.on{opacity:1}
.vsp{width:48px;height:48px;border-radius:50%;border:3px solid rgba(255,255,255,.08);border-top-color:var(--accent2);animation:sp .75s linear infinite;box-shadow:0 0 20px rgba(0,245,255,.12)}
@keyframes sp{to{transform:rotate(360deg)}}
#vs-msg{font-size:.7rem;font-weight:700;color:rgba(255,255,255,.38);letter-spacing:.04em;transition:opacity .3s;display:none}
#vs-msg.on{display:block}

/* ── Loading screen (ilk yükleme + kaynak değişimi) ───────────────────── */
.vload{position:absolute;inset:0;z-index:22;display:flex;flex-direction:column;align-items:center;justify-content:center;background:rgba(4,4,14,.97);transition:opacity .38s ease;opacity:0;pointer-events:none}
.vload.on{opacity:1;pointer-events:auto}
.vload-bg{position:absolute;inset:-24px;background-size:cover;background-position:center;filter:blur(32px) brightness(.16) saturate(1.4);z-index:0;transition:opacity .6s}
.vload-inner{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;gap:20px;padding:0 24px}

/* Orbiting rig */
.vload-rig{position:relative;width:112px;height:112px;flex-shrink:0}
.vload-ring{position:absolute;inset:0;border-radius:50%;border:1.5px solid rgba(0,245,255,.6);animation:vring 2.8s cubic-bezier(.15,.8,.15,1) infinite}
.vload-ring:nth-child(2){inset:20%;border-color:rgba(255,45,125,.45);animation-delay:.7s}
.vload-ring:nth-child(3){inset:38%;border-color:rgba(184,77,255,.4);animation-delay:1.4s}
@keyframes vring{0%{transform:scale(.45);opacity:1}100%{transform:scale(1.9);opacity:0}}
.vload-orb{position:absolute;top:50%;left:50%;border-radius:50%;margin:-4px;animation:vorbit linear infinite}
.vload-orb:nth-child(4){width:8px;height:8px;background:#00f5ff;box-shadow:0 0 10px #00f5ff;--r:46px;animation-duration:2.6s}
.vload-orb:nth-child(5){width:7px;height:7px;background:#ff2d7d;box-shadow:0 0 9px #ff2d7d;--r:37px;animation-duration:2.0s;animation-delay:-.8s}
.vload-orb:nth-child(6){width:6px;height:6px;background:#b84dff;box-shadow:0 0 8px #b84dff;--r:52px;animation-duration:3.3s;animation-delay:-1.5s}
@keyframes vorbit{from{transform:rotate(0deg) translateX(var(--r,44px)) rotate(0deg)}to{transform:rotate(360deg) translateX(var(--r,44px)) rotate(-360deg)}}
.vload-dot{position:absolute;top:50%;left:50%;width:12px;height:12px;border-radius:50%;background:#00f5ff;box-shadow:0 0 18px #00f5ff,0 0 36px rgba(0,245,255,.4);margin:-6px;animation:vdpulse 1.3s ease-in-out infinite}
@keyframes vdpulse{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(1.7);opacity:.65}}

/* Text */
.vload-lbl{font-size:.78rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:rgba(255,255,255,.65)}
.vload-ldots::after{content:'';animation:vdots 1.6s steps(4) infinite}
@keyframes vdots{0%{content:''}25%{content:'.'}50%{content:'..'}75%{content:'...'}100%{content:''}}
.vload-tip{font-size:.72rem;color:rgba(255,255,255,.38);text-align:center;max-width:270px;min-height:34px;line-height:1.55;transition:opacity .35s ease}
.vload-tip.fade{opacity:0}
.vload-playbtn{display:none;align-items:center;gap:10px;margin-top:4px;padding:13px 34px;border-radius:50px;border:none;background:linear-gradient(135deg,#00c8d4,#e0195c);color:#fff;font-size:1rem;font-weight:800;cursor:pointer;font-family:inherit;letter-spacing:.03em;box-shadow:0 0 28px rgba(0,245,255,.3),0 6px 24px rgba(0,0,0,.55);animation:vdpulse 1.6s ease-in-out infinite}
.vload-playbtn.show{display:flex}
.vload-playbtn i{font-size:1.5rem}
.vload-retrybtn{display:none;align-items:center;gap:8px;margin-top:8px;padding:9px 22px;border-radius:50px;border:1px solid rgba(255,255,255,.18);background:rgba(255,255,255,.07);color:rgba(255,255,255,.65);font-size:.82rem;font-weight:600;cursor:pointer;font-family:inherit;transition:background .15s,color .15s}
.vload-retrybtn:hover{background:rgba(255,255,255,.14);color:#fff}
.vload-retrybtn.show{display:flex}

/* Subtitle */
.vsub{
  position:absolute;bottom:24px;left:50%;transform:translateX(-50%);
  text-align:center;pointer-events:none;z-index:25;
  max-width:88%;display:none;flex-direction:column;align-items:center;gap:3px;
  transition:bottom .25s ease;
}
.vsub.on{display:flex}
/* Kontroller açıkken altyazıyı yukarı kaydır — kontrol barının üstünde kalsın */
.vw:not(.ctrls-off) .vsub{bottom:90px}
.vsub-line{
  color:var(--sub-color,#fff);font-size:var(--sub-size,clamp(.88rem,2.2vw,1.2rem));font-weight:600;line-height:1.5;
  white-space:pre-wrap;word-break:break-word;
  background:var(--sub-bg,transparent);padding:var(--sub-pad,0 4px);border-radius:3px;
  text-shadow:var(--sub-shadow,0 0 4px #000,0 1px 6px #000,1px 1px 0 #000,-1px 1px 0 #000,1px -1px 0 #000,-1px -1px 0 #000);
}
.vsub-line.vsub-b{
  color:var(--sub-color-b,rgba(255,255,200,0.92));
}

/* Seek flash — YouTube-style */
.vrf{position:absolute;top:0;bottom:0;width:40%;pointer-events:none;z-index:26;opacity:0;display:flex;align-items:center;justify-content:center;overflow:hidden}
.vrf.L{left:0}.vrf.R{right:0}
.vrf-bg{position:absolute;inset:0;background:rgba(255,255,255,.13);border-radius:0 80% 80% 0/0 50% 50% 0}
.vrf.R .vrf-bg{border-radius:80% 0 0 80%/50% 0 0 50%}
.vrf-inner{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;gap:6px}
.vrf-chevs{display:flex;gap:0;font-size:2rem;color:#fff}
.vrf-chevs i{opacity:0}
.vrf-sec{font-size:.78rem;font-weight:700;color:#fff;text-shadow:0 1px 5px rgba(0,0,0,.7);white-space:nowrap}
@keyframes vrfFade{0%{opacity:0}15%{opacity:1}70%{opacity:1}100%{opacity:0}}
@keyframes vrfBg{0%{transform:scale(.8)}30%{transform:scale(1)}100%{transform:scale(1.06)}}
@keyframes vrfChev{0%,100%{opacity:0}30%,75%{opacity:1}}
.vrf.go{animation:vrfFade .75s ease forwards}
.vrf.go .vrf-bg{animation:vrfBg .75s ease forwards}
.vrf.L.go .vrf-chevs i:nth-child(3){animation:vrfChev .45s .04s ease forwards}
.vrf.L.go .vrf-chevs i:nth-child(2){animation:vrfChev .45s .14s ease forwards}
.vrf.L.go .vrf-chevs i:nth-child(1){animation:vrfChev .45s .24s ease forwards}
.vrf.R.go .vrf-chevs i:nth-child(1){animation:vrfChev .45s .04s ease forwards}
.vrf.R.go .vrf-chevs i:nth-child(2){animation:vrfChev .45s .14s ease forwards}
.vrf.R.go .vrf-chevs i:nth-child(3){animation:vrfChev .45s .24s ease forwards}

/* Next ep card (controls altında kalmasın diye vc altında) */
.vnx{position:absolute;bottom:76px;right:14px;z-index:28;background:rgba(12,12,12,.96);backdrop-filter:blur(14px);border:1px solid #333;border-radius:12px;padding:14px;width:248px;max-width:calc(100% - 28px);display:none;box-shadow:0 12px 40px rgba(0,0,0,.7)}
.vnx.on{display:block}
.vnx-lbl{font-size:.68rem;text-transform:uppercase;letter-spacing:1px;color:#666;margin-bottom:5px}
.vnx-ttl{font-size:.86rem;font-weight:700;color:#f1f1f1;margin-bottom:10px}
.vnx-bar{height:3px;background:rgba(255,255,255,.1);border-radius:2px;overflow:hidden;margin-bottom:10px}
.vnx-fill{height:100%;background:linear-gradient(90deg,var(--accent2),var(--accent));transition:width .5s linear;box-shadow:0 0 12px rgba(0,245,255,.3)}
.vnx-hdr{display:flex;align-items:center;justify-content:space-between;margin-bottom:5px}
.vnx-hdr .vnx-lbl{margin-bottom:0}
.vnx-cancel{background:none;border:none;color:#555;cursor:pointer;padding:2px 4px;border-radius:4px;font-size:1rem;line-height:1;transition:color .15s}
.vnx-cancel:hover{color:#ccc}
.vnx-btn{display:flex;align-items:center;justify-content:center;gap:6px;width:100%;padding:9px;border-radius:7px;border:none;cursor:pointer;background:linear-gradient(135deg,var(--accent),var(--accent3));color:#fff;font-size:.83rem;font-weight:700;text-decoration:none;box-shadow:0 0 24px rgba(255,45,125,.35)}

/* ── Subtitle style chips (settings menu) ───────────────────── */
.sub-sz-btn,.sub-clr-btn,.sub-bg-btn{display:inline-flex;align-items:center;justify-content:center;border:1.5px solid #444;border-radius:6px;background:#1a1a1a;color:#ccc;cursor:pointer;transition:border-color .15s,background .15s,color .15s;line-height:1}
.sub-sz-btn{padding:3px 7px;font-weight:700;font-family:inherit}
.sub-sz-btn:nth-child(1){font-size:.72rem}.sub-sz-btn:nth-child(2){font-size:.88rem}.sub-sz-btn:nth-child(3){font-size:1rem}.sub-sz-btn:nth-child(4){font-size:1.15rem}
.sub-clr-btn{width:22px;height:22px;border-radius:50%;border:2px solid #555}
.sub-bg-btn{padding:2px 8px;font-size:.7rem;font-family:inherit}
.sub-sz-btn.on,.sub-bg-btn.on{border-color:var(--accent2);background:rgba(0,200,212,.15);color:#fff}
.sub-clr-btn.on{box-shadow:0 0 0 2px var(--accent2)}
.sub-row{display:flex;align-items:center;gap:6px;margin-bottom:6px;flex-wrap:wrap}
.sub-row-lbl{font-size:.7rem;color:#888;min-width:48px}

/* ── Controls ─────────────────────────────────────────────────── */
/* Mobilde tüm .vc pointer-events:none iken alt bar tıklanamaz → sadece üst boşluk none */
/* Sadece .vc.on ile görünür — .vw:hover ASLA kullanma (fare üstteyken hideCtrls işe yaramaz; mobil emülatör aynı bug) */
.vc{position:absolute;inset:0;z-index:40;display:flex;flex-direction:column;justify-content:flex-end;opacity:0;transition:opacity .35s cubic-bezier(0.25,0.46,0.45,0.94);pointer-events:none}
.vc.on{opacity:1}
.vc .vp-wrap,.vc .vcb{pointer-events:auto;touch-action:manipulation}
.vc:not(.on) .vp-wrap,.vc:not(.on) .vcb{pointer-events:none;opacity:0;transition:opacity .32s ease}
.vc.on .vp-wrap,.vc.on .vcb{pointer-events:auto;opacity:1}
/* Dar ekran: alt panel animasyonu transform YOK (transform fixed menüyü bozar / kırpar) */
@media(max-width:768px){
  .vc:not(.on) .vp-wrap,.vc:not(.on) .vcb{opacity:0;pointer-events:none}
  .vc.on .vp-wrap,.vc.on .vcb{opacity:1;pointer-events:auto}
}

/* gradient */
.vc::before{content:'';position:absolute;inset:0;background:linear-gradient(to top,rgba(0,0,0,.85) 0%,rgba(0,0,0,.25) 30%,transparent 65%);pointer-events:none}

/* Progress — backdrop üstünde */
.vp-wrap{position:relative;padding:0 12px 6px;z-index:36}
.vp-bar{position:relative;height:3px;background:rgba(255,255,255,.2);border-radius:2px;cursor:pointer;transition:height .12s;margin:10px 0;touch-action:none}
.vp-bar::before{content:'';position:absolute;inset:-10px 0;cursor:pointer;touch-action:none}
.vp-bar:hover,.vp-bar:active{height:5px}
.vp-bar:hover .vp-th,.vp-bar:active .vp-th{opacity:1}
.vp-buf{position:absolute;top:0;left:0;height:100%;background:rgba(255,255,255,.25);border-radius:2px;pointer-events:none}
.vp-fill{position:absolute;top:0;left:0;height:100%;background:linear-gradient(90deg,var(--accent2),var(--accent));border-radius:2px;pointer-events:none;box-shadow:0 0 10px rgba(0,245,255,.25)}
.vp-th{position:absolute;top:50%;right:-6px;width:13px;height:13px;border-radius:50%;background:#fff;transform:translateY(-50%);pointer-events:none;opacity:0;transition:opacity .12s;box-shadow:0 2px 6px rgba(0,0,0,.5)}
.vp-tip{position:absolute;bottom:calc(100% + 14px);background:rgba(6,6,13,.92);border:1px solid rgba(255,255,255,.12);color:#fff;font-size:.7rem;font-weight:700;padding:0;border-radius:8px;transform:translateX(-50%);display:none;white-space:nowrap;pointer-events:none;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,.6)}
.vp-bar:hover .vp-tip,.vp-tip.force-show{display:block}
#vptip-thumb{display:block;width:160px;height:90px;background:#111}
#vptip-time{display:block;text-align:center;padding:4px 6px;font-size:.72rem;font-weight:700;color:#fff}
/* Skip segment marker on progress bar */
.vp-skip-mark{position:absolute;top:0;height:100%;width:3px;background:var(--accent2);border-radius:2px;pointer-events:none;opacity:.85}
/* Skip banner button */
/* Shared skip button style */
#skip-seg-btn,#aniskip-btn{
  position:absolute;right:20px;bottom:80px;
  display:none;align-items:center;gap:7px;
  padding:10px 18px;border-radius:12px;
  background:rgba(8,8,18,.88);backdrop-filter:blur(12px);
  color:#fff;font-size:.88rem;font-weight:700;cursor:pointer;font-family:inherit;
  box-shadow:0 4px 20px rgba(0,0,0,.5);
  transition:opacity .2s,background .15s;z-index:25;
  border:1px solid rgba(0,245,255,.45);
  letter-spacing:.01em;
}
#skip-seg-btn.visible,#aniskip-btn.visible{display:flex}
#skip-seg-btn:hover,#aniskip-btn:hover{background:rgba(0,245,255,.15);border-color:rgba(0,245,255,.8)}

/* Control bar — sol | orta(süre) | sağ(fs dahil) */
.vcb{
  display:flex;align-items:center;justify-content:space-between;
  padding:4px 10px calc(12px + env(safe-area-inset-bottom, 0px));
  gap:4px;
  position:relative;z-index:36;width:100%;box-sizing:border-box;flex-wrap:nowrap;
}
.vcb-l{display:flex;align-items:center;gap:2px;flex:0 0 auto;min-width:0}
.vcb-time{
  flex:1 1 auto;min-width:0;display:flex;align-items:center;justify-content:center;
  padding:0 4px;pointer-events:none;
}
.vcb-r{display:flex;align-items:center;gap:2px;flex:0 0 auto;min-width:0}
/* Masaüstünde dublaj/kaynak ayrı buton; mobilde menü içinde (.dub-in-menu) */
.dub-in-menu{display:none}
@media(max-width:768px){
  .dub-bar,.src-bar{display:none}
  .dub-in-menu{display:block}
  .vvr,.cb.cb-kbhelp{display:none}
}
.vm-sep{height:1px;background:#222;margin:8px 0}
.cb{background:none;border:none;color:rgba(255,255,255,.85);font-size:1.1rem;cursor:pointer;padding:7px 7px;border-radius:6px;line-height:1;display:flex;align-items:center;gap:4px;transition:color .12s,background .12s;white-space:nowrap;flex-shrink:0;font-family:inherit}
.cb:hover{color:#fff;background:rgba(255,255,255,.1)}
.cb.on{color:var(--accent2);text-shadow:0 0 12px rgba(0,245,255,.4)}
.cb .lbl{font-size:.72rem;font-weight:700}
.cb.skbtn{flex-direction:column;align-items:center;padding:5px 6px;font-size:.9rem}
.cb.skbtn small{font-size:.6rem;font-weight:700;line-height:1;margin-top:-1px}

/* Volume */
.vcv{display:flex;align-items:center;gap:4px}
.vvr{-webkit-appearance:none;appearance:none;width:68px;height:3px;border-radius:2px;cursor:pointer;outline:none;background:linear-gradient(90deg,rgba(255,255,255,.82) var(--v,100%),rgba(255,255,255,.18) var(--v,100%))}
.vvr::-webkit-slider-thumb{-webkit-appearance:none;width:12px;height:12px;border-radius:50%;background:#fff;cursor:pointer}

/* Time */
.vtime{font-size:.75rem;font-weight:600;color:rgba(255,255,255,.82);user-select:none;white-space:nowrap;letter-spacing:.02em}

/* Dropdown — açıkken vdrop yükselir (diğer butonların üstüne) */
.vdrop{position:relative;z-index:1}
.vdrop.drop-open{z-index:200}
@supports selector(:has(*)){
  .vdrop:has(.vmenu.on){z-index:200}
}
.vmenu{
  position:absolute;right:0;bottom:calc(100% + 10px);left:auto;
  background:rgba(10,10,22,.97);backdrop-filter:blur(18px);border:1px solid rgba(0,245,255,.2);border-radius:12px;padding:8px;
  min-width:188px;max-width:min(300px,calc(100vw - 20px));max-height:min(52vh,420px);
  overflow-y:auto;-webkit-overflow-scrolling:touch;display:none;z-index:210;
  box-shadow:0 12px 48px rgba(0,0,0,.75),0 0 32px rgba(0,245,255,.08);
}
.vmenu.on{display:block}
/* Telefon: menü viewport’a sabit alt panel */
@media(max-width:768px){
  .vmenu{
    position:fixed !important;
    left:8px !important;right:8px !important;top:auto !important;
    bottom:max(8px, env(safe-area-inset-bottom, 0px)) !important;
    width:auto !important;min-width:0 !important;max-width:none !important;
    max-height:min(72vh, 520px) !important;
    z-index:10002 !important;
    border-radius:18px 18px 14px 14px;
  }
  /* Mobile backdrop — menünün arkasını karartır, tıklayınca kapatır */
  .vm-mobile-backdrop{
    display:none;
    position:fixed;inset:0;
    z-index:10001;
    background:rgba(0,0,0,.55);
    backdrop-filter:blur(2px);
    -webkit-backdrop-filter:blur(2px);
  }
  .vm-mobile-backdrop.on{display:block}
}
/* vc içinde: menülerden düşük, video alanını karartır */
.vm-backdrop{display:none}
.vmt{font-size:.67rem;text-transform:uppercase;letter-spacing:1px;color:#555;font-weight:700;padding:4px 10px 8px}
.vmi{display:flex;align-items:center;gap:8px;padding:8px 12px;border-radius:6px;cursor:pointer;color:rgba(255,255,255,.7);font-size:.83rem;transition:background .12s}
.vmi:hover{background:rgba(255,255,255,.07);color:#fff}
.vmi.on{color:var(--accent2)}
.vmi .dot{width:5px;height:5px;border-radius:50%;flex-shrink:0}
.vmi.on .dot{background:var(--accent2);box-shadow:0 0 8px rgba(0,245,255,.6)}
.vmi:not(.on) .dot{border:1px solid rgba(255,255,255,.2)}

/* ── Player info bar ──────────────────────────────────────────── */
.pinfo{background:linear-gradient(180deg,#0a0a16,#06060d);padding:14px 20px 16px;border-bottom:1px solid rgba(255,255,255,.06)}
.pinfo-row{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:6px}
.pinfo-ep-meta{font-size:.72rem;color:var(--accent2);font-weight:700;margin-bottom:2px;letter-spacing:.3px;text-shadow:0 0 14px rgba(0,245,255,.2)}
.pinfo-ep-title{font-size:1.02rem;font-weight:800;color:#eee;line-height:1.3;margin-bottom:4px}
.pinfo-stats{display:flex;gap:10px;color:#555;font-size:.75rem;flex-wrap:wrap}
.pinfo-stats span{display:flex;align-items:center;gap:3px}
.pnav{display:flex;gap:6px;flex-shrink:0}
.pnav-btn{display:inline-flex;align-items:center;gap:5px;padding:6px 12px;border-radius:7px;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.08);color:#666;font-size:.78rem;font-weight:600;cursor:pointer;text-decoration:none;transition:all .13s;font-family:inherit}
.pnav-btn:hover{background:rgba(0,245,255,.07);color:var(--text);border-color:rgba(0,245,255,.3)}
.pnav-btn.pnav-next{background:rgba(0,245,255,.08);border-color:rgba(0,245,255,.25);color:var(--accent2)}
.pnav-btn.pnav-next:hover{background:rgba(0,245,255,.15)}

/* Sub chips */
.sub-row{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-top:6px}
.sub-row-lbl{font-size:.66rem;text-transform:uppercase;letter-spacing:1px;color:#444;font-weight:700;flex-shrink:0}
.schip{padding:3px 10px;border-radius:10px;font-size:.73rem;font-weight:700;cursor:pointer;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.07);color:#555;transition:all .12s;user-select:none}
.schip:hover{border-color:rgba(0,245,255,.5);color:var(--accent2)}
.schip.on{background:rgba(255,45,125,.12);border-color:var(--accent);color:var(--accent)}

/* ── Sidebar ──────────────────────────────────────────────────── */
.ps-hdr{padding:13px 13px 0;flex-shrink:0;border-bottom:1px solid #1e1e1e}
.ps-hdr h3{font-size:.72rem;text-transform:uppercase;letter-spacing:1px;color:#444;font-weight:700;margin-bottom:10px}
.ps-stabs{display:flex;gap:5px;flex-wrap:wrap;padding-bottom:11px}
.pst{padding:3px 10px;border-radius:10px;font-size:.72rem;font-weight:700;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.07);color:#444;cursor:pointer;transition:all .13s;font-family:inherit}
.pst:hover{color:#aaa}
.pst.on{background:rgba(0,245,255,.1);border-color:rgba(0,245,255,.35);color:var(--accent2)}
.ps-list{flex:1;overflow-y:auto;padding:6px}
.ps-list::-webkit-scrollbar{width:3px}
.ps-list::-webkit-scrollbar-thumb{background:#222;border-radius:2px}
.ps-item{display:flex;gap:8px;align-items:center;padding:7px 7px;border-radius:8px;cursor:pointer;text-decoration:none;color:inherit;border:1px solid transparent;margin-bottom:3px;transition:background .12s}
.ps-item:hover{background:rgba(255,255,255,.04)}
.ps-item.now{background:rgba(0,245,255,.08);border-color:rgba(0,245,255,.22)}
.ps-item.ps-watched .ps-name{color:rgba(255,255,255,.35)}
.ps-thumb{width:84px;flex-shrink:0;border-radius:5px;overflow:hidden;background:#1a1a1a;position:relative}
.ps-thumb img{width:100%;aspect-ratio:16/9;object-fit:cover;display:block}
.ps-thumb .nth{aspect-ratio:16/9;display:flex;align-items:center;justify-content:center;color:#2a2a2a}
.ps-thumb .nowmark{position:absolute;inset:0;background:rgba(0,245,255,.15);display:flex;align-items:center;justify-content:center;color:var(--accent2);font-size:1rem}
/* Progress bar on thumbnail */
.ps-prog{position:absolute;bottom:0;left:0;height:3px;width:var(--p,0%);background:linear-gradient(90deg,var(--accent2),var(--accent));border-radius:0 2px 2px 0}
.ps-info{flex:1;min-width:0}
.ps-num{font-size:.66rem;color:#444;font-weight:700;margin-bottom:2px}
.ps-name{font-size:.78rem;font-weight:600;color:rgba(255,255,255,.65);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;line-height:1.35}
.ps-item.now .ps-name{color:var(--accent2)}
.ps-pct{font-size:.6rem;color:var(--accent2);opacity:.7;margin-top:2px;font-weight:700}

@media(max-width:1100px){
  .pw{flex-direction:column}
  .pw-side{width:100%;height:auto;max-height:400px;position:static;border-left:none;border-top:1px solid #1e1e1e;order:2}
  .pw-main{order:1}
  .vvr{display:none}
  .ep-below{padding:0 14px 36px}
}
@media(max-width:600px){
  .vsub{bottom:16px}
  .vw:not(.ctrls-off) .vsub{bottom:76px}
  .vsub-line{font-size:.88rem}
  .pinfo{padding:10px 14px 14px}
  .pinfo-row{flex-wrap:nowrap;align-items:center;gap:8px}
  .pinfo-row>div:first-child{min-width:0;flex:1;overflow:hidden}
  .pinfo-ep-title{font-size:.85rem;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden;margin-bottom:2px}
  .pinfo-ep-meta{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:.68rem}
  .pinfo-stats{flex-wrap:nowrap;overflow:hidden;gap:8px}
  .pinfo-stats span:nth-child(n+3){display:none}
  .pnav{gap:4px;flex-shrink:0}
  .pnav-btn{padding:5px 8px;font-size:.72rem;gap:3px}
  .eb-info,.eb-cmt{padding-left:14px;padding-right:14px}
  .vcb{padding:4px 6px 10px;gap:4px}
  .vcb-l{gap:0}
  .vcb-time{padding:0 4px}
  .vcb-r{gap:0}
  /* 44px minimum touch target (iOS/Android HIG) */
  .cb{min-width:44px;min-height:44px;padding:6px 6px;font-size:.95rem;justify-content:center}
  .cb:active{background:rgba(255,255,255,.15)}
  .cb.skbtn{padding:4px 4px;min-width:44px}
  .cb .lbl{max-width:64px;overflow:hidden;text-overflow:ellipsis;font-size:.65rem}
  .vtime{font-size:.68rem}
  /* Bigger progress bar touch area on mobile */
  .vp-bar::before{inset:-14px 0}
  /* Skip buttons: lower position so they don't crowd the control bar */
  #skip-seg-btn,#aniskip-btn{bottom:calc(62px + env(safe-area-inset-bottom, 0px));right:12px;padding:8px 14px;font-size:.82rem;gap:5px}
  /* Sidebar: cap height on small phones */
  .pw-side{max-height:260px}
}
@media(max-width:480px){
  /* NicoNico row: hide filter chip (too cramped), allow wrap, ease padding */
  #nico-input-row{max-height:none;flex-wrap:wrap;gap:5px;padding:5px 8px}
  #nico-input-row .nico-filter-chip{display:none!important}
  #nico-color-pick{width:22px;height:22px;border-radius:5px}
  #nico-send-btn{padding:5px 10px;font-size:.78rem}
  #nico-toggle-btn{font-size:.72rem;padding:4px 9px}
  /* Mood buttons: smaller on narrow screens */
  .mood-btn{min-width:88px;padding:10px 12px}
  .mood-title{font-size:1rem}
}
@media(max-width:520px){
  /* Seek butonlarını gizle — double-tap zaten var, fullscreen görünsün */
  .skbtn{display:none !important}
}
@media(max-width:380px){
  /* Very narrow: mood results 2-col grid */
  .mood-grid{grid-template-columns:repeat(2,1fr)}
  .mood-emojis{gap:7px}
  .mood-btn{min-width:0;flex:1 1 calc(50% - 7px);max-width:none}
}

/* ── Episode below ──────────────────────────────────────────────── */
.ep-below{padding:0;max-width:100%}

/* Tabs */
.eb-tabs{display:flex;gap:0;border-bottom:1px solid rgba(255,255,255,.07);background:#06060d;padding:0 12px;position:sticky;top:var(--nav-h);z-index:10;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.eb-tabs::-webkit-scrollbar{display:none}
.eb-tab{padding:12px 14px;font-size:.82rem;font-weight:700;color:#555;cursor:pointer;border:none;background:none;font-family:inherit;border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .15s,border-color .15s;display:flex;align-items:center;gap:6px;white-space:nowrap;flex-shrink:0}
.eb-tab:hover{color:#aaa}
.eb-tab.on{color:var(--accent2);border-bottom-color:var(--accent2)}
.eb-tab .tab-badge{background:rgba(0,245,255,.15);color:var(--accent2);font-size:.65rem;padding:2px 6px;border-radius:8px;font-weight:800}

/* Tab panels */
.eb-panel{display:none;animation:fadeIn .2s ease}
.eb-panel.on{display:block}
@keyframes fadeIn{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
@keyframes unmute-pulse{0%,100%{box-shadow:0 4px 24px rgba(255,45,125,.3)}50%{box-shadow:0 4px 32px rgba(255,45,125,.7),0 0 0 4px rgba(255,45,125,.2)}}

/* Info panel */
.eb-info{padding:24px 20px 40px;max-width:900px;margin:0 auto}
@media(max-width:1100px){.eb-info{max-width:100%}}

/* Anime card */
.ep-card{display:flex;gap:20px;background:linear-gradient(135deg,rgba(0,245,255,.04) 0%,rgba(255,45,125,.025) 100%);border:1px solid rgba(255,255,255,.07);border-radius:14px;padding:20px;margin-bottom:24px;position:relative;overflow:hidden}
.ep-card::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse at top left,rgba(0,245,255,.06),transparent 60%);pointer-events:none}
.ep-card-poster{width:100px;flex-shrink:0;border-radius:9px;overflow:hidden;box-shadow:0 8px 28px rgba(0,0,0,.5);align-self:flex-start}
.ep-card-poster img{width:100%;display:block;aspect-ratio:2/3;object-fit:cover}
.ep-card-body{flex:1;min-width:0}
.ep-card-anime-title{font-size:.72rem;text-transform:uppercase;letter-spacing:.12em;color:var(--accent2);font-weight:700;margin-bottom:5px;text-shadow:0 0 14px rgba(0,245,255,.2)}
.ep-card-anime-title a{color:inherit;text-decoration:none}
.ep-card-anime-title a:hover{text-decoration:underline}
.ep-card-ep-title{font-size:1.05rem;font-weight:800;color:#f0f0f0;line-height:1.3;margin-bottom:10px}
.ep-card-stats{display:flex;gap:14px;flex-wrap:wrap;margin-bottom:12px}
.ep-stat{display:flex;align-items:center;gap:5px;font-size:.75rem;color:#666;font-weight:600}
.ep-stat i{font-size:.82rem}
.ep-stat.stat-views{color:#888}
.ep-stat.stat-dur{color:#666}
.ep-stat.stat-dub{color:rgba(0,245,255,.6);background:rgba(0,245,255,.08);border:1px solid rgba(0,245,255,.15);border-radius:6px;padding:2px 8px}
.ep-stat.stat-rating{color:#ffd60a}

/* Description */
.ep-desc-wrap{margin-bottom:16px}
.ep-desc-lbl{font-size:.68rem;text-transform:uppercase;letter-spacing:.1em;color:#444;font-weight:700;margin-bottom:8px}
.ep-desc-text{color:#888;font-size:.88rem;line-height:1.75;margin:0;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:4}
.ep-desc-text.expanded{-webkit-line-clamp:unset;display:block}
.ep-expand-btn{background:none;border:none;color:var(--accent2);font-size:.78rem;font-weight:700;cursor:pointer;padding:5px 0;font-family:inherit;margin-top:4px}
.ep-expand-btn:hover{text-decoration:underline}

/* Genre / tag chips */
.ep-tags{display:flex;gap:6px;flex-wrap:wrap;margin-top:4px}
.ep-tag{padding:3px 10px;border-radius:10px;font-size:.72rem;font-weight:700;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.08);color:#666;text-decoration:none;transition:all .12s}
.ep-tag:hover{border-color:rgba(255,45,125,.5);color:var(--accent)}

/* Anime meta row */
.ep-meta-row{display:flex;gap:20px;flex-wrap:wrap;padding-top:16px;border-top:1px solid rgba(255,255,255,.05);margin-top:4px}
.ep-meta-item{display:flex;flex-direction:column;gap:2px}
.ep-meta-key{font-size:.62rem;text-transform:uppercase;letter-spacing:.1em;color:#3a3a5a;font-weight:700}
.ep-meta-val{font-size:.8rem;font-weight:600;color:#777}

@media(max-width:600px){
  .ep-card{gap:14px;padding:14px}
  .ep-card-poster{width:72px}
  .ep-card-ep-title{font-size:.92rem}
}
@media(max-width:400px){
  .ep-card-poster{display:none}
}

/* ── Comments panel ──────────────────────────────────────── */
.eb-cmt{padding:20px 20px 48px;max-width:900px;margin:0 auto}
@media(max-width:1100px){.eb-cmt{max-width:100%}}

/* ── Watermark cover ─────────────────────────────────── */
#wm-cover{
  position:absolute;
  top:0;left:50%;transform:translateX(-50%);
  width:clamp(160px,28%,280px);
  height:clamp(32px,8%,54px);
  background:rgba(0,0,0,.92);
  backdrop-filter:blur(10px);
  border-radius:0 0 12px 12px;
  z-index:30;
  pointer-events:none;
  transition:opacity .6s ease;
  display:flex;align-items:center;justify-content:center;
}
#wm-cover.hide{opacity:0}
#wm-cover span{
  font-family:var(--font-display,'Orbitron',sans-serif);
  font-size:clamp(.6rem,1.6vw,.8rem);
  font-weight:800;letter-spacing:.18em;
  background:linear-gradient(105deg,#fff,var(--accent2,#00f5ff),var(--accent,#ff2d7d));
  -webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;
  text-shadow:none;opacity:.95;
}
/* Dikey (portrait) tam ekran — vw çok küçük olur, vmin kullan */
@media(orientation:portrait){
  #wm-cover{
    width:clamp(180px,52%,280px);
    height:clamp(34px,12%,52px);
  }
  #wm-cover span{font-size:clamp(.68rem,3vmin,.82rem)}
}
/* Fullscreen safe-area (notch) desteği */
#vw:fullscreen #wm-cover,
#vw:-webkit-full-screen #wm-cover{
  top:env(safe-area-inset-top,0px);
  width:clamp(180px,38%,300px);
  height:clamp(34px,7%,56px);
}
#vw:fullscreen #wm-cover span,
#vw:-webkit-full-screen #wm-cover span{
  font-size:clamp(.7rem,2.2vmin,.85rem);
}
@media(orientation:portrait){
  #vw:fullscreen #wm-cover,
  #vw:-webkit-full-screen #wm-cover{
    width:clamp(180px,55%,300px);
    height:clamp(36px,14%,56px);
  }
  #vw:fullscreen #wm-cover span,
  #vw:-webkit-full-screen #wm-cover span{
    font-size:clamp(.7rem,3.5vmin,.85rem);
  }
}

/* ── iOS fake fullscreen ────────────────────────────── */
#vw.ios-fullscreen{
  position:fixed!important;top:0;left:0;
  width:100vw!important;height:100dvh!important;
  z-index:99999;background:#000;
}
body.ios-fs-active{overflow:hidden!important;touch-action:none}

/* ── Comments ────────────────────────────────────────── */
.cmt-section{margin-top:8px}
.cmt-hdr{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px}
.cmt-title{font-size:.95rem;font-weight:800;color:var(--text);display:flex;align-items:center;gap:8px}
.cmt-count{font-size:.78rem;color:var(--text3)}

/* Form */
.cmt-form-wrap{display:flex;gap:12px;margin-bottom:20px}
.cmt-form-avatar{
  width:36px;height:36px;border-radius:50%;flex-shrink:0;
  background:linear-gradient(135deg,var(--accent2),var(--accent));
  display:flex;align-items:center;justify-content:center;
  font-size:.82rem;font-weight:800;color:#06060d;overflow:hidden;
}
.cmt-form-body{flex:1;min-width:0}
.cmt-input{
  width:100%;background:rgba(17,17,31,.9);border:1px solid var(--border);
  border-radius:var(--r);padding:11px 14px;color:var(--text);font-size:.88rem;
  resize:none;outline:none;font-family:inherit;min-height:44px;max-height:180px;
  transition:border-color .18s,box-shadow .18s;line-height:1.5;
}
.cmt-input:focus{border-color:var(--accent2);box-shadow:0 0 0 2px rgba(0,245,255,.15)}
.cmt-form-actions{display:flex;align-items:center;justify-content:space-between;margin-top:8px}
.cmt-gif-btn{
  background:rgba(17,17,31,.8);border:1px solid var(--border);color:var(--text2);
  padding:7px 14px;border-radius:var(--r);font-size:.8rem;font-weight:700;cursor:pointer;
  font-family:inherit;transition:all .15s;display:flex;align-items:center;gap:5px;
}
.cmt-gif-btn:hover{border-color:var(--accent2);color:var(--accent2)}
.cmt-submit-btn{
  background:linear-gradient(135deg,var(--accent),var(--accent3));
  border:none;color:#fff;padding:8px 20px;border-radius:var(--r);
  font-size:.82rem;font-weight:700;cursor:pointer;font-family:inherit;
  display:flex;align-items:center;gap:6px;transition:transform .15s,box-shadow .15s;
  box-shadow:0 0 20px rgba(255,45,125,.25);
}
.cmt-submit-btn:hover{transform:translateY(-1px);box-shadow:0 0 28px rgba(255,45,125,.4)}
.cmt-submit-btn:disabled{opacity:.5;pointer-events:none}

/* GIF Picker */
.gif-picker{
  background:rgba(10,10,22,.98);border:1px solid var(--border);
  border-radius:var(--r2);padding:14px;margin-bottom:18px;
  box-shadow:0 12px 48px rgba(0,0,0,.55);
}
.gif-search-wrap{position:relative;margin-bottom:12px}
.gif-search-input{
  width:100%;background:rgba(17,17,31,.9);border:1px solid var(--border);
  border-radius:var(--r);padding:10px 14px 10px 36px;color:var(--text);font-size:.86rem;outline:none;font-family:inherit;
}
.gif-search-input:focus{border-color:var(--accent2)}
.gif-results{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:6px;
  max-height:260px;overflow-y:auto;
}
.gif-results img{width:100%;aspect-ratio:1;object-fit:cover;border-radius:6px;cursor:pointer;transition:opacity .15s}
.gif-results img:hover{opacity:.8}
.gif-loading{grid-column:1/-1;text-align:center;color:var(--text3);font-size:.84rem;padding:20px}

/* Comment items */
.cmt-item{
  display:flex;gap:13px;align-items:flex-start;
  margin-bottom:10px;padding:11px 14px;
  border-radius:13px;
  background:rgba(255,255,255,.018);
  border:1px solid rgba(255,255,255,.05);
  transition:background .15s,border-color .15s;
}
.cmt-item:hover{background:rgba(255,255,255,.03);border-color:rgba(255,255,255,.09)}

/* Avatar — no-frame variant (direct flex child) */
.cmt-ava{
  width:40px;height:40px;border-radius:50%;flex-shrink:0;
  background:linear-gradient(135deg,rgba(0,245,255,.55),rgba(255,45,125,.55));
  display:flex;align-items:center;justify-content:center;
  font-size:.84rem;font-weight:800;color:#fff;overflow:hidden;
}
.cmt-ava.admin{background:linear-gradient(135deg,var(--accent),var(--accent3))}

/* Avatar frame wrapper — frame variant */
.cmt-ava-wrap{
  position:relative;flex-shrink:0;
  width:46px;height:46px;align-self:flex-start;
}
.cmt-ava-wrap::before{
  content:'';position:absolute;inset:0;
  border-radius:50%;
  animation:frame-spin 4s linear infinite;
  pointer-events:none;
}
/* Avatar inside wrapper sits at inset:3px, covering ring center */
.cmt-ava-wrap .cmt-ava{
  position:absolute;inset:3px;
  width:auto;height:auto;flex-shrink:initial;
}
/* Per-frame ring colors */
.cmt-ava-wrap.fr-neon::before   {background:conic-gradient(#00f5ff,#b84dff,#00f5ff);box-shadow:0 0 8px rgba(0,245,255,.45)}
.cmt-ava-wrap.fr-fire::before   {background:conic-gradient(#ff6b35,#ff2d7d,#ff8c00,#ff6b35);box-shadow:0 0 8px rgba(255,107,53,.45)}
.cmt-ava-wrap.fr-galaxy::before {background:conic-gradient(#7c3aed,#b84dff,#4a1d96,#7c3aed);box-shadow:0 0 8px rgba(124,58,237,.45)}
.cmt-ava-wrap.fr-gold::before   {background:conic-gradient(#ffd700,#ff8c00,#ffd700);box-shadow:0 0 10px rgba(255,215,0,.4)}
.cmt-ava-wrap.fr-sakura::before {background:conic-gradient(#ff9ec4,#ff2d7d,#ffd6e7,#ff9ec4);box-shadow:0 0 8px rgba(255,158,196,.4)}
.cmt-ava-wrap.fr-rainbow::before{background:conic-gradient(#ff0000,#ff8c00,#ffd700,#00c800,#0088ff,#8b00ff,#ff0080,#ff0000)}
.cmt-ava-wrap.fr-ice::before    {background:conic-gradient(#a8edff,#60cfff,#a8edff);box-shadow:0 0 8px rgba(168,237,255,.4)}
.cmt-ava-wrap.fr-blood::before  {background:conic-gradient(#8b0000,#dc143c,#8b0000);box-shadow:0 0 8px rgba(220,20,60,.4)}
.cmt-ava-wrap.fr-mint::before   {background:conic-gradient(#00ff7f,#00d4a4,#00ff7f);box-shadow:0 0 8px rgba(0,255,127,.35)}
.cmt-ava-wrap.fr-ocean::before  {background:conic-gradient(#006fbf,#00d2ff,#006fbf);box-shadow:0 0 8px rgba(0,210,255,.4)}
.cmt-ava-wrap.fr-poison::before {background:conic-gradient(#6b0ac9,#c300ff,#6b0ac9);box-shadow:0 0 8px rgba(195,0,255,.4)}
.cmt-body{flex:1;min-width:0}
.cmt-meta{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:5px}
.cmt-name{font-size:.84rem;font-weight:700;color:var(--text);text-decoration:none}
.cmt-name:not([class*="username-color-"]):hover{color:#fff}
.cmt-badge{font-size:.6rem;padding:2px 7px;border-radius:10px;font-weight:800;letter-spacing:.06em}
.cmt-badge-admin{background:rgba(255,45,125,.2);color:var(--accent);border:1px solid rgba(255,45,125,.3)}
.cmt-badge-pinned{background:rgba(0,245,255,.1);color:var(--accent2);border:1px solid rgba(0,245,255,.25)}
.cmt-badge-staff{background:rgba(255,191,0,.15);color:#ffbf00;border:1px solid rgba(255,191,0,.3)}
.cmt-time{font-size:.72rem;color:var(--text3)}
.cmt-text{font-size:.88rem;color:var(--text2);line-height:1.6;word-break:break-word;white-space:pre-wrap}
.cmt-gif{max-width:240px;border-radius:8px;margin-top:8px;display:block}
.cmt-actions{display:flex;align-items:center;gap:14px;margin-top:8px}
.cmt-action-btn{
  background:none;border:none;cursor:pointer;color:var(--text3);font-size:.76rem;font-weight:700;
  font-family:inherit;display:flex;align-items:center;gap:4px;padding:4px 0;transition:color .14s;
}
.cmt-action-btn:hover{color:var(--text)}
.cmt-action-btn.liked{color:var(--accent);text-shadow:0 0 12px rgba(255,45,125,.4)}
.cmt-follow-btn{
  background:none;border:1px solid rgba(0,245,255,.25);cursor:pointer;
  color:rgba(0,245,255,.6);font-size:.68rem;font-weight:700;font-family:inherit;
  padding:2px 7px;border-radius:20px;transition:all .15s;
  display:inline-flex;align-items:center;gap:3px;
}
.cmt-follow-btn:hover{background:rgba(0,245,255,.12);color:var(--accent2);border-color:var(--accent2)}
.cmt-follow-btn.following{border-color:rgba(255,255,255,.15);color:rgba(255,255,255,.35)}
.cmt-follow-btn.following:hover{border-color:rgba(255,80,80,.4);color:#ff6b6b;background:rgba(255,80,80,.08)}
.cmt-mention{color:var(--accent2);font-weight:700;text-decoration:none}
.cmt-mention:hover{text-decoration:underline}
.cmt-action-btn.liked i{filter:drop-shadow(0 0 6px rgba(255,45,125,.5))}

/* Replies */
.cmt-replies{margin-top:10px;margin-left:4px;padding-left:16px;border-left:2px solid rgba(0,245,255,.12)}
.cmt-replies .cmt-item{padding:8px 12px;margin-bottom:6px;border-radius:10px}
.cmt-replies .cmt-ava{width:30px;height:30px;font-size:.72rem}
.cmt-replies .cmt-ava-wrap{width:36px;height:36px}
.cmt-replies .cmt-name{font-size:.8rem}
.reply-form-wrap{display:flex;gap:10px;margin-top:12px}
.reply-input{
  flex:1;background:rgba(17,17,31,.9);border:1px solid var(--border);
  border-radius:var(--r);padding:9px 13px;color:var(--text);font-size:.84rem;
  outline:none;font-family:inherit;min-height:38px;resize:none;
}
.reply-input:focus{border-color:var(--accent2)}
.reply-submit-btn{
  background:var(--accent);border:none;color:#fff;
  padding:9px 16px;border-radius:var(--r);font-size:.8rem;font-weight:700;cursor:pointer;font-family:inherit;white-space:nowrap;
}

.cmt-login-prompt{
  text-align:center;padding:28px 20px;color:var(--text3);font-size:.88rem;
  background:rgba(17,17,31,.5);border:1px solid var(--border);border-radius:var(--r2);margin-bottom:20px;
}
.cmt-empty{text-align:center;padding:32px 20px;color:var(--text3);font-size:.88rem}
.cmt-load-btn{
  background:rgba(17,17,31,.8);border:1px solid var(--border);color:var(--text2);
  padding:10px 24px;border-radius:var(--r);font-size:.84rem;font-weight:700;cursor:pointer;font-family:inherit;transition:all .15s;
}
.cmt-load-btn:hover{border-color:var(--accent2);color:var(--accent2)}

/* ═══════════════════════════════════════════════════
   PLAYER PAGE PREMIUM ENHANCEMENTS
   ═══════════════════════════════════════════════════ */

/* Video progress bar glow */
.vp-fill{
  box-shadow:0 0 14px rgba(0,245,255,.45),0 0 28px rgba(255,45,125,.2);
  transition:width .1s linear;
}

/* Video thumb enhanced */
.vp-th{
  width:16px;height:16px;
  background:linear-gradient(135deg,#fff,rgba(0,245,255,.9));
  box-shadow:0 0 12px rgba(0,245,255,.7),0 2px 8px rgba(0,0,0,.6);
}

/* Control buttons enhanced */
.cb:hover{
  color:#fff;background:rgba(0,245,255,.1);
  box-shadow:0 0 16px rgba(0,245,255,.1);
}

/* Video controls gradient stronger */
.vc::before{
  background:linear-gradient(to top,rgba(0,0,0,.9) 0%,rgba(0,0,0,.3) 40%,transparent 70%);
}

/* Current episode sidebar highlight */
.ps-item.now{
  background:linear-gradient(135deg,rgba(0,245,255,.1),rgba(255,45,125,.05));
  border-color:rgba(0,245,255,.3);
  box-shadow:inset 0 0 0 1px rgba(0,245,255,.15);
}
.ps-item.now .ps-name{
  color:var(--accent2);
  text-shadow:0 0 12px rgba(0,245,255,.3);
}

/* Episode sidebar item hover */
.ps-item:hover{
  background:rgba(0,245,255,.06);
  border-color:rgba(0,245,255,.12);
}

/* Pinfo bar enhanced */
.pinfo{
  background:linear-gradient(180deg,rgba(10,10,22,.98),rgba(6,6,13,.99));
  border-bottom:1px solid rgba(0,245,255,.08);
}
.pinfo-ep-meta{
  background:linear-gradient(90deg,var(--accent2),var(--accent));
  -webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;
  font-size:.75rem;font-weight:800;
}
.pinfo-ep-title{
  font-size:1.05rem;font-weight:800;
  color:#f0f4ff;
}

/* Next episode card enhanced */
.vnx{
  background:rgba(8,8,20,.97);
  border:1px solid rgba(0,245,255,.2);
  box-shadow:0 12px 48px rgba(0,0,0,.75),0 0 30px rgba(0,245,255,.06);
}
.vnx-btn{
  box-shadow:0 0 28px rgba(255,45,125,.4),0 4px 16px rgba(0,0,0,.4);
  transition:transform .15s,box-shadow .18s;
}
.vnx-btn:hover{transform:translateY(-2px);box-shadow:0 0 40px rgba(255,45,125,.55)}
.vnx-fill{background:linear-gradient(90deg,var(--accent2),var(--accent));box-shadow:0 0 14px rgba(0,245,255,.35)}

/* Skip button enhanced */
#skip-seg-btn,#aniskip-btn{
  border:1px solid rgba(0,245,255,.5);
  box-shadow:0 0 20px rgba(0,245,255,.15),0 4px 20px rgba(0,0,0,.4);
  backdrop-filter:blur(14px);
}

/* Comment section enhanced */
.cmt-input:focus{
  border-color:var(--accent2);
  box-shadow:0 0 0 2px rgba(0,245,255,.12),0 0 20px rgba(0,245,255,.06);
}


/* Episode tabs enhanced */
.eb-tab.on{
  color:var(--accent2);
  text-shadow:0 0 12px rgba(0,245,255,.3);
}

/* Below player ep card enhanced */
.ep-card{
  transition:border-color .2s,box-shadow .2s;
}
.ep-card:hover{
  border-color:rgba(0,245,255,.18);
  box-shadow:0 8px 32px rgba(0,0,0,.4),0 0 30px rgba(0,245,255,.05);
}

/* Anime info card in player enhanced */
.ec-poster{box-shadow:0 8px 32px rgba(0,0,0,.6),0 0 40px rgba(0,245,255,.06)}

/* Spinner enhanced */
.vsp{
  border:3px solid rgba(255,255,255,.08);
  border-top-color:var(--accent2);
  box-shadow:0 0 24px rgba(0,245,255,.35),inset 0 0 12px rgba(0,245,255,.05);
}

/* Volume slider enhanced */
.vvr::-webkit-slider-thumb{
  box-shadow:0 0 8px rgba(255,255,255,.4);
}

/* Watch party FAB enhanced */
#party-fab{
  box-shadow:0 0 28px rgba(255,45,125,.4),0 4px 20px rgba(0,0,0,.4);
}

/* Mobile: video aspect ratio preserved */
@media(max-width:600px){
  .pw-main{background:#000}
  .pinfo-ep-title{font-size:.9rem}
}

/* NicoNico input enhanced */
#nico-input:focus{
  border-color:rgba(0,245,255,.4);
  box-shadow:0 0 0 2px rgba(0,245,255,.1);
  background:rgba(255,255,255,.1);
}

/* ── Kaynak Seçici Tab Bar ──────────────────────────────────────────── */
.src-tab-bar{
  background:linear-gradient(180deg,#09090f 0%,#0b0b18 100%);
  border-bottom:1px solid rgba(255,255,255,.05);
  padding:10px 16px 12px;
}
.src-tab-hdr{
  display:flex;align-items:center;gap:5px;
  color:rgba(255,255,255,.28);font-size:.62rem;font-weight:700;
  text-transform:uppercase;letter-spacing:1.1px;margin-bottom:8px;
}
.src-tab-scroll{
  display:flex;gap:7px;overflow-x:auto;
  scrollbar-width:none;-webkit-overflow-scrolling:touch;
  padding-bottom:2px;
}
.src-tab-scroll::-webkit-scrollbar{display:none}
.src-tab{
  display:inline-flex;align-items:center;gap:6px;
  padding:7px 15px;border-radius:30px;flex-shrink:0;
  border:1px solid rgba(255,255,255,.1);
  background:rgba(255,255,255,.04);
  color:rgba(255,255,255,.5);
  font-size:.8rem;font-weight:600;cursor:pointer;
  white-space:nowrap;font-family:inherit;
  transition:background .15s,border-color .15s,color .15s,box-shadow .15s;
}
.src-tab i{font-size:.85rem;opacity:.75;flex-shrink:0}
.src-tab:hover{
  background:rgba(0,245,255,.07);
  border-color:rgba(0,245,255,.22);
  color:rgba(255,255,255,.85);
}
.src-tab.on{
  background:rgba(0,245,255,.12);
  border-color:rgba(0,245,255,.38);
  color:var(--accent2,#00f5ff);
  box-shadow:0 0 18px rgba(0,245,255,.14),inset 0 1px 0 rgba(0,245,255,.18);
}
.src-tab.on i{opacity:1}
/* 4K (Anizium) kaynak — altın sarısı badge */
.src-tab-4k{
  background:linear-gradient(135deg,rgba(255,214,10,.13),rgba(255,180,0,.07));
  border-color:rgba(255,214,10,.45);
  color:rgba(255,214,10,.9);
}
.src-tab-4k i{color:#ffd60a;opacity:1}
.src-tab-4k:hover{
  background:linear-gradient(135deg,rgba(255,214,10,.22),rgba(255,180,0,.13));
  border-color:rgba(255,214,10,.65);
  color:#ffd60a;
}
.src-tab-4k.on{
  background:linear-gradient(135deg,rgba(255,214,10,.28),rgba(255,180,0,.18));
  border-color:#ffd60a;
  color:#ffd60a;
  box-shadow:0 0 18px rgba(255,214,10,.22),inset 0 1px 0 rgba(255,214,10,.25);
}
/* Dropdown menüdeki featured satır */
.vmi-featured{
  background:linear-gradient(90deg,rgba(255,214,10,.08),transparent);
  border-left:2px solid rgba(255,214,10,.6);
  padding-left:10px;
  color:rgba(255,214,10,.9);
}
.vmi-featured .dot{background:#ffd60a !important}
</style>
@endpush

@section('content')
<div class="pw">

  {{-- ── Main ───────────────────────────────────────────────────── --}}
  <div class="pw-main">

    {{-- Ambiyans ışığı canvas — .vw dışında, .pw-main içinde --}}
    <canvas id="ambi-canvas" width="32" height="18" aria-hidden="true"></canvas>

    <div class="vw" id="vw">
      <div id="vd-clip"><video id="vd" playsinline></video></div>

      {{-- IMA Ad Container --}}
      @if(!empty($adsConfig['enabled']) && !empty($adsConfig['vast_url']))
      <div id="ad-container" style="position:absolute;inset:0;z-index:50;display:none;background:#000"></div>
      @endif

      {{-- Intro overlay --}}
      @if($introUrl)
      <div id="intro-overlay">
        <video id="intro-vd" src="{{ $introUrl }}" playsinline webkit-playsinline
               style="width:100%;height:100%;object-fit:contain;display:block"></video>
        <button id="intro-skip" onclick="skipIntro()">
          Geç <span id="intro-timer"></span>
        </button>
      </div>
      @endif

      {{-- NicoNico yorum katmanı --}}
      <div id="nico-layer" style="position:absolute;inset:0;pointer-events:none;overflow:hidden;z-index:18"></div>

      {{-- İlk kez izleyenler badge --}}
      <div id="firstwatch-badge" style="display:none;position:absolute;top:12px;left:12px;z-index:20;background:rgba(0,0,0,.65);border:1px solid rgba(0,245,255,.35);border-radius:20px;padding:5px 13px;font-size:.75rem;color:#fff;backdrop-filter:blur(8px);pointer-events:none">
        <span style="color:var(--accent2)">🔴</span> <span id="firstwatch-count">0</span> kişi ilk kez izliyor
      </div>

      {{-- Watch Party butonu --}}
      @auth
      <button id="party-fab" onclick="openPartyModal()"
        style="display:none;position:absolute;top:12px;right:12px;z-index:20;background:rgba(255,45,125,.15);border:1px solid rgba(255,45,125,.4);border-radius:20px;padding:5px 13px;font-size:.75rem;color:#fff;cursor:pointer;backdrop-filter:blur(8px);transition:all .2s"
        onmouseover="this.style.background='rgba(255,45,125,.3)'" onmouseout="this.style.background='rgba(255,45,125,.15)'">
        <i class="bi bi-people-fill" style="color:#ff2d7d"></i> Birlikte İzle
      </button>
      @endauth

      {{-- Ruh Hali Motoru overlay --}}
      <div id="mood-overlay">
        <div id="mood-picker">
          <div class="mood-title">🎬 Bölüm bitti! Sırada ne izleyelim?</div>
          <div class="mood-sub">Ruh halini seç, sana özel öneri getirelim.</div>
          <div class="mood-emojis">
            <button class="mood-btn" onclick="fetchMood('sad')"><span class="me">😭</span><span class="ml">Ağlamak</span></button>
            <button class="mood-btn" onclick="fetchMood('funny')"><span class="me">🤣</span><span class="ml">Gülmek</span></button>
            <button class="mood-btn" onclick="fetchMood('hype')"><span class="me">🔥</span><span class="ml">Heyecan</span></button>
            <button class="mood-btn" onclick="fetchMood('think')"><span class="me">🧠</span><span class="ml">Düşünmek</span></button>
            <button class="mood-btn" onclick="fetchMood('romance')"><span class="me">😍</span><span class="ml">Romantizm</span></button>
            <button class="mood-btn" onclick="fetchMood('scary')"><span class="me">👻</span><span class="ml">Korkmak</span></button>
          </div>
          <button class="mood-close" onclick="closeMoodOverlay()">Şimdi değil</button>
        </div>
        <div class="mood-results" id="mood-results">
          <div class="mood-results-title" id="mood-results-title">Önerilen animeler</div>
          <div class="mood-grid" id="mood-grid"></div>
          <button class="mood-close" onclick="closeMoodOverlay()">Kapat</button>
        </div>
      </div>

      {{-- Watermark cover --}}
      @if($wmCoverSeconds > 0)
      <div id="wm-cover"><span>ANIMEXE</span></div>
      @endif

      {{-- Buffer spinner (mid-play buffering) --}}
      <div class="vs" id="vs"><div class="vsp"></div><div id="vs-msg"></div></div>

      {{-- Loading screen (ilk yükleme + kaynak değişimi) --}}
      <div id="vload" class="vload on">
        <div class="vload-bg" id="vload-bg"></div>
        <div class="vload-inner">
          <div class="vload-rig">
            <div class="vload-ring"></div>
            <div class="vload-ring"></div>
            <div class="vload-ring"></div>
            <div class="vload-orb"></div>
            <div class="vload-orb"></div>
            <div class="vload-orb"></div>
            <div class="vload-dot"></div>
          </div>
          <div class="vload-lbl">Yükleniyor<span class="vload-ldots"></span></div>
          <div class="vload-tip" id="vload-tip"></div>
          <button class="vload-playbtn" id="vload-playbtn" onclick="_vloadPlay()">
            <i class="bi bi-play-fill"></i> Oynatmak için tıkla
          </button>
          <button class="vload-retrybtn" id="vload-retrybtn" onclick="window.location.reload()">
            <i class="bi bi-arrow-clockwise"></i> Yüklenemiyor — Yenile
          </button>
        </div>
      </div>

      {{-- İntro/Outro atla butonu --}}
      <button id="aniskip-btn" onclick="skipAniSkip()">
        <i class="bi bi-skip-end-fill"></i> <span id="aniskip-label">İntroyu Atla</span>
      </button>

      {{-- Most-skipped segment button --}}
      <button id="skip-seg-btn" style="display:none!important"></button>

      {{-- Muted chip (autoplay policy — küçük, video'yu bloklamaz) --}}
      <div id="vunmute" style="display:none;position:absolute;bottom:72px;left:50%;transform:translateX(-50%);z-index:36;pointer-events:auto">
        <button onclick="doUnmute()" style="display:flex;align-items:center;gap:8px;padding:10px 20px;border-radius:50px;background:rgba(6,6,20,.92);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border:1px solid rgba(255,45,125,.5);color:#fff;font-size:.84rem;font-weight:700;cursor:pointer;font-family:inherit;white-space:nowrap;box-shadow:0 4px 24px rgba(255,45,125,.3);animation:unmute-pulse 1.8s ease-in-out infinite">
          <i class="bi bi-volume-mute-fill" style="color:#ff2d7d;font-size:1.1rem"></i>
          <span>Sessiz — sesi açmak için tıkla</span>
        </button>
      </div>

      {{-- Subtitle overlay --}}
      <div class="vsub" id="vsub"></div>

      {{-- Seek flash --}}
      <div class="vrf L" id="rf-l"><div class="vrf-bg"></div><div class="vrf-inner"><div class="vrf-chevs"><i class="bi bi-chevron-left"></i><i class="bi bi-chevron-left"></i><i class="bi bi-chevron-left"></i></div><span class="vrf-sec">10 saniye</span></div></div>
      <div class="vrf R" id="rf-r"><div class="vrf-bg"></div><div class="vrf-inner"><div class="vrf-chevs"><i class="bi bi-chevron-right"></i><i class="bi bi-chevron-right"></i><i class="bi bi-chevron-right"></i></div><span class="vrf-sec">10 saniye</span></div></div>
      <div id="hold-ind" style="display:none;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background:rgba(0,0,0,.72);border:1px solid rgba(255,255,255,.18);border-radius:28px;padding:10px 22px;color:#fff;font-size:1rem;font-weight:800;pointer-events:none;z-index:30;backdrop-filter:blur(8px);white-space:nowrap">⚡ 2× Hız</div>

      {{-- Controls --}}
      <div class="vc" id="vc">
        <div class="vm-backdrop" id="vm-backdrop" onclick="event.stopPropagation();closeMenus();" aria-hidden="true"></div>
        <div class="vm-mobile-backdrop" id="vm-mobile-backdrop" onclick="closeMenus();" aria-hidden="true"></div>
        {{-- Progress --}}
        <div class="vp-wrap">
          <div class="vp-bar" id="vpbar">
            <div class="vp-tip" id="vptip"><canvas id="vptip-thumb" width="160" height="90"></canvas><span id="vptip-time">0:00</span></div>
            <div class="vp-buf" id="vpbuf" style="width:0%"></div>
            <div class="vp-fill" id="vpfill" style="width:0%">
              <div class="vp-th"></div>
            </div>
          </div>
        </div>

        {{-- Control bar — süre ortada, sağda ayar / tam ekran aynı hizada --}}
        <div class="vcb">
          <div class="vcb-l">
          @if($prev)
          <a href="{{ route('watch',[$anime->slug,$prev->season?->season_number??$seasonModel->season_number,$prev->episode_number]) }}" class="cb" title="Önceki Bölüm (P)">
            <i class="bi bi-skip-start-fill"></i>
          </a>
          @endif
          <button class="cb skbtn" onclick="seek(-10)" title="-10s (J)">
            <i class="bi bi-arrow-counterclockwise"></i><small>10s</small>
          </button>
          <button class="cb" id="cb-play" onclick="doPlay()" title="Oynat/Durdur (K)">
            <i class="bi bi-play-fill" id="cb-play-i"></i>
          </button>
          <button class="cb skbtn" onclick="seek(10)" title="+10s (L)">
            <i class="bi bi-arrow-clockwise"></i><small>10s</small>
          </button>
          @if($next)
          <a href="{{ $nextUrl }}" class="cb" title="Sonraki Bölüm (N)">
            <i class="bi bi-skip-end-fill"></i>
          </a>
          @endif
          </div>
          <div class="vcb-time"><span class="vtime" id="vtime">0:00 / 0:00</span></div>
          <div class="vcb-r">
            {{-- Kalite badge: sadece landscape'te görünür --}}
            <div class="vdrop set-btn-wrap">
              <button class="cb" id="cb-set" onclick="openMenu('mnu-set')" title="Kalite ve Ayarlar" style="gap:4px">
                <i class="bi bi-gear-fill" style="font-size:.95rem"></i>
                <span class="lbl" id="qlbl" style="font-size:.72rem;font-weight:700;min-width:32px;text-align:left">Auto</span>
              </button>
              <div class="vmenu" id="mnu-set" style="min-width:190px">
                @if(count($videoSourcesData ?? []) > 1)
                <div class="dub-in-menu">
                  <div class="vmt">Çeviri / Kaynak</div>
                  @foreach($videoSourcesData as $idx => $vs)
                  <div class="vmi vmi-src {{ $idx === 0 ? 'on' : '' }}{{ !empty($vs['featured']) ? ' vmi-featured' : '' }}"
                       data-url="{{ $vs['url'] }}" data-lbl="{{ $vs['label'] }}" data-key="{{ $vs['key'] }}" data-type="{{ $vs['type'] }}" onclick="doSource(this)">
                    <span class="dot"></span>
                    @if(!empty($vs['featured']))
                      <span>⭐ {{ $vs['label'] }}</span>
                    @else
                      <span>{{ $vs['label'] }}</span>
                    @endif
                  </div>
                  @endforeach
                  <div class="vm-sep"></div>
                </div>
                @endif
                @if(count($dubSources) > 1)
                <div class="dub-in-menu">
                  <div class="vmt">Dublaj / Ses</div>
                  @foreach($dubSources as $d)
                  <div class="vmi vmi-dub {{ $d['active'] ? 'on' : '' }}" data-url="{{ $d['url'] }}" data-lbl="{{ $d['label'] }}" data-key="{{ $d['key'] }}" onclick="doDub(this)">
                    <span class="dot"></span><span>{{ $d['label'] }}</span>
                  </div>
                  @endforeach
                  <div class="vm-sep"></div>
                </div>
                @endif
                @if(count($subtitlesData) > 0)
                <div class="vmt">Altyazı</div>
                <div class="vmi {{ !collect($subtitlesData)->contains('is_default',true)?'on':'' }}" data-i="-1" onclick="doSub(-1,this)">
                  <span class="dot"></span><span>Kapalı</span>
                </div>
                @foreach($subtitlesData as $i => $s)
                <div class="vmi {{ $s['is_default']?'on':'' }}" data-i="{{ $i }}" onclick="doSub({{ $i }},this)">
                  <span class="dot"></span><span>{{ $s['label'] }}</span>
                </div>
                @endforeach
                <div class="vmt" style="margin-top:2px">Altyazı Görünümü</div>
                <div style="padding:2px 0 6px">
                  <div class="sub-row">
                    <span class="sub-row-lbl">Boyut</span>
                    <div style="display:flex;gap:4px">
                      <button class="sub-sz-btn" data-sz="small"  onclick="setSubSize('small',this)">A</button>
                      <button class="sub-sz-btn" data-sz="medium" onclick="setSubSize('medium',this)">A</button>
                      <button class="sub-sz-btn" data-sz="large"  onclick="setSubSize('large',this)">A</button>
                      <button class="sub-sz-btn" data-sz="xlarge" onclick="setSubSize('xlarge',this)">A</button>
                    </div>
                  </div>
                  <div class="sub-row">
                    <span class="sub-row-lbl">Renk</span>
                    <div style="display:flex;gap:5px;align-items:center">
                      <button class="sub-clr-btn" data-clr="#ffffff" onclick="setSubColor('#ffffff',this)" title="Beyaz" style="background:#fff"></button>
                      <button class="sub-clr-btn" data-clr="#ffff00" onclick="setSubColor('#ffff00',this)" title="Sarı"  style="background:#ffff00"></button>
                      <button class="sub-clr-btn" data-clr="#00ffcc" onclick="setSubColor('#00ffcc',this)" title="Nane"  style="background:#00ffcc"></button>
                      <button class="sub-clr-btn" data-clr="#ff9acd" onclick="setSubColor('#ff9acd',this)" title="Pembe" style="background:#ff9acd"></button>
                      <button class="sub-clr-btn" data-clr="#a0d4ff" onclick="setSubColor('#a0d4ff',this)" title="Mavi"  style="background:#a0d4ff"></button>
                    </div>
                  </div>
                  <div class="sub-row">
                    <span class="sub-row-lbl">Arka plan</span>
                    <div style="display:flex;gap:4px">
                      <button class="sub-bg-btn" data-bg="none" onclick="setSubBg('none',this)">Yok</button>
                      <button class="sub-bg-btn" data-bg="semi" onclick="setSubBg('semi',this)">Yarı</button>
                      <button class="sub-bg-btn" data-bg="full" onclick="setSubBg('full',this)">Tam</button>
                    </div>
                  </div>
                </div>
                <div style="height:1px;background:#222;margin:6px 0"></div>
                @endif
                <div class="vmt">Video Kalitesi</div>
                <div class="vmi on" id="q-auto" data-q="-1" onclick="doQuality(-1,this)">
                  <span class="dot"></span><span>Otomatik</span>
                </div>
                {{-- HLS levels injected by JS --}}
                <div id="q-levels"></div>
                <div style="height:1px;background:#222;margin:6px 0"></div>
                <div class="vmt">Oynatma Hızı</div>
                @foreach([0.5,0.75,1,1.25,1.5,2] as $spd)
                <div class="vmi {{ $spd==1?'on':'' }}" data-spd="{{ $spd }}" onclick="doSpeed({{ $spd }},this)">
                  <span class="dot"></span><span>{{ $spd }}x</span>
                </div>
                @endforeach
                <div style="height:1px;background:#222;margin:6px 0"></div>
                <div class="vmt">Video Zoom</div>
                <div class="vmi" id="fill-toggle" onclick="toggleFill()">
                  <span class="dot"></span><span>Ekranı Doldur</span>
                </div>
                <div class="zoom-row" id="zoom-row">
                  <input type="range" class="zoom-slider" id="zoom-slider"
                         min="100" max="200" step="5" value="100"
                         oninput="applyZoom(this.value)">
                  <div class="zoom-meta">
                    <span>Normal</span>
                    <span id="zoom-lbl" style="color:var(--accent2);font-weight:700">100%</span>
                    <span>2×</span>
                  </div>
                </div>
                <div style="height:1px;background:#222;margin:6px 0"></div>
                <div class="vmt">Görsel</div>
                <div class="vmi" id="ambi-toggle" onclick="toggleAmbi()"><span class="dot"></span><span>Ambiyans Işığı</span></div>
              </div>
            </div>

            {{-- Altyazı: her zaman görünür, ayrı CC butonu --}}
            @if(count($subtitlesData) > 0)
            <div class="vdrop sub-bar">
              <button class="cb" id="cb-sub" onclick="openMenu('mnu-sub')" title="Altyazı (C)" style="flex-shrink:0">
                <i class="bi bi-badge-cc-fill"></i>
              </button>
              <div class="vmenu" id="mnu-sub" style="min-width:170px">
                <div class="vmt">Altyazı</div>
                <div class="vmi {{ !collect($subtitlesData)->contains('is_default',true)?'on':'' }}" data-i="-1" onclick="doSub(-1,this);closeMenus()">
                  <span class="dot"></span><span>Kapalı</span>
                </div>
                @foreach($subtitlesData as $i => $s)
                <div class="vmi {{ $s['is_default']?'on':'' }}" data-i="{{ $i }}" onclick="doSub({{ $i }},this);closeMenus()">
                  <span class="dot"></span><span>{{ $s['label'] }}</span>
                </div>
                @endforeach
              </div>
            </div>
            @endif

            {{-- Dub: sadece geniş ekranda ayrı buton --}}
            @if(count($dubSources) > 1)
            <div class="vdrop dub-bar">
              <button class="cb" id="cb-dub" onclick="openMenu('mnu-dub')" title="Dublaj">
                <i class="bi bi-translate"></i>
                <span class="lbl" id="dub-lbl">{{ collect($dubSources)->firstWhere('active',true)['label'] ?? ($dubSources[0]['label']??'Dil') }}</span>
              </button>
              <div class="vmenu" id="mnu-dub">
                <div class="vmt">Dublaj / Dil</div>
                @foreach($dubSources as $d)
                <div class="vmi vmi-dub {{ $d['active'] ? 'on' : '' }}" data-url="{{ $d['url'] }}" data-lbl="{{ $d['label'] }}" data-key="{{ $d['key'] }}" onclick="doDub(this)">
                  <span class="dot"></span><span>{{ $d['label'] }}</span>
                </div>
                @endforeach
              </div>
            </div>
            @endif
            <div class="vcv">
              <input type="range" class="vvr" id="cb-vvr" min="0" max="1" step="0.02" value="1" style="--v:100%" oninput="doVol(this.value)">
              <button class="cb" id="cb-vol" onclick="doMute()" title="Sessiz (M)" style="flex-shrink:0">
                <i class="bi bi-volume-up-fill" id="cb-vol-i"></i>
              </button>
            </div>
            <button class="cb cb-kbhelp" onclick="toggleKbHelp()" title="Klavye Kısayolları (?)" style="flex-shrink:0;font-size:.72rem;font-weight:800;padding:0 8px;opacity:.6">?</button>
            <button class="cb" id="cb-fs" onclick="doFS()" title="Tam Ekran (F)" style="flex-shrink:0">
              <i class="bi bi-fullscreen" id="cb-fs-i"></i>
            </button>
          </div>
        </div>
      </div>

      {{-- Next ep --}}
      @if($next)
      <div class="vnx" id="vnx">
        <div class="vnx-hdr">
          <div class="vnx-lbl">Sıradaki Bölüm</div>
          <button class="vnx-cancel" onclick="cancelNext()" title="İptal"><i class="bi bi-x"></i></button>
        </div>
        <div class="vnx-ttl">{{ $next->episode_number }}. {{ $next->title ?: 'Bölüm' }}</div>
        <div class="vnx-bar"><div class="vnx-fill" id="vnx-fill" style="width:0%"></div></div>
        <a href="{{ $nextUrl }}" class="vnx-btn"><i class="bi bi-play-fill"></i> Sonraki Bölüme Geç</a>
      </div>
      @endif
    </div>

    {{-- NicoNico yorum giriş satırı --}}
    @auth
    <div id="nico-input-row" class="nico-off ctrls-hidden">
      <button id="nico-toggle-btn" onclick="toggleNico()" title="Canlı yorumları aç/kapat"><i class="bi bi-chat-right-text-fill"></i> Canlı</button>
      <input type="color" id="nico-color-pick" value="#ffffff" title="Renk seç">
      <input type="text" id="nico-input" placeholder="Yorum yaz, Enter ile gönder..." maxlength="100" onkeydown="if(event.key==='Enter')sendNicoComment()">
      <button class="nico-filter-chip" id="nico-filter-btn" onclick="toggleNicoFilter()" title="Sadece takip ettiklerimin yorumları"><i class="bi bi-people-fill"></i> Takip</button>
      <button id="nico-send-btn" onclick="sendNicoComment()"><i class="bi bi-send-fill"></i></button>
    </div>
    @endauth

    {{-- Kaynak Seçici Tab Bar --}}
    @if(count($videoSourcesData ?? []) > 1)
    <div class="src-tab-bar">
      <div class="src-tab-hdr"><i class="bi bi-collection-play-fill"></i> Çeviri / Kaynak</div>
      <div class="src-tab-scroll">
        @foreach($videoSourcesData as $idx => $vs)
        <button class="src-tab {{ $idx === 0 ? 'on' : '' }}{{ !empty($vs['featured']) ? ' src-tab-4k' : '' }}"
                data-url="{{ $vs['url'] }}"
                data-lbl="{{ $vs['label'] }}"
                data-key="{{ $vs['key'] }}"
                data-type="{{ $vs['type'] }}"
                onclick="doSource(this)">
          @if(!empty($vs['featured']))
            <i class="bi bi-star-fill" style="color:#ffd60a"></i>
          @else
            <i class="bi bi-play-circle-fill"></i>
          @endif
          <span>{{ $vs['label'] }}</span>
        </button>
        @endforeach
      </div>
    </div>
    <div id="src-hint" style="display:none;align-items:flex-start;gap:10px;margin:0;padding:10px 14px;background:rgba(0,245,255,.05);border-top:1px solid rgba(0,245,255,.12);border-bottom:1px solid rgba(0,245,255,.06)">
      <i class="bi bi-info-circle-fill" style="color:rgba(0,245,255,.6);font-size:.9rem;flex-shrink:0;margin-top:1px"></i>
      <div style="flex:1;min-width:0">
        <div style="font-size:.78rem;font-weight:700;color:rgba(255,255,255,.8);margin-bottom:3px">Kaynak & Çeviri Hakkında</div>
        <div style="font-size:.74rem;color:rgba(255,255,255,.45);line-height:1.55">
          Yukarıdaki sekmeler farklı çeviri gruplarının yayınlarıdır. Bir kaynak çalışmıyorsa veya altyazı bozuksa başka bir sekmeyi deneyin — genellikle en az bir tanesi sorunsuz çalışır.
        </div>
      </div>
      <button onclick="document.getElementById('src-hint').style.display='none';localStorage.setItem('axe_src_hint','1')" style="background:none;border:none;color:rgba(255,255,255,.25);font-size:1rem;cursor:pointer;padding:2px 4px;flex-shrink:0;line-height:1;transition:color .15s" onmouseover="this.style.color='rgba(255,255,255,.7)'" onmouseout="this.style.color='rgba(255,255,255,.25)'" title="Kapat">
        <i class="bi bi-x-lg"></i>
      </button>
    </div>
    <script>if(!localStorage.getItem('axe_src_hint')){document.getElementById('src-hint').style.display='flex'}</script>
    @endif

    {{-- Info bar --}}
    <div class="pinfo">
      <div class="pinfo-row">
        <div style="flex:1;min-width:0">
          <div class="pinfo-ep-meta">
            <a href="{{ $anime->detailUrl }}" style="color:inherit">{{ $anime->title }}</a>
            &nbsp;·&nbsp;{{ $seasonModel->season_number }}. Sezon
          </div>
          <h1 class="pinfo-ep-title">
            {{ $ep->episode_number }}. Bölüm{{ $ep->title ? ' — '.$ep->title : '' }}
          </h1>
          <div class="pinfo-stats">
            <span><i class="bi bi-eye"></i>{{ number_format($ep->view_count) }}</span>
            @if($ep->duration)<span><i class="bi bi-clock"></i>{{ $ep->duration_formatted }}</span>@endif
            @if($activeDub)<span style="color:rgba(0,245,255,.55)"><i class="bi bi-translate"></i>{{ ['trdub'=>'TR Dublaj','original'=>'Japonca','endub'=>'EN Dublaj'][$activeDub]??$activeDub }}</span>@endif
            @if($anime->rating)<span style="color:#ffd60a"><i class="bi bi-star-fill"></i>{{ number_format($anime->rating,1) }}</span>@endif
          </div>
        </div>
        <div class="pnav">
          @auth
          <button class="pnav-btn" onclick="openShareModal()" title="Arkadaşınla paylaş" style="color:var(--accent2)">
            <i class="bi bi-send-fill"></i><span class="d-none d-sm-inline"> Paylaş</span>
          </button>
          @endauth
          @if($prev)
          <a href="{{ route('watch',[$anime->slug,$prev->season?->season_number??$seasonModel->season_number,$prev->episode_number]) }}" class="pnav-btn">
            <i class="bi bi-chevron-left"></i><span class="d-none d-sm-inline"> Önceki</span>
          </a>
          @endif
          @if($next)
          <a href="{{ $nextUrl }}" class="pnav-btn pnav-next">
            <span class="d-none d-sm-inline">Sonraki </span><i class="bi bi-chevron-right"></i>
          </a>
          @endif
        </div>
      </div>
    </div>

    {{-- ── Tabs + Content ─────────────────────────────────────────── --}}
    <div class="ep-below">

      {{-- Tab nav --}}
      <div class="eb-tabs">
        <button class="eb-tab on" onclick="switchTab('info',this)">
          <i class="bi bi-info-circle"></i> Bölüm Bilgisi
        </button>
        <button class="eb-tab" onclick="switchTab('cmt',this)">
          <i class="bi bi-chat-dots"></i> Yorumlar
          <span class="tab-badge" id="tab-cmt-badge" style="display:none"></span>
        </button>
        @auth
        <button class="eb-tab" onclick="switchTab('ai',this)" style="color:var(--accent3)">
          <i class="bi bi-stars"></i> AI Analiz
        </button>
        <button class="eb-tab" onclick="switchTab('notes',this)" style="color:#ffd700">
          <i class="bi bi-journal-text"></i> Notlarım
          <span class="tab-badge" id="tab-notes-badge" style="display:none;background:rgba(255,215,0,.15);color:#ffd700"></span>
        </button>
        @else
        <button class="eb-tab" onclick="showPlayerLoginPrompt()" style="color:var(--accent3);opacity:.6">
          <i class="bi bi-stars"></i> AI Analiz <i class="bi bi-lock-fill" style="font-size:.65rem"></i>
        </button>
        @endauth
        <button class="eb-tab" onclick="switchTab('predict',this)" style="color:#ff9f0a">
          <i class="bi bi-lightning-charge"></i> Tahminler
          <span class="tab-badge" id="tab-predict-badge" style="display:none;background:rgba(255,159,10,.15);color:#ff9f0a"></span>
        </button>
      </div>

      {{-- ── Info Panel ──────────────────────────────────────────── --}}
      <div class="eb-panel on" id="panel-info">
        <div class="eb-info">

          <div class="ep-card">
            {{-- Anime posteri --}}
            @if($anime->coverUrl)
            <div class="ep-card-poster">
              <img src="{{ $anime->coverUrl }}" alt="{{ $anime->title }}" loading="lazy">
            </div>
            @endif

            <div class="ep-card-body">
              <div class="ep-card-anime-title">
                <a href="{{ $anime->detailUrl }}">{{ $anime->title }}</a>
                &nbsp;·&nbsp; {{ $seasonModel->season_number }}. Sezon
              </div>
              <div class="ep-card-ep-title">
                {{ $ep->episode_number }}. Bölüm{{ $ep->title ? ' — '.$ep->title : '' }}
              </div>

              <div class="ep-card-stats">
                <div class="ep-stat stat-views"><i class="bi bi-eye"></i> {{ number_format($ep->view_count) }} izlenme</div>
                @if($ep->duration)<div class="ep-stat stat-dur"><i class="bi bi-clock"></i> {{ $ep->duration_formatted }}</div>@endif
                @if($activeDub)<div class="ep-stat stat-dub"><i class="bi bi-translate"></i> {{ ['trdub'=>'Türkçe Dublaj','original'=>'Japonca (Orijinal)','endub'=>'İngilizce Dublaj'][$activeDub] ?? $activeDub }}</div>@endif
                @if($anime->rating)<div class="ep-stat stat-rating"><i class="bi bi-star-fill"></i> {{ number_format($anime->rating,1) }}</div>@endif
              </div>

              {{-- Like / Dislike --}}
              @php
                $epLikes    = \App\Models\EpisodeVote::where('episode_id',$ep->id)->where('vote',1)->count();
                $epDislikes = \App\Models\EpisodeVote::where('episode_id',$ep->id)->where('vote',-1)->count();
                $myVote     = auth()->check() ? \App\Models\EpisodeVote::where('user_id',auth()->id())->where('episode_id',$ep->id)->value('vote') : null;
              @endphp
              <div class="ep-vote-row" id="ep-vote-row" style="display:flex;gap:10px;margin-top:14px;align-items:center">
                @auth
                <button id="btn-like" onclick="voteEpisode(1)"
                  class="ep-vote-btn {{ $myVote==1?'voted-like':'' }}"
                  style="display:flex;align-items:center;gap:6px;padding:7px 14px;border-radius:20px;border:1px solid {{ $myVote==1?'#3fb950':'#30363d' }};background:{{ $myVote==1?'rgba(63,185,80,.15)':'transparent' }};color:{{ $myVote==1?'#3fb950':'var(--text2)' }};cursor:pointer;font-size:.82rem;transition:all .2s">
                  <i class="bi bi-hand-thumbs-up{{ $myVote==1?'-fill':'' }}" id="like-icon"></i>
                  <span id="like-cnt">{{ $epLikes }}</span>
                </button>
                <button id="btn-dislike" onclick="voteEpisode(-1)"
                  class="ep-vote-btn {{ $myVote==-1?'voted-dislike':'' }}"
                  style="display:flex;align-items:center;gap:6px;padding:7px 14px;border-radius:20px;border:1px solid {{ $myVote==-1?'#f85149':'#30363d' }};background:{{ $myVote==-1?'rgba(248,81,73,.15)':'transparent' }};color:{{ $myVote==-1?'#f85149':'var(--text2)' }};cursor:pointer;font-size:.82rem;transition:all .2s">
                  <i class="bi bi-hand-thumbs-down{{ $myVote==-1?'-fill':'' }}" id="dislike-icon"></i>
                  <span id="dislike-cnt">{{ $epDislikes }}</span>
                </button>
                @else
                <a href="{{ route('frontend.login') }}" style="display:flex;align-items:center;gap:6px;padding:7px 14px;border-radius:20px;border:1px solid #30363d;color:var(--text3);font-size:.82rem;text-decoration:none">
                  <i class="bi bi-hand-thumbs-up"></i> {{ $epLikes }}
                </a>
                <a href="{{ route('frontend.login') }}" style="display:flex;align-items:center;gap:6px;padding:7px 14px;border-radius:20px;border:1px solid #30363d;color:var(--text3);font-size:.82rem;text-decoration:none">
                  <i class="bi bi-hand-thumbs-down"></i> {{ $epDislikes }}
                </a>
                @endauth
              </div>

              @if($ep->description)
              <div class="ep-desc-wrap">
                <div class="ep-desc-lbl">Bölüm Hakkında</div>
                <p class="ep-desc-text" id="ep-desc">{{ $ep->description }}</p>
                @if(mb_strlen($ep->description) > 220)
                <button class="ep-expand-btn" id="ep-expand-btn" onclick="toggleDesc()">Devamını Oku <i class="bi bi-chevron-down"></i></button>
                @endif
              </div>
              @elseif($anime->description)
              <div class="ep-desc-wrap">
                <div class="ep-desc-lbl">Anime Hakkında</div>
                <p class="ep-desc-text" id="ep-desc">{{ $anime->description }}</p>
                @if(mb_strlen($anime->description) > 220)
                <button class="ep-expand-btn" id="ep-expand-btn" onclick="toggleDesc()">Devamını Oku <i class="bi bi-chevron-down"></i></button>
                @endif
              </div>
              @endif

              {{-- Türler --}}
              @if($anime->genres && $anime->genres->count())
              <div class="ep-tags">
                @foreach($anime->genres->take(6) as $g)
                <a href="{{ route('genre', $g->slug) }}" class="ep-tag">{{ $g->name }}</a>
                @endforeach
              </div>
              @endif
            </div>
          </div>

          {{-- Anime meta --}}
          <div class="ep-meta-row">
            @if($anime->studio)
            <div class="ep-meta-item">
              <span class="ep-meta-key">Stüdyo</span>
              <span class="ep-meta-val">{{ $anime->studio }}</span>
            </div>
            @endif
            @if($anime->release_year)
            <div class="ep-meta-item">
              <span class="ep-meta-key">Yıl</span>
              <span class="ep-meta-val">{{ $anime->release_year }}</span>
            </div>
            @endif
            @if($anime->status)
            <div class="ep-meta-item">
              <span class="ep-meta-key">Durum</span>
              <span class="ep-meta-val">{{ ['ongoing'=>'Devam Ediyor','completed'=>'Tamamlandı','upcoming'=>'Yakında'][$anime->status] ?? $anime->status }}</span>
            </div>
            @endif
            <div class="ep-meta-item">
              <span class="ep-meta-key">Sezon</span>
              <span class="ep-meta-val">{{ $anime->seasons->count() }} Sezon · {{ $anime->episode_count }} Bölüm</span>
            </div>
          </div>

        </div>
      </div>

      {{-- ── Comments Panel ──────────────────────────────────────── --}}
      <div class="eb-panel" id="panel-cmt">
        <div class="eb-cmt">
          <div class="cmt-section" id="cmt-section">
            <div class="cmt-hdr">
              <span class="cmt-title"><i class="bi bi-chat-dots"></i> Yorumlar</span>
              <span class="cmt-count" id="cmt-count-lbl"></span>
            </div>

            @auth
            <div class="cmt-form-wrap" id="cmt-form-wrap">
              <div class="cmt-form-avatar">@if(auth()->user()->avatar)<img src="{{ \App\Support\MediaUrl::fromStoragePath(auth()->user()->avatar) }}" style="width:100%;height:100%;object-fit:cover">@else{{ mb_substr(auth()->user()->name,0,1) }}@endif</div>
              <div class="cmt-form-body">
                <div id="cmt-gif-preview" style="display:none;margin-bottom:8px">
                  <div style="position:relative;display:inline-block">
                    <img id="cmt-gif-img" src="" alt="GIF" style="max-height:140px;border-radius:8px;display:block">
                    <button onclick="clearGif()" style="position:absolute;top:4px;right:4px;background:rgba(0,0,0,.7);border:none;color:#fff;border-radius:50%;width:22px;height:22px;cursor:pointer;font-size:.75rem;display:flex;align-items:center;justify-content:center">✕</button>
                  </div>
                </div>
                <textarea id="cmt-input" class="cmt-input" placeholder="Yorumunu yaz..." rows="2" oninput="autoResize(this);updateCharCount()"></textarea>
                <div style="font-size:.68rem;color:rgba(255,255,255,.25);text-align:right;margin-top:2px" id="cmt-char-count"></div>
                <div class="cmt-form-actions">
                  @if(auth()->check() && auth()->user()->hasPerk('comment_gif'))
                  <button class="cmt-gif-btn" onclick="toggleGifPicker()" title="GIF ekle">
                    <i class="bi bi-image"></i> GIF
                  </button>
                  @else
                  <button class="cmt-gif-btn" style="opacity:.4;cursor:default" title="GIF eklemek için premium gerekiyor" onclick="event.preventDefault()">
                    <i class="bi bi-image"></i> GIF <i class="bi bi-lock-fill" style="font-size:.65rem"></i>
                  </button>
                  @endif
                  <button class="cmt-submit-btn" id="cmt-submit-btn" onclick="submitComment()">
                    <i class="bi bi-send-fill"></i> Gönder
                  </button>
                </div>
              </div>
            </div>

            <div id="gif-picker" class="gif-picker" style="display:none">
              <div class="gif-search-wrap">
                <i class="bi bi-search" style="position:absolute;left:12px;top:50%;transform:translateY(-50%);color:var(--text3);font-size:.85rem"></i>
                <input type="text" id="gif-search-input" class="gif-search-input" placeholder="GIF ara..." oninput="searchGif(this.value)">
              </div>
              <div id="gif-results" class="gif-results">
                <div class="gif-loading">Arama yapın...</div>
              </div>
            </div>
            @else
            <div class="cmt-login-prompt">
              <i class="bi bi-chat-square-heart" style="font-size:2rem;opacity:.3;display:block;margin-bottom:10px"></i>
              Yorum yapmak için <a href="{{ route('frontend.login') }}" style="color:var(--accent2)">giriş yapın</a>.
            </div>
            @endauth

            <div id="cmt-list"></div>
            <div id="cmt-load-more" style="display:none;text-align:center;padding:16px">
              <button class="cmt-load-btn" onclick="loadComments()">Daha fazla yorum yükle</button>
            </div>
            <div id="cmt-empty" style="display:none" class="cmt-empty">
              <i class="bi bi-chat-dots" style="font-size:2rem;opacity:.2;display:block;margin-bottom:8px"></i>
              İlk yorumu sen yap!
            </div>
          </div>
        </div>
      </div>

      {{-- ── AI Analiz Paneli ──────────────────────────────────────── --}}
      @auth
      <div class="eb-panel" id="panel-ai">
        <div style="padding:24px 20px">
          {{-- Bölüm AI analizi --}}
          <div style="margin-bottom:24px">
            <div style="display:flex;align-items:center;gap:10px;margin-bottom:16px">
              <div style="width:36px;height:36px;border-radius:10px;background:linear-gradient(135deg,var(--accent3),var(--accent));display:flex;align-items:center;justify-content:center;font-size:.95rem;color:#fff;box-shadow:0 0 16px rgba(184,77,255,.4);flex-shrink:0"><i class="bi bi-cpu"></i></div>
              <div>
                <div style="font-weight:700;color:var(--text);font-size:.9rem">Bölüm AI Analizi</div>
                <div style="font-size:.75rem;color:var(--text3);margin-top:1px">Spoilersız bölüm analizi ve öneriler</div>
              </div>
            </div>
            <button id="ai-ep-btn" onclick="loadEpAi()" style="padding:10px 20px;border-radius:10px;border:1px solid rgba(184,77,255,.35);background:rgba(184,77,255,.1);color:var(--accent3);font-size:.85rem;font-weight:700;cursor:pointer;transition:all .16s;font-family:inherit;display:flex;align-items:center;gap:8px">
              <i class="bi bi-stars"></i> Bu bölümü AI ile analiz et
            </button>
            <div id="ai-ep-loader" style="display:none;padding:16px 0;display:none;align-items:center;gap:8px">
              <div style="display:flex;gap:4px">
                <div style="width:7px;height:7px;border-radius:50%;background:var(--accent3);animation:aip-b .9s ease-in-out infinite"></div>
                <div style="width:7px;height:7px;border-radius:50%;background:var(--accent);animation:aip-b .9s .18s ease-in-out infinite"></div>
                <div style="width:7px;height:7px;border-radius:50%;background:var(--accent2);animation:aip-b .9s .36s ease-in-out infinite"></div>
              </div>
              <span style="color:var(--text3);font-size:.82rem">AI analiz yapıyor...</span>
            </div>
            <div id="ai-ep-result" style="display:none;margin-top:16px;padding:16px;background:linear-gradient(135deg,rgba(184,77,255,.1),rgba(0,245,255,.06));border:1px solid rgba(184,77,255,.2);border-radius:12px;color:var(--text);font-size:.88rem;line-height:1.65"></div>
          </div>

          {{-- Sohbet bölümü (mini) --}}
          <div style="border-top:1px solid rgba(255,255,255,.06);padding-top:20px">
            <div style="font-size:.8rem;font-weight:700;color:var(--text2);margin-bottom:10px;text-transform:uppercase;letter-spacing:.08em"><i class="bi bi-chat-dots" style="margin-right:5px;color:var(--accent3)"></i>Bu anime hakkında AI'ya sor</div>
            <div style="display:flex;flex-wrap:wrap;gap:6px;margin-bottom:12px">
              @foreach(['Bu animeyi tamamlamalı mıyım?','Benzer anime önerir misin?','Bu bölümde neler oldu?','Anime ne zaman bitti?'] as $q)
              <button onclick="aiPlayerAsk('{{ $q }}')" style="padding:5px 11px;border-radius:999px;font-size:.75rem;font-weight:600;cursor:pointer;background:rgba(0,245,255,.06);border:1px solid rgba(0,245,255,.2);color:var(--accent2);transition:all .14s;font-family:inherit">{{ $q }}</button>
              @endforeach
            </div>
            <div style="display:flex;gap:8px">
              <input id="ai-player-inp" type="text" placeholder="Soru sor..." style="flex:1;background:rgba(255,255,255,.05);border:1px solid rgba(184,77,255,.25);border-radius:9px;padding:10px 12px;color:var(--text);font-size:.84rem;font-family:inherit;outline:none" onkeydown="if(event.key==='Enter') sendPlayerAiMsg()">
              <button onclick="sendPlayerAiMsg()" style="padding:10px 16px;border-radius:9px;border:none;background:linear-gradient(135deg,var(--accent3),var(--accent));color:#fff;cursor:pointer;font-size:.85rem;transition:transform .14s" id="ai-player-send"><i class="bi bi-send-fill"></i></button>
            </div>
            <div id="ai-player-msgs" style="margin-top:12px;display:flex;flex-direction:column;gap:8px;max-height:280px;overflow-y:auto"></div>
          </div>
        </div>
      </div>
      {{-- ── Not Paneli ─────────────────────────────────────────────── --}}
      <div class="eb-panel" id="panel-notes" style="padding:16px">
        <div style="margin-bottom:14px">
          <div style="font-size:.8rem;font-weight:700;color:#ffd700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px"><i class="bi bi-journal-text" style="margin-right:5px"></i>Bölüm Notları</div>
          <div style="display:flex;gap:8px;align-items:flex-start">
            <textarea id="note-input" placeholder="Bu bölüm için not al..." style="flex:1;background:rgba(255,255,255,.05);border:1px solid rgba(255,215,0,.2);border-radius:9px;padding:10px 12px;color:var(--text);font-size:.84rem;font-family:inherit;outline:none;resize:none;height:72px" maxlength="500"></textarea>
          </div>
          <div style="display:flex;gap:6px;margin-top:8px;justify-content:flex-end">
            <button onclick="captureTimestamp()" style="padding:6px 12px;border-radius:8px;border:1px solid rgba(255,215,0,.3);background:rgba(255,215,0,.08);color:#ffd700;font-size:.78rem;font-family:inherit;cursor:pointer">
              <i class="bi bi-clock"></i> <span id="note-ts-label">Şu anki zaman</span>
            </button>
            <button onclick="saveNote()" style="padding:6px 14px;border-radius:8px;border:none;background:rgba(255,215,0,.85);color:#000;font-size:.82rem;font-weight:700;font-family:inherit;cursor:pointer">
              <i class="bi bi-plus-lg"></i> Kaydet
            </button>
          </div>
        </div>
        <div id="notes-list" style="display:flex;flex-direction:column;gap:8px;max-height:320px;overflow-y:auto"></div>
        <div id="notes-empty" style="text-align:center;padding:28px;color:var(--text3);font-size:.82rem">
          <i class="bi bi-journal" style="font-size:1.8rem;opacity:.3;display:block;margin-bottom:8px"></i>
          Henüz not eklemedin. Sahne kaydet, sonra bul!
        </div>
      </div>

      @endauth

      {{-- ── Tahmin Paneli (herkese görünür, giriş gerektirir yazma) ── --}}
      <div class="eb-panel" id="panel-predict" style="padding:16px">
        <div style="font-size:.8rem;font-weight:700;color:#ff9f0a;text-transform:uppercase;letter-spacing:.08em;margin-bottom:12px">
          <i class="bi bi-lightning-charge" style="margin-right:5px"></i>Bir Sonraki Bölüm Tahminleri
        </div>

        @auth
        <div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:14px" id="predict-form-wrap">
          <textarea id="predict-input" placeholder="Ne olacağını tahmin et... (maks 280 karakter)"
            style="flex:1;background:rgba(255,159,10,.05);border:1px solid rgba(255,159,10,.2);border-radius:9px;padding:10px 12px;color:var(--text);font-size:.84rem;font-family:inherit;outline:none;resize:none;height:68px" maxlength="280"></textarea>
          <button onclick="submitPrediction()" style="padding:9px 14px;border-radius:9px;border:none;background:#ff9f0a;color:#000;font-size:.85rem;font-weight:800;font-family:inherit;cursor:pointer;flex-shrink:0;align-self:flex-end">
            <i class="bi bi-send-fill"></i>
          </button>
        </div>
        @else
        <div style="text-align:center;padding:12px;margin-bottom:12px;background:rgba(255,159,10,.05);border:1px solid rgba(255,159,10,.15);border-radius:10px;font-size:.82rem;color:rgba(255,255,255,.4)">
          <a href="{{ route('frontend.login') }}" style="color:#ff9f0a">Giriş yap</a> veya <a href="{{ route('frontend.register') }}" style="color:#ff9f0a">kayıt ol</a> — tahmin yaz
        </div>
        @endauth

        <div id="predictions-list" style="display:flex;flex-direction:column;gap:8px;max-height:380px;overflow-y:auto"></div>
        <div id="predictions-empty" style="text-align:center;padding:28px;color:var(--text3);font-size:.82rem;display:none">
          <i class="bi bi-lightning" style="font-size:1.8rem;opacity:.3;display:block;margin-bottom:8px"></i>
          Henüz tahmin yok. İlk tahmini sen yaz!
        </div>
      </div>

    </div>
  </div>

  {{-- ── Sidebar ─────────────────────────────────────────────────── --}}
  <div class="pw-side">

    {{-- Sekmeler --}}
    <div class="ps-tabs">
      <button class="ps-tab on" id="tab-eps" onclick="switchSideTab('eps')"><i class="bi bi-collection-play"></i> Bölümler</button>
      <button class="ps-tab" id="tab-spoiler" onclick="switchSideTab('spoiler')"><i class="bi bi-lock-fill"></i> Spoiler Kutusu</button>
    </div>

    {{-- Bölümler sekmesi --}}
    <div class="ps-tab-content on" id="tc-eps" style="flex-direction:column">
      <div class="ps-hdr" style="flex-shrink:0">
        @if($anime->seasons->count() > 1)
        <div class="ps-stabs">
          @foreach($anime->seasons as $s)
          <button class="pst {{ $s->id===$seasonModel->id?'on':'' }}" data-s="{{ $s->season_number }}" onclick="swS({{ $s->season_number }},this)">
            {{ $s->season_number }}. Sezon
          </button>
          @endforeach
        </div>
        @endif
      </div>
      <div style="flex:1;overflow-y:auto">
        @foreach($anime->seasons as $s)
        <div class="ps-list" id="psl{{ $s->season_number }}" style="{{ $s->id!==$seasonModel->id?'display:none':'' }}">
          @foreach($s->episodes as $pe)
          @php
            $isnow  = $pe->id === $ep->id;
            $pct    = $watchProgress[$pe->id] ?? 0;
            $watched = !$isnow && $pct >= 90;
          @endphp
          <a href="{{ route('watch',[$anime->slug,$s->season_number,$pe->episode_number]) }}"
             class="ps-item {{ $isnow?'now':'' }} {{ $watched?'ps-watched':'' }}" id="{{ $isnow?'now-ep':'' }}">
            <div class="ps-thumb">
              @if($pe->thumbnailUrl)<img src="{{ $pe->thumbnailUrl }}" alt="" loading="lazy">
              @elseif($anime->coverUrl)<img src="{{ $anime->coverUrl }}" alt="" loading="lazy">
              @else<div class="nth"><i class="bi bi-film"></i></div>@endif
              @if($isnow)<div class="nowmark"><i class="bi bi-play-circle-fill"></i></div>@endif
              @if($watched && !$isnow)<div class="nowmark" style="background:rgba(0,245,255,.6)"><i class="bi bi-check-circle-fill" style="font-size:.9rem"></i></div>@endif
              @if($pct > 0 && $pct < 90 && !$isnow)
              <div class="ps-prog" style="--p:{{ $pct }}%"></div>
              @endif
            </div>
            <div class="ps-info">
              <div class="ps-num">{{ $pe->episode_number }}. Bölüm @if($watched && !$isnow)<span style="color:var(--accent2);font-size:.62rem;margin-left:4px"><i class="bi bi-check2"></i></span>@endif</div>
              <div class="ps-name">{{ $pe->title ?: ($pe->episode_number.'. Bölüm') }}</div>
              @if($pct > 0 && $pct < 90 && !$isnow)<div class="ps-pct">%{{ $pct }}</div>@endif
            </div>
          </a>
          @endforeach
        </div>
        @endforeach
      </div>
    </div>

    {{-- Spoiler Kutusu sekmesi --}}
    <div class="ps-tab-content" id="tc-spoiler">
      <div id="sb-panel" class="ps-tab-content on" style="flex:1;overflow-y:auto;padding:12px;gap:8px;flex-direction:column">
        <div id="sb-loading" style="text-align:center;padding:24px;color:rgba(255,255,255,.3);font-size:.8rem">
          <i class="bi bi-hourglass"></i> Yükleniyor...
        </div>
      </div>
      @auth
      <div class="sb-form">
        <textarea class="sb-inp" id="sb-inp" rows="2" maxlength="600" placeholder="Spoiler veya gizli düşüncen (AI kontrol eder)..."></textarea>
        <button class="sb-send" onclick="submitSpoilerBox()"><i class="bi bi-lock"></i> Gönder</button>
      </div>
      @else
      <div style="padding:12px;text-align:center;font-size:.75rem;color:rgba(255,255,255,.3)">
        <a href="{{ route('frontend.login') }}" style="color:#ff2d7d">Giriş yap</a> — yorum ekle
      </div>
      @endauth
    </div>

  </div>

</div>

{{-- ── Share Modal ─────────────────────────────────── --}}
@auth
<div id="share-modal-overlay" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,.78);z-index:8000;backdrop-filter:blur(8px);align-items:center;justify-content:center;padding:16px" onclick="if(event.target===this)closeShareModal()">
  <div style="background:#0e0e1a;border:1px solid rgba(255,255,255,.1);border-radius:20px;width:100%;max-width:400px;overflow:hidden">
    <div style="padding:16px 20px;border-bottom:1px solid rgba(255,255,255,.07);display:flex;justify-content:space-between;align-items:center">
      <h5 style="margin:0;font-size:.95rem;color:#fff"><i class="bi bi-send" style="color:var(--accent2)"></i> Bölümü Paylaş</h5>
      <button onclick="closeShareModal()" style="background:none;border:none;color:rgba(255,255,255,.4);font-size:1.1rem;cursor:pointer"><i class="bi bi-x-lg"></i></button>
    </div>
    {{-- Episode preview --}}
    <div style="padding:14px 20px;display:flex;gap:12px;align-items:center;border-bottom:1px solid rgba(255,255,255,.06)">
      @if($anime->coverUrl)
      <img src="{{ $anime->coverUrl }}" style="width:44px;height:66px;border-radius:8px;object-fit:cover;flex-shrink:0" alt="">
      @endif
      <div>
        <div style="font-size:.82rem;font-weight:800;color:#fff">{{ $anime->title }}</div>
        <div style="font-size:.74rem;color:rgba(255,255,255,.45)">{{ $seasonModel->season_number }}. Sezon {{ $ep->episode_number }}. Bölüm{{ $ep->title?' — '.$ep->title:'' }}</div>
        <label style="display:flex;align-items:center;gap:6px;margin-top:6px;font-size:.74rem;color:rgba(255,255,255,.5);cursor:pointer">
          <input type="checkbox" id="share-ts-chk" style="accent-color:var(--accent2)"> Şu anki konumdan başlat
        </label>
      </div>
    </div>
    {{-- User search --}}
    <div style="padding:14px 20px">
      <input type="text" id="share-search" placeholder="Kullanıcı ara (username)..." autocomplete="off"
        style="width:100%;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:9px 14px;color:#fff;font-size:.85rem;font-family:inherit;outline:none"
        oninput="shareSearch(this.value)">
      <div id="share-results" style="margin-top:8px;max-height:200px;overflow-y:auto"></div>
      <div id="share-selected" style="display:none;margin-top:10px"></div>
    </div>
    <div style="padding:0 20px 16px">
      <button id="share-send-btn" onclick="doShareSend()" disabled
        style="width:100%;padding:11px;border-radius:12px;border:none;background:var(--accent2);color:#05050e;font-size:.88rem;font-weight:700;cursor:pointer;transition:all .15s;opacity:.5"
        >Gönder</button>
    </div>
  </div>
</div>
@endauth

{{-- Watch Party Modal --}}
@auth
<div id="party-modal-bg" onclick="if(event.target===this)closePartyModal()">
  <div id="party-modal">
    <div style="padding:16px 20px;border-bottom:1px solid rgba(255,255,255,.07);display:flex;justify-content:space-between;align-items:center">
      <h5 style="margin:0;font-size:.95rem;color:#fff"><i class="bi bi-people-fill" style="color:#ff2d7d"></i> Birlikte İzle — Watch Party</h5>
      <button onclick="closePartyModal()" style="background:none;border:none;color:rgba(255,255,255,.4);font-size:1.1rem;cursor:pointer"><i class="bi bi-x-lg"></i></button>
    </div>
    <div id="party-modal-body" style="padding:20px">
      <div id="party-create-view">
        <p style="font-size:.84rem;color:rgba(255,255,255,.55);margin-bottom:16px">Oda oluştur, kodunu arkadaşlarınla paylaş ve aynı anda izleyin.</p>
        <label style="display:flex;align-items:center;gap:10px;font-size:.84rem;color:rgba(255,255,255,.6);margin-bottom:12px;cursor:pointer">
          <input type="checkbox" id="party-private" style="accent-color:#ff2d7d"> Şifreli oda
        </label>
        <div id="party-pw-wrap" style="display:none;margin-bottom:12px">
          <input type="text" id="party-pw" placeholder="Oda şifresi" maxlength="30"
            style="width:100%;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.1);border-radius:10px;padding:9px 14px;color:#fff;font-size:.85rem;font-family:inherit;outline:none;box-sizing:border-box">
        </div>
        <div style="margin-bottom:16px">
          <div id="party-join-wrap" style="display:flex;gap:8px;align-items:center">
            <input type="text" id="party-join-code" placeholder="Oda kodu gir (6 harf)" maxlength="10"
              style="flex:1;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.1);border-radius:10px;padding:9px 14px;color:#fff;font-size:.85rem;font-family:inherit;outline:none;text-transform:uppercase"
              oninput="this.value=this.value.toUpperCase()">
            <button onclick="joinParty()" style="padding:9px 16px;border-radius:10px;border:none;background:rgba(0,245,255,.15);color:var(--accent2);font-size:.85rem;font-weight:700;font-family:inherit;cursor:pointer">
              Katıl
            </button>
          </div>
          <div style="text-align:center;font-size:.74rem;color:rgba(255,255,255,.3);margin:10px 0">veya</div>
        </div>
        <button onclick="createParty()" style="width:100%;padding:11px;border-radius:12px;border:none;background:linear-gradient(135deg,#ff2d7d,#ff6b6b);color:#fff;font-size:.88rem;font-weight:700;cursor:pointer">
          <i class="bi bi-plus-lg"></i> Yeni Oda Oluştur
        </button>
      </div>
      <div id="party-room-view" style="display:none">
        <div style="text-align:center;margin-bottom:16px">
          <div style="font-size:.78rem;color:rgba(255,255,255,.4);margin-bottom:6px">Oda Kodu</div>
          <div id="party-room-code" style="font-size:2rem;font-weight:900;letter-spacing:.2em;color:#ff2d7d;cursor:pointer" onclick="copyRoomCode()" title="Kopyala"></div>
          <div style="font-size:.72rem;color:rgba(255,255,255,.3);margin-top:4px">Kopyalamak için tıkla</div>
        </div>
        <div id="party-members-list" style="display:flex;flex-wrap:wrap;gap:8px;margin-bottom:16px;min-height:40px"></div>
        <button onclick="leaveParty()" style="width:100%;padding:9px;border-radius:10px;border:1px solid rgba(255,80,80,.3);background:rgba(255,80,80,.08);color:#ff5050;font-size:.84rem;font-weight:700;cursor:pointer">
          <i class="bi bi-box-arrow-right"></i> Odadan Çık
        </button>
      </div>
    </div>
  </div>
</div>
@endauth

@endsection

{{-- Tracking meta tags --}}
<meta name="track-anime-id"   content="{{ $anime->id }}">
<meta name="track-episode-id" content="{{ $ep->id }}">

@push('scripts')
<script src="https://cdn.jsdelivr.net/npm/hls.js@1.5.13/dist/hls.min.js" onerror="window._hlsLoadFailed=true"></script>
@if(!empty($adsConfig['enabled']) && !empty($adsConfig['vast_url']))
<script src="https://imasdk.googleapis.com/js/sdkloader/ima3.js"></script>
@endif
<script>
console.log('[Animexe Player] v3 loaded');
const M3U8    = @json($ep->m3u8_url);
const MP4     = @json($ep->video_url);
const IS_AUTH = {{ auth()->check() ? 'true' : 'false' }};

// ── Referer'sız doğrudan yükleme politikası ────────────────────────────────────
// Anizium CDN'i: Referer=animexe.com → 403, ama Referer YOK → 200 (+ CORS animexe.com'a açık).
// Bu yüzden tüm alt-istekler referer'sız gitmeli. Sunucu proxy'sine (IP bloklu → 502) gerek kalmaz.
(function(){
    try {
        var m = document.createElement('meta');
        m.name = 'referrer'; m.content = 'no-referrer';
        (document.head || document.documentElement).appendChild(m);
    } catch(e) {}
})();

// CORS açık CDN'ler — doğrudan tarayıcıdan yükle (sunucu proxy YOK).
// Anizium mirror'ları animexe.com'a CORS izni veriyor + referer'sız 200 dönüyor.
const DIRECT_CORS_HOSTS = [
    'anizium.co',
    'aniziumserver.sbs', 'aniziumserver.site', 'aniziumserver.com',
    'misakina.asia', 'misakina.cfd',
    'irtau1.online',
    'tsuriko-1.asia', 'tsuriko-2.asia', 'tsuriko-3.asia',
    'rhyzoku-2.asia', 'rhyzoku-4.asia',
    'kamadotanjiro.asia', 'uryuishida.asia',
    'tohru.icu', 'tohru.cyou',
    'zappy-net.store', 'pixel-quirk.shop', 'tau-video.xyz',
];

// Referer gereken (CORS kapalı) CDN'ler için son çare sunucu proxy'si
const KNOWN_REFS = {
    'aniziumserver.sbs':  'https://anizium.co/',
    'aniziumserver.site': 'https://anizium.co/',
    'aniziumserver.com':  'https://anizium.co/',
};

// Sunucu-proxy'sine sarılmış URL'yi çöz (gerçek CDN URL'sini çıkar)
function _unwrapProxy(url) {
    try {
        var m = url.match(/\/(?:stream\/proxy|cf-proxy)\?u=([^&]+)/);
        if (m) { return atob(decodeURIComponent(m[1])); }
        m = url.match(/\/hls-proxy\.php\?(?:.*&)?url=([^&]+)/);
        if (m) { return decodeURIComponent(m[1]); }
    } catch(e) {}
    return url;
}

function proxyUrl(url) {
    if (!url) return url;
    try {
        // Sunucu proxy'sine sarılmışsa aç — doğrudan CDN'e gitmeyi dene
        var wrapped = url.indexOf('/stream/proxy') !== -1
                   || url.indexOf('/hls-proxy.php') !== -1
                   || url.indexOf('/cf-proxy') !== -1;
        var real = wrapped ? _unwrapProxy(url) : url;

        var host;
        try { host = new URL(real, location.origin).hostname; } catch(e) { return url; }

        // Kendi origin / CDN → dokunma
        if (host.endsWith('animexe.com') || host.endsWith('b-cdn.net') || host === location.hostname) return real;

        // CORS açık CDN → DOĞRUDAN (no-referrer meta sayesinde 200)
        if (DIRECT_CORS_HOSTS.some(function(d){ return host === d || host.endsWith('.' + d); })) return real;

        // Zaten sarılmış ama bilinmeyen host → sunucu proxy'sini koru
        if (wrapped) return url;

        // Sarılmamış dış URL, referer gereken CDN → sunucu proxy'si (son çare)
        var ref = (Object.entries(KNOWN_REFS).find(function(e){ return host.endsWith(e[0]); }) || [null,''])[1];
        if (ref) return '/hls-proxy.php?ref=' + encodeURIComponent(ref) + '&url=' + encodeURIComponent(real);
        return real; // referer gerekmiyorsa doğrudan dene
    } catch(e) { return url; }
}
const SUBS = @json($subtitlesData);
const VIDEO_SOURCES = @json($videoSourcesData ?? []);

// ── Reklam (VAST / IMA) ───────────────────────────────────────────────────────
@if(!empty($adsConfig['enabled']) && !empty($adsConfig['vast_url']))
(function initAds() {
    const VAST_URL      = @json($adsConfig['vast_url']);
    const FREQ_EPISODES = @json($adsConfig['freq_episodes']);
    const FREQ_MS       = @json($adsConfig['freq_minutes']) * 60 * 1000;
    const LS_KEY        = 'axe_ad';

    function _adState() {
        try { return JSON.parse(localStorage.getItem(LS_KEY)) || {}; } catch { return {}; }
    }
    function _saveState(s) {
        try { localStorage.setItem(LS_KEY, JSON.stringify(s)); } catch {}
    }

    // Önce mevcut durumu oku (tick'ten ÖNCE)
    const _state = _adState();
    const _now   = Date.now();

    // Bölüm sayacını artır ve kaydet
    _state.epsSinceLast = (_state.epsSinceLast || 0) + 1;
    _saveState(_state);

    // Frekans kontrolü (tick sonrası değerle)
    const _lastShown = _state.lastShown || 0;
    if ((_now - _lastShown) < FREQ_MS) return;             // dakika limiti dolmadı
    if (_state.epsSinceLast < FREQ_EPISODES) return;       // bölüm limiti dolmadı

    // IMA SDK yüklü değilse (adblocker vb.) sessizce geç
    if (typeof google === 'undefined' || !google.ima) return;

    const adContainer = document.getElementById('ad-container');
    if (!adContainer) return;

    let adsManager, adDisplayContainer, adsLoader;
    let _adStarted = false;

    // Güvenlik: IMA 8 saniyede cevap vermezse videoyu başlat
    const _fallbackTimer = setTimeout(() => {
        if (!_adStarted) { _adError(); }
    }, 8000);

    function _startMainVideo() {
        clearTimeout(_fallbackTimer);
        window._imaAdPending = false;
        if (typeof startPlayer === 'function') startPlayer();
    }

    function _adDone() {
        adContainer.style.display = 'none';
        try { adsManager && adsManager.destroy(); } catch {}
        _saveState({ lastShown: Date.now(), epsSinceLast: 0 });
        _startMainVideo();
    }

    function _adError() {
        adContainer.style.display = 'none';
        try { adsManager && adsManager.destroy(); } catch {}
        _startMainVideo();
    }

    function _onAdsLoaded(e) {
        _adStarted = true;
        adsManager = e.getAdsManager(document.getElementById('vd'));
        adsManager.addEventListener(google.ima.AdEvent.Type.COMPLETE,          _adDone);
        adsManager.addEventListener(google.ima.AdEvent.Type.SKIPPED,           _adDone);
        adsManager.addEventListener(google.ima.AdEvent.Type.ALL_ADS_COMPLETED, _adDone);
        adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR,     _adError);
        // Reklam başlarken ana videoyu durdur (IMA standart CONTENT_PAUSE_REQUESTED)
        adsManager.addEventListener(google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, () => {
            const v = document.getElementById('vd');
            if (v && !v.paused) v.pause();
        });
        try {
            adContainer.style.display = 'block';
            const w = adContainer.offsetWidth  || window.innerWidth  || 640;
            const h = adContainer.offsetHeight || window.innerHeight || 360;
            adsManager.init(w, h, google.ima.ViewMode.NORMAL);
            adsManager.start();
        } catch { _adError(); }
    }

    adDisplayContainer = new google.ima.AdDisplayContainer(adContainer, document.getElementById('vd'));
    adDisplayContainer.initialize();

    adsLoader = new google.ima.AdsLoader(adDisplayContainer);
    adsLoader.addEventListener(google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, _onAdsLoaded);
    adsLoader.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, _adError);

    const req = new google.ima.AdsRequest();
    req.adTagUrl = VAST_URL;
    req.linearAdSlotWidth  = window.innerWidth  || 640;
    req.linearAdSlotHeight = window.innerHeight || 360;
    adsLoader.requestAds(req);

    window._imaAdPending = true;
})();
@endif

// ── Kendi MP4 Pre-roll Reklam Sistemi ────────────────────────────────────────
@if(!empty($vadConfig['mode']))
(function initVideoAd() {
    const CFG    = @json($vadConfig);
    const LS_KEY = 'axe_vad';

    function _st()      { try { return JSON.parse(localStorage.getItem(LS_KEY)) || {}; } catch { return {}; } }
    function _save(s)   { try { localStorage.setItem(LS_KEY, JSON.stringify(s)); } catch {} }

    // Frekans kontrolü: N bölümde 1 + M dakikada max 1
    const state = _st();
    state.epsSinceLast = (state.epsSinceLast || 0) + 1;
    _save(state);

    const now = Date.now();
    if ((now - (state.lastShown || 0)) < CFG.freq_minutes * 60 * 1000) return;
    if (state.epsSinceLast < CFG.freq_episodes) return;

    // Reklam gösterilecek — ana videoyu ve introyu beklet
    window._imaAdPending = true;

    const vw = document.getElementById('vw');
    if (!vw) { window._imaAdPending = false; return; }

    function _markShown() { _save({ lastShown: Date.now(), epsSinceLast: 0 }); }

    function _vadDone() {
        _markShown();
        document.getElementById('vad-overlay')?.remove();
        window._imaAdPending = false;
        // Intro varsa önce intro, yoksa direkt ana video
        if (typeof INTRO_URL !== 'undefined' && INTRO_URL) {
            const iv = document.getElementById('intro-vd');
            if (iv) {
                iv.play().catch(() => { iv.muted = true; iv.play().catch(() => window.skipIntro?.()); });
                return;
            }
        }
        if (typeof startPlayer === 'function') startPlayer();
    }

    function _beacon(path) {
        try { fetch(path, { method: 'POST', keepalive: true }).catch(() => {}); } catch {}
    }

    // Reklam/upsell overlay stilleri — mobil uyumlu (bir kez enjekte)
    function _injectVadStyle() {
        if (document.getElementById('vad-style')) return;
        document.head.insertAdjacentHTML('beforeend', `<style id="vad-style">
        .vad-card{margin:auto;max-width:420px;width:100%;text-align:center;background:linear-gradient(160deg,#1a1035,#0d0a20);border:1px solid rgba(167,139,250,.35);border-radius:18px;padding:30px 26px;box-shadow:0 20px 60px rgba(0,0,0,.6)}
        .vad-emoji{font-size:40px;margin-bottom:10px;line-height:1}
        .vad-title{font-size:19px;font-weight:800;color:#fff;margin-bottom:8px}
        .vad-desc{font-size:13px;color:#b8b3d9;line-height:1.55;margin-bottom:20px}
        .vad-btn-premium{display:block;background:linear-gradient(90deg,#8b5cf6,#6d28d9);color:#fff;font-weight:700;font-size:14.5px;padding:13px;border-radius:10px;text-decoration:none;margin-bottom:10px}
        .vad-btn-skip{width:100%;background:rgba(255,255,255,.07);color:#8f8ab0;border:1px solid rgba(255,255,255,.12);font-size:14px;font-weight:600;padding:12px;border-radius:10px;cursor:not-allowed}
        .vad-btn-skip.ready{background:rgba(255,255,255,.16);color:#fff;cursor:pointer}
        .vad-bar{position:absolute;left:0;right:0;bottom:0;min-height:56px;background:linear-gradient(transparent,rgba(0,0,0,.8));display:flex;align-items:center;justify-content:space-between;gap:10px;padding:8px 14px;z-index:1}
        .vad-cta{color:#c4b5fd;font-size:12.5px;font-weight:600;text-decoration:none;flex:0 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
        .vad-skip{flex:0 0 auto;background:rgba(255,255,255,.14);color:#cfcbe8;border:1px solid rgba(255,255,255,.25);font-size:13px;font-weight:700;padding:9px 16px;border-radius:8px;cursor:not-allowed;white-space:nowrap}
        .vad-skip.ready{background:rgba(255,255,255,.24);color:#fff;cursor:pointer}
        @media (max-width:480px){ .vad-cta{font-size:11px} .vad-skip{padding:8px 12px;font-size:12px} }
        @media (max-width:360px){ .vad-cta{display:none} }
        @media (max-height:560px){
          .vad-card{padding:16px 18px;border-radius:14px}
          .vad-emoji{font-size:26px;margin-bottom:4px}
          .vad-title{font-size:15px;margin-bottom:5px}
          .vad-desc{font-size:11.5px;line-height:1.4;margin-bottom:12px}
          .vad-btn-premium{padding:10px;font-size:13px;margin-bottom:7px}
          .vad-btn-skip{padding:9px;font-size:13px}
        }
        @media (max-width:420px){ .vad-card{padding:20px 16px} }
        </style>`);
    }

    // ── Upsell modu: reklam yerine premium teklifi ────────────────────────────
    if (CFG.mode === 'upsell') {
        _injectVadStyle();
        vw.insertAdjacentHTML('beforeend', `
        <div id="vad-overlay" class="vad-ov-upsell" style="position:absolute;inset:0;z-index:60;background:rgba(5,5,16,.96);display:flex;overflow-y:auto;padding:16px">
          <div class="vad-card">
            <div class="vad-emoji">👑</div>
            <div class="vad-title">Reklamsız İzlemek İster misin?</div>
            <div class="vad-desc">
              Premium üyelikle hiç reklam görmeden, kesintisiz anime izlersin.
              Üstelik özel rozetler ve daha fazlası seni bekliyor.
            </div>
            <a href="${CFG.premium_url}" class="vad-btn-premium">👑 Premium'a Geç</a>
            <button id="vad-skip" class="vad-btn-skip" disabled>Devam Et (5)</button>
          </div>
        </div>`);

        const skipBtn = document.getElementById('vad-skip');
        let left = 5;
        const t = setInterval(() => {
            left--;
            if (left <= 0) {
                clearInterval(t);
                skipBtn.textContent = 'Devam Et ▶';
                skipBtn.disabled = false;
                skipBtn.classList.add('ready');
                skipBtn.onclick = _vadDone;
            } else {
                skipBtn.textContent = `Devam Et (${left})`;
            }
        }, 1000);
        return;
    }

    // ── Reklam modu: MP4 pre-roll ─────────────────────────────────────────────
    _injectVadStyle();
    const AD = CFG.ad;
    vw.insertAdjacentHTML('beforeend', `
    <div id="vad-overlay" style="position:absolute;inset:0;z-index:60;background:#000">
      <video id="vad-vd" src="${AD.url}" playsinline webkit-playsinline preload="auto"
             style="width:100%;height:100%;object-fit:contain;display:block"></video>
      ${AD.click_url ? `<a id="vad-click" href="${AD.click_url}" target="_blank" rel="noopener sponsored" style="position:absolute;inset:0 0 64px 0;display:block"></a>` : ''}
      <div style="position:absolute;top:10px;left:10px;background:rgba(0,0,0,.65);color:#ffd60a;font-size:11px;font-weight:700;letter-spacing:.08em;padding:4px 10px;border-radius:6px;pointer-events:none">REKLAM</div>
      <button id="vad-unmute" style="display:none;position:absolute;top:10px;right:10px;background:rgba(0,0,0,.65);color:#fff;border:1px solid rgba(255,255,255,.25);font-size:12.5px;font-weight:600;padding:7px 12px;border-radius:8px;cursor:pointer">🔊 Sesi Aç</button>
      <div class="vad-bar">
        <a href="${CFG.premium_url}" class="vad-cta">👑 Premium'a geç, reklamsız izle</a>
        <button id="vad-skip" class="vad-skip" disabled>Reklamı Geç (${AD.skip_after})</button>
      </div>
      <div id="vad-prog" style="position:absolute;left:0;bottom:0;height:3px;width:0%;background:#ffd60a;pointer-events:none;z-index:2"></div>
    </div>`);

    const adVd    = document.getElementById('vad-vd');
    const skipBtn = document.getElementById('vad-skip');
    const unmute  = document.getElementById('vad-unmute');
    const prog    = document.getElementById('vad-prog');
    const clickEl = document.getElementById('vad-click');
    let _impSent = false, _skipReady = false, _finished = false;

    function _finish() {
        if (_finished) return;
        _finished = true;
        try { adVd.pause(); } catch {}
        _vadDone();
    }

    // Güvenlik: 10 sn içinde oynamaya başlamazsa reklamı atla
    const _loadTimeout = setTimeout(() => { if (!_impSent) _finish(); }, 10000);

    adVd.addEventListener('playing', () => {
        clearTimeout(_loadTimeout);
        if (!_impSent) { _impSent = true; _beacon(`/api/slot/${AD.id}/view`); }
    });

    adVd.addEventListener('timeupdate', () => {
        if (adVd.duration > 0) prog.style.width = (adVd.currentTime / adVd.duration * 100) + '%';
        if (!_skipReady && AD.skip_after > 0) {
            const left = Math.ceil(AD.skip_after - adVd.currentTime);
            if (left <= 0) {
                _skipReady = true;
                skipBtn.textContent = 'Reklamı Geç ▶';
                skipBtn.disabled = false;
                skipBtn.classList.add('ready');
                skipBtn.onclick = _finish;
            } else {
                skipBtn.textContent = `Reklamı Geç (${left})`;
            }
        }
    });

    // skip_after = 0 → geç butonu hiç aktifleşmez, reklam sonuna kadar izlenir
    if (AD.skip_after <= 0) skipBtn.style.display = 'none';

    adVd.addEventListener('ended', _finish);
    adVd.addEventListener('error', _finish);

    if (clickEl) clickEl.addEventListener('click', () => _beacon(`/api/slot/${AD.id}/hit`));

    // Otomatik oynat — ses engellenirse sessiz başlat + "Sesi Aç" göster
    adVd.play().catch(() => {
        adVd.muted = true;
        unmute.style.display = 'block';
        unmute.onclick = () => { adVd.muted = false; unmute.style.display = 'none'; };
        adVd.play().catch(_finish);
    });
})();
@endif

// ── H.265 uyumluluk (global) ──────────────────────────────────────────────────
const _hevcOk = typeof MediaSource !== 'undefined' && [
    'video/mp4; codecs="hev1.1.6.L120.90"',
    'video/mp4; codecs="hvc1.1.6.L120.90"',
    'video/mp4; codecs="hev1.1.4.L120.90"',
    'video/mp4; codecs="hvc1.1.4.L120.90"',
    'video/mp4; codecs="hev1"',
    'video/mp4; codecs="hvc1"',
].some(ct => MediaSource.isTypeSupported?.(ct));

async function _probeIsHevcOnly(url) {
    try {
        url = (typeof proxyUrl === 'function') ? proxyUrl(url) : url; // sarılmışsa doğrudan CDN'e
        const ctrl = typeof AbortSignal !== 'undefined' && AbortSignal.timeout
            ? AbortSignal.timeout(6000) : undefined;
        const opts = { referrerPolicy: 'no-referrer' };
        if (ctrl) opts.signal = ctrl;
        const r = await fetch(url, opts);
        if (!r.ok) return false;
        const txt = await r.text();
        const streams = [...txt.matchAll(/#EXT-X-STREAM-INF:([^\n]+)/g)];
        if (!streams.length) return false;
        const _isHevc = c => /hev1|hvc1|dvh1/i.test(c || '');
        // H.264 stream var mı? (CODECS etiketi yoksa bilinmiyor → güvenli say)
        const hasH264 = streams.some(m => {
            const codecs = (m[1].match(/CODECS="([^"]+)"/) || [])[1] || '';
            return !codecs || !_isHevc(codecs);
        });
        return !hasH264;
    } catch { return false; }
}

function _reportHevcSource(url) {
    if (!url) return;
    const csrfToken = document.querySelector('meta[name=csrf-token]')?.content || '';
    fetch('/api/sources/flag-hevc', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken },
        body: JSON.stringify({ url }),
        keepalive: true,
    }).catch(() => {});
}

(async function _filterHevcSources() {
    if (_hevcOk) return; // tarayıcı H.265 destekliyor, filtreleme gerekmez
    const btns = document.querySelectorAll(
        '.vmi-dub[data-url], .src-tab[data-url], .vmi-src[data-url]'
    );
    for (const btn of btns) {
        const url = btn.dataset.url;
        if (!url || !url.includes('.m3u8')) continue;
        const hevcOnly = await _probeIsHevcOnly(url);
        if (hevcOnly) {
            btn.style.display = 'none';
            btn.classList.remove('on');
            _reportHevcSource(url); // admin paneline raporla
        }
    }
})();

// ── Loading screen ────────────────────────────────────────────────────────────
(function(){
    const bg = document.getElementById('vload-bg');
    const coverUrl = @json($ep->thumbnailUrl ?: ($anime->coverUrl ?? null));
    if (bg && coverUrl) bg.style.backgroundImage = 'url(' + coverUrl + ')';
})();

const _TIPS = [
    '💡 Sol/sağ ok tuşları ile 5 sn ileri/geri sar',
    '⌨️ J ve L tuşları 10 sn ileri/geri sarmak için',
    '🎧 M tuşu ile sesi kapat/aç',
    '🖥️ F tuşu veya çift tıkla tam ekrana geç',
    '📺 Ayarlar menüsünden video kalitesini değiştirebilirsin',
    '⏸️ Boşluk tuşu ile durdur / devam et',
    '🔊 Yukarı/aşağı ok tuşları ses seviyesini ayarlar',
    '💾 Kaldığın yerden devam etmek için giriş yap',
    '🎯 İzleme geçmişin otomatik kaydediliyor',
    '⭐ Beğendiğin bölümlere yorum bırakmayı unutma',
    '🎮 Birlikte İzle özelliğiyle arkadaşlarınla izle',
    '🔔 Favori animeler yeni bölüm gelince seni bilgilendirir',
    '🌙 Geceleri ses yüksekliğini düşük tut, komşuları düşün 😄',
    '🎬 Bölüm bittikten sonra Ruh Hali Motoru ile sonra ne izleyeceğini seç',
];
let _tipIdx = Math.floor(Math.random() * _TIPS.length);
let _tipTimer = null, _tipDelayTimer = null;
const _vloadTipEl = document.getElementById('vload-tip');
const _vloadEl = document.getElementById('vload');
const _vloadPlayBtn = document.getElementById('vload-playbtn');
let _vloadFirstPlay = false; // ilk playing eventi sonrası vload kalıcı kapanır

function _showNextTip() {
    if (!_vloadTipEl) return;
    _vloadTipEl.classList.add('fade');
    setTimeout(() => {
        _vloadTipEl.textContent = _TIPS[_tipIdx % _TIPS.length];
        _vloadTipEl.classList.remove('fade');
        _tipIdx++;
    }, 350);
}

const _vloadRetryBtn = document.getElementById('vload-retrybtn');
let _vloadRetryTimer = null;

function showVload() {
    if (!_vloadEl) return;
    _vloadEl.style.display = ''; // hideVload tarafından gizlenmiş olabilir
    _vloadFirstPlay = false;
    _vloadEl.classList.add('on');
    // Label'ı "Yükleniyor"a geri döndür (_showVloadPlayBtn "Oynatmaya hazır" yapmış olabilir)
    const _lbl = document.querySelector('.vload-lbl');
    if (_lbl) _lbl.innerHTML = 'Yükleniyor<span class="vload-ldots"></span>';
    if (_vloadPlayBtn) _vloadPlayBtn.classList.remove('show');
    if (_vloadRetryBtn) _vloadRetryBtn.classList.remove('show');
    // İpuçları yükleme uzarsa (>1.2s) göster
    clearTimeout(_tipDelayTimer);
    clearInterval(_tipTimer);
    clearTimeout(_vloadRetryTimer);
    _tipDelayTimer = setTimeout(() => {
        _showNextTip();
        _tipTimer = setInterval(_showNextTip, 3800);
    }, 1200);
    // 12s sonra hâlâ yükleniyorsa "Yenile" butonu göster
    _vloadRetryTimer = setTimeout(() => {
        if (_vloadEl.classList.contains('on') && _vloadRetryBtn) {
            _vloadRetryBtn.classList.add('show');
        }
    }, 12000);
}

function hideVload() {
    if (!_vloadEl || _vloadFirstPlay) return;
    _vloadFirstPlay = true;
    _vloadEl.classList.remove('on');
    // Transition tamamlanmayabilir — 420ms sonra display:none ile garantile
    setTimeout(() => { if (_vloadEl && !_vloadEl.classList.contains('on')) _vloadEl.style.display = 'none'; }, 420);
    clearTimeout(_tipDelayTimer);
    clearInterval(_tipTimer);
    clearTimeout(_vloadRetryTimer);
    if (_vloadRetryBtn) _vloadRetryBtn.classList.remove('show');
}

function _showVloadPlayBtn() {
    // Unmute chip varsa kaldır — zaten "tıkla" butonu var
    hideUnmute();
    // "Yükleniyor" yanılgısını kır: kaynak hazır, sadece autoplay engeli var
    const _lbl = document.querySelector('.vload-lbl');
    if (_lbl) _lbl.innerHTML = 'Oynatmaya hazır';
    clearTimeout(_tipDelayTimer); clearInterval(_tipTimer);
    if (_vloadTipEl) _vloadTipEl.textContent = '';
    if (_vloadPlayBtn) _vloadPlayBtn.classList.add('show');
}

function _vloadPlay() {
    if (_vloadPlayBtn) _vloadPlayBtn.classList.remove('show');
    // Sessizi kaldırarak dene, olmazsa sesli olmadan devam et
    vd.muted = false;
    vd.play()
        .then(hideVload)
        .catch(() => {
            vd.muted = true;
            vd.play()
                .then(() => { hideVload(); showUnmute(); })
                .catch(() => { _vloadPlayBtn?.classList.add('show'); });
        });
}
const HAS_NXT = @json((bool)$next);
const NXT_URL = @json($nextUrl);

// ─── Intro video ──────────────────────────────────────────────────────────────
const INTRO_URL        = @json($introUrl);        // null ise intro yok
const INTRO_SKIP_AFTER = @json($introSkipAfter);  // kaç saniye sonra skip butonu çıkar
const MAIN_SKIP_SEC    = @json($mainVideoSkipSec); // ana videoda kaç saniye atlanacak
const WM_COVER_SECS   = @json($wmCoverSeconds);   // rakip watermark kaç saniye kapalı kalacak
let ANISKIP = @json($aniSkip ?? null);  // {op:{start,end}, ed:{start,end}} veya null — also fetched async below
// debug: console'dan kontrol: window._introDebug
window._introDebug = { ANISKIP, ep_intro_start: @json($ep->intro_start ?? null), ep_intro_end: @json($ep->intro_end ?? null) };

(function initIntro() {
    if (!INTRO_URL) return;
    const overlay  = document.getElementById('intro-overlay');
    const introVd  = document.getElementById('intro-vd');
    const skipBtn  = document.getElementById('intro-skip');
    const timerEl  = document.getElementById('intro-timer');
    if (!overlay || !introVd) return;

    let skipCountdown = null;

    function skipIntro() { // global da tanımlı
        introVd.pause();
        overlay.classList.add('hidden');
        clearInterval(skipCountdown);
        startMainVideo();
    }
    window.skipIntro = skipIntro;

    // Skip butonu geri sayımı
    let remaining = INTRO_SKIP_AFTER;
    if (remaining <= 0) {
        skipBtn.classList.add('visible');
        timerEl.textContent = '';
    } else {
        timerEl.textContent = '(' + remaining + ')';
        skipCountdown = setInterval(() => {
            remaining--;
            if (remaining <= 0) {
                clearInterval(skipCountdown);
                skipBtn.classList.add('visible');
                timerEl.textContent = '';
            } else {
                timerEl.textContent = '(' + remaining + ')';
            }
        }, 1000);
    }

    // Intro bitti → ana video başlat
    introVd.addEventListener('ended', skipIntro);
    introVd.addEventListener('error', skipIntro); // yüklenemezse geç

    // Intro'yu otomatik oynat — reklam bekliyorsa reklam bitince başlatılır (_vadDone)
    if (!window._imaAdPending) {
        introVd.play().catch(() => {
            introVd.muted = true;
            introVd.play().catch(skipIntro);
        });
    }
})();

function startMainVideo() {
    if (window._imaAdPending) return;
    _mainSkipSec = MAIN_SKIP_SEC;
    applyDubPref();
}

let _mainSkipSec = 0; // intro geçildikten sonra ana videoda atlanacak süre

// ─── HLS setup ────────────────────────────────────────────────────────────────
const vd = document.getElementById('vd');
let hls = null;

function loadHLS(url, seekTo = 0, onFail = null) {
    if (window._imaAdPending) return;

    // HLS.js CDN'den yüklenemedi — kullanıcıya hata göster
    if (window._hlsLoadFailed || typeof Hls === 'undefined') {
        showVload();
        // Native HLS (Safari/iOS) destekliyorsa yine de dene
        if (url && vd.canPlayType('application/vnd.apple.mpegurl')) {
            vd.src = url;
            vd.play().catch(_showVloadPlayBtn);
            return;
        }
        hideVload();
        showNoVideo();
        showToast('Video oynatıcı yüklenemedi. Sayfayı yenileyin veya reklam engelleyicinizi kapatın.', 8000);
        return;
    }

    const _rawUrl = url; // Proxy öncesi orijinal URL (CORS hatasında retry için)
    url = proxyUrl(url);
    // Doğrudan CDN yüklemesi mi? (kendi origin'imiz değil = cross-origin CDN'e direkt gidiyoruz)
    let _isDirect = false;
    try { _isDirect = url.indexOf('http') === 0 && new URL(url).hostname !== location.hostname; } catch(e) {}
    vd.pause(); // Ses bozulmasını önle — destroy öncesi durdur
    if (hls) { hls.destroy(); hls = null; }
    // MediaSource'u tam sıfırla — önceki bufferAppendError (HEVC) SourceBuffer'ı
    // bozuk bırakmış olabilir; temizlemezsek sonraki (çalışan) kaynak da patlar.
    try {
        vd.pause();
        vd.removeAttribute('src');
        while (vd.firstChild) vd.removeChild(vd.firstChild);
        vd.load(); // networkState=EMPTY, eski MediaSource bırakılır
    } catch(e) {}
    document.getElementById('q-levels').innerHTML = '';
    const qLab = document.querySelector('#q-auto span:last-child');
    if (qLab) qLab.textContent = 'Otomatik';

    if (!url) { showNoVideo(); return; }

    vd.style.display = ''; // showNoVideo() tarafından gizlenmiş olabilir — sıfırla
    const noVidBox = document.getElementById('no-video-msg');
    if (noVidBox) noVidBox.style.display = 'none';

    showVload(); // ← Yükleme başlıyor, hemen loading screen göster

    // Seek helper — video src değişince loadedmetadata'da uygula
    function _seekAndPlay() {
        if (seekTo > 0) vd.currentTime = seekTo;
        vd.play().catch(() => {
            vd.muted = true;
            vd.play().catch(_showVloadPlayBtn);
            showUnmute();
        });
    }
    function _seekAfterMeta(playFn) {
        if (seekTo > 0) {
            vd.addEventListener('loadedmetadata', function onMeta() {
                vd.removeEventListener('loadedmetadata', onMeta);
                vd.currentTime = seekTo;
                (playFn || (() => {}))();
            });
        } else {
            (playFn || (() => {}))();
        }
    }

    if (Hls.isSupported()) {
        hls = new Hls({
            startPosition: seekTo > 0 ? seekTo : -1,
            startFragPrefetch: true,
            maxBufferLength: 20,
            maxMaxBufferLength: 300,
            enableWorker: true,
            manifestLoadingTimeOut: 8000,
            // Direct CDN denemesinde CORS hatasında anında proxy'e geç (0 retry)
            // Proxy URL'inde transient hatalar için 2 retry tut
            manifestLoadingMaxRetry: _isDirect ? 0 : 2,
            levelLoadingTimeOut: 8000,
            levelLoadingMaxRetry: _isDirect ? 0 : 2,
            fragLoadingTimeOut: 15000,
            fragLoadingMaxRetry: 3,
            nudgeMaxRetry: 5,
            xhrSetup: function(xhr) { xhr.withCredentials = false; },
        });
        hls.loadSource(url);
        hls.attachMedia(vd);

        const _thisHls = hls; // race-guard: stale timers/callbacks check this
        const _hlsTimeout = setTimeout(() => {
            if (hls !== _thisHls) return; // newer loadHLS already took over
            hls.destroy(); hls = null;
            hideVload();
            if (onFail) onFail(); else showNoVideo();
        }, 15000);

        hls.on(Hls.Events.MANIFEST_PARSED, (_, d) => {
            clearTimeout(_hlsTimeout);

            // ── Codec uyumluluk filtresi ────────────────────────────────────
            const _isHevc = c => /hev1|hvc1|dvh1|hvc/i.test(c || '');

            if (!_hevcOk) {
                const h264Levels = d.levels.filter(l => !_isHevc(l.attrs?.CODECS));
                if (h264Levels.length === 0) {
                    // H.264 level yok — yine de oynamayı dene.
                    // Chrome 108+ hardware HEVC destekleyebilir (MediaSource.isTypeSupported
                    // yanlış false döner). Gerçekten oynatılamazsa bufferAppendError gelir.
                    console.warn('[HLS] HEVC-only stream, hardware decode deneniyor...');
                } else if (h264Levels.length < d.levels.length) {
                    // Bazı level'lar HEVC — en iyi H.264'ü seç, auto-switch kapat
                    let bestH264 = 0, bestBw = 0;
                    d.levels.forEach((l, i) => { if (!_isHevc(l.attrs?.CODECS) && l.bitrate > bestBw) { bestBw = l.bitrate; bestH264 = i; } });
                    hls.currentLevel = bestH264;
                    hls.autoLevelEnabled = false;
                }
            }
            // ────────────────────────────────────────────────────────────────

            // startPosition HLS config'de set edildi — burada tekrar currentTime set etme,
            // ikisi çakışınca video başa atlıyor
            // Autoplay: önce sesli, engellenirse sessiz, o da olmazsa tıkla-oynat butonu.
            vd.play().catch(() => {
                vd.muted = true;
                vd.play()
                    .then(showUnmute)
                    .catch(_showVloadPlayBtn);
            });

            // Video oynatılabilir hale gelince (buffer doldu) ama hâlâ duruyorsa →
            // autoplay engeli. Sessiz oynatmayı dene, olmazsa DERHAL buton göster (failover YOK).
            vd.addEventListener('canplay', function _cpAuto() {
                vd.removeEventListener('canplay', _cpAuto);
                if (_vloadFirstPlay || hls !== _thisHls) return;
                if (vd.paused) {
                    vd.muted = true;
                    vd.play().then(showUnmute).catch(_showVloadPlayBtn);
                }
            });

            // Stuck watchdog: buffer VARSA (readyState>=2) autoplay engelidir → buton göster,
            // failover YAPMA (kaynak sağlam). Hiç veri yoksa gerçek stall/codec → sıradakine geç.
            const _playStuck = setTimeout(() => {
                if (_vloadFirstPlay || hls !== _thisHls) return;
                if (vd.readyState >= 2) {
                    // Video hazır ama oynamıyor = autoplay bloğu. Son bir sessiz deneme + buton.
                    vd.muted = true;
                    vd.play().then(showUnmute).catch(() => {});
                    _showVloadPlayBtn();
                    return;
                }
                // Hiç veri yüklenmedi — gerçek sorun, sonraki kaynağa geç
                setTimeout(() => {
                    if (!_vloadFirstPlay && hls === _thisHls && vd.readyState < 2) {
                        hls?.destroy(); hls = null;
                        hideVload();
                        if (onFail) onFail(); else _showVloadPlayBtn();
                    } else if (!_vloadFirstPlay && vd.readyState >= 2) {
                        _showVloadPlayBtn();
                    }
                }, 3000);
            }, 5000);
            vd.addEventListener('playing', () => clearTimeout(_playStuck), { once: true });

            const lvls = document.getElementById('q-levels');
            lvls.innerHTML = '';
            document.querySelectorAll('#mnu-set .vmi[data-q]').forEach(e => e.classList.remove('on'));
            const qAuto = document.getElementById('q-auto');
            if (qAuto) { qAuto.classList.add('on'); }
            if (hls && hls.autoLevelEnabled) hls.currentLevel = -1;

            d.levels.forEach((l, i) => {
                const h = l.height || Math.round(l.width * 9/16);
                const isHevcLvl = _isHevc(l.attrs?.CODECS);
                const div = document.createElement('div');
                div.className = 'vmi' + (isHevcLvl && !_hevcOk ? ' disabled' : '');
                div.dataset.q = i;
                div.title = isHevcLvl ? 'H.265 — tarayıcı desteği yok' : '';
                div.innerHTML = `<span class="dot"></span><span>${h}p${isHevcLvl ? ' H.265' : (l.attrs?.CODECS?.includes('avc1')||h>=1080?' HD':'')}</span>`;
                if (!isHevcLvl || _hevcOk) div.onclick = () => doQuality(i, div);
                lvls.appendChild(div);
            });
        });

        let _hevcRecovered = false, _mediaRecovered = false, _netErrCount = 0, _mediaErrCount = 0;
        hls.on(Hls.Events.ERROR, (_, data) => {
            if (hls !== _thisHls) return; // stale event from a destroyed/replaced instance
            if (!data.fatal) {
                // Manifest hiç yüklenemiyorsa (proxy 502 / ölü mirror) tekrar deneme —
                // doğrudan failover ile sıradaki kaynağa geç (aynı URL'yi dövme).
                if (data.type === Hls.ErrorTypes.NETWORK_ERROR &&
                    (data.details === 'manifestLoadError' || data.details === 'manifestLoadTimeOut' ||
                     data.details === 'levelLoadError' || data.details === 'levelLoadTimeOut')) {
                    const _reUrl = hls.url, _reTime = vd.currentTime;
                    hls.destroy(); hls = null;
                    if (onFail) { onFail(); }
                    else { loadHLS(_reUrl, _reTime, showNoVideo); }
                    return;
                } else if (data.type === Hls.ErrorTypes.NETWORK_ERROR && _netErrCount < 3) {
                    // Segment (fragment) hatası: birkaç kez mevcut pozisyondan yüklemeyi dene
                    _netErrCount++;
                    setTimeout(() => { if (hls) hls.startLoad(); }, 800 * _netErrCount);
                } else if (data.type === Hls.ErrorTypes.NETWORK_ERROR) {
                    // 3 retry sonrası hâlâ segment hatası — failover ile sıradaki kaynağa geç
                    _netErrCount = 0;
                    const _reTime = vd.currentTime;
                    hls.destroy(); hls = null;
                    if (onFail) { onFail(); }
                    else { showNoVideo(); }
                    return;
                } else if (data.type === Hls.ErrorTypes.MEDIA_ERROR) {
                    // Non-fatal media hataları birikirse (codec sorun) → fatal gibi işle
                    _mediaErrCount++;
                    if (_mediaErrCount >= 4) {
                        data.fatal = true; // aşağıdaki fatal handler'a düş
                    } else {
                        return;
                    }
                } else {
                    return;
                }
            }
            if (!data.fatal) return;
            _netErrCount = 0;
            clearTimeout(_hlsTimeout);

            console.error('[HLS] Fatal:', data.type, data.details, data);

            // bufferAppendError = codec uyumsuzluğu (genelde H.265 → Chrome'da olmaz)
            if (data.details === 'bufferAppendError' || data.details === 'bufferAddCodecError') {
                // TEŞHİS: bu kaynağın gerçek codec'lerini yazdır (HEVC mi H.264 mü?)
                try {
                    const _codecs = (hls && hls.levels || []).map(l => (l.attrs && l.attrs.CODECS) || l.videoCodec || '?').join(', ');
                    console.warn('[HEVC-teşhis] Kaynak codecs:', _codecs || '(bilinmiyor)', '| _hevcOk:', _hevcOk);
                } catch(e) {}
                showVload(); // Siyah ekran yerine loading göster
                // Sadece bir kez H.264 level'a geçmeyi dene — tekrar gelirse direkt destroy
                if (!_hevcRecovered) {
                    const _isH265 = c => /hev1|hvc1|dvh1|hvc/i.test(c || '');
                    const levels = hls?.levels || [];
                    // Sadece CODECS açıkça belirtilmiş ve H.265 olmayan level'a geç
                    // CODECS bilinmiyorsa (undefined) → o da HEVC olabilir, deneme
                    const h264Idx = levels.findIndex(l => { const c = l.attrs?.CODECS || ''; return c && !_isH265(c); });
                    if (h264Idx >= 0) {
                        _hevcRecovered = true;
                        hls.currentLevel = h264Idx;
                        hls.autoLevelEnabled = false;
                        hls.recoverMediaError();
                        return;
                    }
                }
                hls.destroy(); hls = null;
                hideVload();
                // Bu oturumda hatırla + backend'e raporla (admin görsün, sonraki kullanıcı hızlı açsın)
                if (_rawUrl) _knownHevcUrls[_rawUrl] = 1;
                _reportHevcSource(_rawUrl);
                if (onFail) {
                    onFail();
                } else {
                    showToast('Bu video H.265 (HEVC) formatında — Chrome desteklemiyor. Başka kaynak deneyin.', 8000);
                    showNoVideo();
                }
                return;
            }

            // Media decode / buffer hatası → bir kez recoverMediaError dene
            if (data.type === Hls.ErrorTypes.MEDIA_ERROR && !_mediaRecovered) {
                _mediaRecovered = true;
                hls.recoverMediaError();
                return;
            }

            hls.destroy(); hls = null;

            // Doğrudan yükleme başarısız (CORS/network) → sunucu proxy'si IP-bloklu (502),
            // ona dönmek anlamsız. Doğrudan sıradaki kaynağa (failover) geç.
            hideVload();
            if (onFail) onFail(); else showNoVideo();
        });
    } else if (vd.canPlayType('application/vnd.apple.mpegurl') && url) {
        // Safari / iOS native HLS
        vd.src = url;
        _seekAfterMeta(() => vd.play().catch(() => { _showVloadPlayBtn(); }));
        document.getElementById('q-levels').innerHTML = '';
        document.querySelectorAll('#mnu-set .vmi[data-q]').forEach(e => e.classList.remove('on'));
        const qAuto = document.getElementById('q-auto');
        if (qAuto) { qAuto.classList.add('on'); qAuto.querySelector('span:last-child').textContent = 'Otomatik (cihaz)'; }
    } else if (MP4) {
        vd.src = MP4;
        _seekAfterMeta(() => vd.play().catch(() => { _showVloadPlayBtn(); }));
        document.getElementById('q-levels').innerHTML = '';
        document.querySelectorAll('#mnu-set .vmi[data-q]').forEach(e => e.classList.remove('on'));
        const qAuto = document.getElementById('q-auto');
        if (qAuto) { qAuto.classList.add('on'); qAuto.querySelector('span:last-child').textContent = 'Tek kalite (MP4)'; }
    }
}

function showNoVideo() {
    hideVload();
    const vdEl = document.getElementById('vd');
    if (vdEl) vdEl.style.display = 'none';
    let box = document.getElementById('no-video-msg');
    if (!box) {
        box = document.createElement('div');
        box.id = 'no-video-msg';
        box.style.cssText = 'position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#0a0a0a;color:#aaa;gap:10px;z-index:10;';
        box.innerHTML = '<i class="bi bi-wifi-off" style="font-size:2.5rem;color:#444"></i>' +
            '<div style="font-size:.95rem;font-weight:700;color:#bbb">Video yüklenemedi</div>' +
            '<div style="font-size:.78rem;color:#555;margin-bottom:2px">Bağlantı hatası veya kaynak erişim sorunu</div>' +
            '<button onclick="location.reload()" style="margin-top:4px;padding:9px 22px;border-radius:50px;border:1px solid rgba(0,245,255,.35);background:rgba(0,245,255,.07);color:#00f5ff;font-size:.82rem;font-weight:700;cursor:pointer;font-family:inherit;display:flex;align-items:center;gap:6px;transition:background .15s" onmouseover="this.style.background=\'rgba(0,245,255,.14)\'" onmouseout="this.style.background=\'rgba(0,245,255,.07)\'">' +
            '<i class="bi bi-arrow-clockwise"></i> Yeniden Dene</button>';
        const wrap = vdEl?.parentElement || document.getElementById('vd-clip') || document.getElementById('vw');
        if (wrap) { wrap.style.position = 'relative'; wrap.appendChild(box); }
    }
    box.style.display = 'flex';
}

function _startMp4(sk) {
    if (window._imaAdPending) return;
    vd.style.display = '';
    const noVidBox = document.getElementById('no-video-msg');
    if (noVidBox) noVidBox.style.display = 'none';
    showVload();
    vd.src = MP4;
    const _canPlay = () => { vd.removeEventListener('canplay', _canPlay); };
    vd.addEventListener('canplay', _canPlay);
    _triedUrls = new Set(); if (MP4) _triedUrls.add(MP4); // failover için MP4'ü işaretle
    const _err = () => {
        vd.removeEventListener('error', _err); vd.removeEventListener('canplay', _canPlay);
        console.warn('[Player] MP4 err:', vd.error && vd.error.code);
        // CDN MP4 açılmazsa anizium HLS / diğer kaynaklara geç (siyah ekran yerine)
        _failoverNext(sk);
    };
    vd.addEventListener('error', _err);
    if (sk > 0) {
        vd.addEventListener('loadedmetadata', function _meta() {
            vd.removeEventListener('loadedmetadata', _meta);
            vd.removeEventListener('error', _err);
            vd.currentTime = sk;
            vd.play().catch(() => { vd.muted = true; vd.play().then(showUnmute).catch(() => {}); });
        });
    } else {
        vd.play().catch(() => { vd.muted = true; vd.play().then(showUnmute).catch(() => {}); });
    }
}

// ═══ EVRENSEL KAYNAK FAILOVER ══════════════════════════════════════════════════
// Bir kaynak 403/HEVC/timeout ile ölürse, sıradaki oynatılabilir kaynağa otomatik geç.
// Denenen URL'ler _triedUrls'te tutulur → sonsuz döngü olmaz.
let _triedUrls = new Set();
let _bsRetryUrl = null; // siyah ekran aynı URL'de tekrarlarsa failover tetikle (aşağıda kullanılıyor)

// Tüm oynatılabilir kaynakları öncelik sırasıyla topla (tekilleştirilmiş).
// Sıra: aktif/kaydedilmiş dub → diğer dublajlar → kalite sekmeleri → VIDEO_SOURCES → M3U8 → MP4
function _allPlayableUrls() {
    const list = [];
    const add = (url, type, opts) => {
        if (!url) return;
        list.push(Object.assign({ url: url, type: type || 'hls' }, opts || {}));
    };

    // 1) Aktif dub önce, sonra diğerleri (original'ı öne al — en stabil)
    const dubEls = Array.from(document.querySelectorAll('.vmi-dub[data-url]'));
    const activeDub = dubEls.find(e => e.classList.contains('on'));
    const origDub   = dubEls.find(e => e.dataset.key === 'original');
    const orderedDubs = [];
    if (activeDub) orderedDubs.push(activeDub);
    if (origDub && origDub !== activeDub) orderedDubs.push(origDub);
    dubEls.forEach(e => { if (orderedDubs.indexOf(e) === -1) orderedDubs.push(e); });
    orderedDubs.forEach(e => add(e.dataset.url, 'hls', { dubEl: e, label: e.dataset.lbl || 'Dublaj' }));

    // 2) Kaynak/çevirmen sekmeleri
    document.querySelectorAll('.vmi-src[data-url], .src-tab[data-url]').forEach(e =>
        add(e.dataset.url, e.dataset.type || 'hls', { srcEl: e, label: e.dataset.lbl || 'Kaynak' })
    );

    // 3) VIDEO_SOURCES (PHP tarafında 1080→720→4K sıralı geliyor)
    (VIDEO_SOURCES || []).forEach(s => add(s.url, s.type || 'hls', { label: s.label || s.quality || 'Kaynak' }));

    // 4) Ana M3U8 ve MP4 son yedek
    add(M3U8, 'hls', { label: 'Ana kaynak' });
    if (MP4) add(MP4, (MP4.indexOf('.m3u8') !== -1 || MP4.indexOf('/stream/') === 0) ? 'hls' : 'mp4', { label: 'MP4' });

    // Tekilleştir
    const seen = {}, out = [];
    for (const c of list) {
        if (c.url && !seen[c.url]) { seen[c.url] = 1; out.push(c); }
    }

    // HEVC-farkında sıralama: tarayıcı H.265 oynatamıyorsa, daha önce HEVC işaretlenmiş
    // kaynakları en sona at → failover önce çalışan H.264'leri dener (hızlı açılış).
    if (!_hevcOk) {
        const hevcUrls = {};
        (VIDEO_SOURCES || []).forEach(s => { if (s.is_hevc && s.url) hevcUrls[s.url] = 1; });
        if (typeof _knownHevcUrls === 'object') Object.keys(_knownHevcUrls).forEach(u => hevcUrls[u] = 1);
        out.sort((a, b) => (hevcUrls[a.url] ? 1 : 0) - (hevcUrls[b.url] ? 1 : 0)); // stabil: HEVC sona
    }
    return out;
}

// Bu oturumda bufferAppendError almış (HEVC) URL'ler — failover'da sona atılır
var _knownHevcUrls = {};

// Sıradaki denenmemiş kaynağı yükle. Hepsi bittiyse hata göster.
function _failoverNext(sk) {
    const all = _allPlayableUrls();
    let next = null;
    for (const c of all) { if (!_triedUrls.has(c.url)) { next = c; break; } }
    if (!next) {
        console.warn('[Player] Tüm kaynaklar denendi, oynatılamadı (' + _triedUrls.size + ')');
        showNoVideo();
        return;
    }
    _triedUrls.add(next.url);
    console.log('[Player] Failover →', next.label, '(' + _triedUrls.size + '/' + all.length + ')');

    // UI: aktif dub/kaynak butonunu işaretle
    if (next.dubEl) {
        document.querySelectorAll('.vmi-dub').forEach(e => e.classList.toggle('on', e === next.dubEl));
        const lblEl = document.getElementById('dub-lbl');
        if (lblEl && next.dubEl.dataset.lbl) lblEl.textContent = next.dubEl.dataset.lbl;
    }
    if (next.srcEl) {
        document.querySelectorAll('.vmi-src,.src-tab').forEach(e => e.classList.toggle('on', e === next.srcEl));
    }

    // Önceki bufferAppendError'dan sonra MediaSource'un temizlenmesi için kısa gecikme.
    // Gecikmesiz ardışık yükleme, çalışan kaynağı da bozuk state'te patlatıyor (elle
    // tıklayınca araya zaman girdiği için çalışıyordu).
    showVload();
    setTimeout(function() {
        if (next.type === 'mp4') {
            _playMp4Direct(next.url, sk, function() { _failoverNext(sk); });
        } else {
            loadHLS(next.url, sk, function() { _failoverNext(sk); });
        }
    }, 500);
}

// Yeni bir oynatma başlat: denenen listesini sıfırla, ilk URL'yi işaretle, hata → failover
function _beginPlayback(url, type, sk) {
    _triedUrls = new Set();
    _bsRetryUrl = null; // siyah ekran sayacını sıfırla
    if (url) _triedUrls.add(url);
    if (type === 'mp4') {
        _playMp4Direct(url, sk, () => _failoverNext(sk));
    } else {
        loadHLS(url, sk, () => _failoverNext(sk));
    }
}

// MP4 doğrudan oynatma (HLS değil) — hata olursa onFail çağır
function _playMp4Direct(url, t, onFail) {
    showVload();
    vd.pause();
    if (hls) { hls.destroy(); hls = null; }
    vd.src = url;
    const _err = () => { vd.removeEventListener('error', _err); if (onFail) onFail(); else showNoVideo(); };
    vd.addEventListener('error', _err, { once: true });
    const _play = () => vd.play().catch(() => { vd.muted = true; vd.play().catch(() => {}); });
    if (t > 0) {
        vd.addEventListener('loadedmetadata', function _sm() {
            vd.removeEventListener('loadedmetadata', _sm);
            vd.currentTime = t;
            _play();
        }, { once: true });
    } else {
        _play();
    }
}

function _startM3u8(sk, srcOverride) {
    // srcOverride: embed modda M3U8 null ama video_url HLS olabilir
    // VIDEO_SOURCES PHP tarafında kaliteye göre sıralandı (1080p → 720p → 4K)
    const _preferredVS = !srcOverride && (VIDEO_SOURCES || []).find(
        s => s.source === 'anizium' && s.type === 'hls' && s.url
    );

    // İlk denenecek kaynağı seç: kaydedilmiş dub > original dub > tercihli kalite > M3U8
    let firstUrl = null, firstDubEl = null;
    const savedDub = PREF.dub;
    if (savedDub) {
        const dubEl = document.querySelector('.vmi-dub[data-key="' + savedDub + '"]');
        if (dubEl && dubEl.dataset.url) { firstUrl = dubEl.dataset.url; firstDubEl = dubEl; }
    }
    if (!firstUrl) {
        const jpEl = document.querySelector('.vmi-dub[data-key="original"]');
        if (jpEl && jpEl.dataset.url) { firstUrl = jpEl.dataset.url; firstDubEl = jpEl; }
    }
    if (!firstUrl) firstUrl = srcOverride || (_preferredVS ? _preferredVS.url : M3U8);
    if (!firstUrl) { showNoVideo(); return; }

    // UI: aktif dub/kaynak sekmesini işaretle
    if (firstDubEl) {
        document.querySelectorAll('.vmi-dub').forEach(e => e.classList.toggle('on', e === firstDubEl));
        const lblEl = document.getElementById('dub-lbl');
        if (lblEl && firstDubEl.dataset.lbl) lblEl.textContent = firstDubEl.dataset.lbl;
    } else if (_preferredVS) {
        document.querySelectorAll('.vmi-src, .src-tab').forEach(e =>
            e.classList.toggle('on', e.dataset.url === _preferredVS.url)
        );
    }

    _beginPlayback(firstUrl, 'hls', sk);
}

// Kaydedilmiş dub tercihi varsa onu uygula; yoksa Japonca (original) önceliklidir.
function applyDubPref() {
    const sk = _mainSkipSec || 0;
    if (!M3U8 && !MP4) { showNoVideo(); return; }

    // Embed modda anizium M3U8 URL'si video_url alanına kaydediliyor —
    // native <video src> HLS okuyamaz (Safari hariç), HLS.js ile aç.
    // Proxy URL'leri (/stream/proxy?u=...) de HLS olarak işlenir.
    const mp4IsHls = MP4 && (MP4.includes('.m3u8') || MP4.startsWith('/stream/'));

    if (IS_AUTH && MP4 && !mp4IsHls) {
        _startMp4(sk);      // Üye: CDN MP4 birincil, anizium yedek
    } else if (M3U8 || mp4IsHls) {
        _startM3u8(sk, mp4IsHls ? MP4 : null);   // anizium HLS birincil
    } else {
        _startMp4(sk);      // Sadece CDN MP4 mevcut
    }
}

// Quality badge update
function updateQualityLabel() {
    const qlbl = document.getElementById('qlbl');
    if (!qlbl || !hls) return;
    const lvl = hls.currentLevel;
    if (lvl < 0) { qlbl.textContent = 'Auto'; return; }
    const l = hls.levels[lvl];
    qlbl.textContent = l ? (l.height || Math.round(l.width * 9/16)) + 'p' : 'Auto';
}

// Quality
function doQuality(q, el) {
    document.querySelectorAll('#mnu-set .vmi[data-q]').forEach(e => e.classList.remove('on'));
    el.classList.add('on');
    if (hls && Hls.isSupported()) { hls.currentLevel = q; setTimeout(updateQualityLabel, 100); }
    closeMenus();
}

// ─── Zoom / Fill ─────────────────────────────────────────────────────────────
let fillEnabled = false;

function toggleFill() {
    fillEnabled = !fillEnabled;
    const btn = document.getElementById('fill-toggle');
    const row = document.getElementById('zoom-row');
    btn.classList.toggle('on', fillEnabled);
    row.classList.toggle('on', fillEnabled);
    if (fillEnabled) {
        applyZoom(document.getElementById('zoom-slider').value);
    } else {
        vd.style.objectFit = 'contain';
        vd.style.transform = '';
        document.getElementById('zoom-slider').value = 100;
        document.getElementById('zoom-lbl').textContent = '100%';
    }
}

function applyZoom(val) {
    const pct = parseInt(val);
    const scale = pct / 100;
    document.getElementById('zoom-lbl').textContent = pct + '%';
    vd.style.objectFit = 'cover';
    // scale 1.0'dan büyükse ek büyütme (cover zaten sığdırır, scale daha da büyütür)
    vd.style.transform = scale > 1 ? `scale(${scale})` : '';
}

// Muted chip (autoplay policy)
const vunmuteEl = document.getElementById('vunmute');
function showUnmute() {
    if (!vunmuteEl) return;
    vunmuteEl.style.display = 'block';
}
function hideUnmute() {
    if (!vunmuteEl) return;
    vunmuteEl.style.display = 'none';
}
function doUnmute() {
    vd.muted = false;
    vd.volume = Math.max(vd.volume || 0.8, 0.5);
    hideUnmute();
    updVol();
    // Eğer video durduysa başlat
    if (vd.paused && vd.readyState >= 2) vd.play().catch(() => {});
}
vd.addEventListener('volumechange', () => { updVol(); if (!vd.muted) hideUnmute(); });

// ─── Tercih hafızası (localStorage) ─────────────────────────────────────────
const PREF = {
    get dub()  { return localStorage.getItem('axe_dub'); },
    set dub(v) { localStorage.setItem('axe_dub', v); },
    get sub()  { return localStorage.getItem('axe_sub'); },       // dil kodu veya 'off'
    set sub(v) { localStorage.setItem('axe_sub', v); },
    get fs()   { return localStorage.getItem('axe_fs') === '1'; },
    set fs(v)  { localStorage.setItem('axe_fs', v ? '1' : '0'); },
    get subStyle() { try { return JSON.parse(localStorage.getItem('axe_sub_style') || 'null') || {}; } catch { return {}; } },
    set subStyle(v){ localStorage.setItem('axe_sub_style', JSON.stringify(v)); },
};

// PREF hazır — intro yoksa ana videoyu hemen başlat; varsa intro bitince startMainVideo() çağırır
function startPlayer() { _mainSkipSec = MAIN_SKIP_SEC; applyDubPref(); }
if (!INTRO_URL) {
    if (window._imaAdPending) {
        // IMA reklam yükleniyor — reklam bitince startPlayer() çağrılacak
    } else {
        startPlayer();
    }
}

// Dub (hem mnu-dub hem ayarlar içi .vmi-dub senkron)
function doDub(el) {
    const url = el.dataset.url, lbl = el.dataset.lbl, key = el.dataset.key, t = vd.currentTime;
    document.querySelectorAll('.vmi-dub').forEach(e => e.classList.toggle('on', e.dataset.url === url));
    const lblEl = document.getElementById('dub-lbl');
    if (lblEl) lblEl.textContent = lbl;
    if (key) PREF.dub = key;
    // Bu dub ölürse evrensel failover diğer dub/kaynaklara geçer (siyah ekran yerine)
    _beginPlayback(url, 'hls', t);
    closeMenus();
}

// Çeviri kaynağı seçici (animecix çok-çevirmenli bölümler)
function doSource(el) {
    const url = el.dataset.url, lbl = el.dataset.lbl, key = el.dataset.key;
    const t = vd.currentTime;
    document.querySelectorAll('.vmi-src, .src-tab').forEach(e => e.classList.toggle('on', e.dataset.key === key));
    const lblEl = document.getElementById('src-lbl');
    if (lblEl) lblEl.textContent = lbl;
    // Seçilen kaynak ölürse evrensel failover devreye girer
    _beginPlayback(url, el.dataset.type === 'mp4' ? 'mp4' : 'hls', t);
    closeMenus();
}

// Speed
function doSpeed(s, el) {
    vd.playbackRate = s;
    document.querySelectorAll('[data-spd]').forEach(e => e.classList.remove('on'));
    el.classList.add('on');
    closeMenus();
    // Yüksek hızda HLS buffer'ı zorla yeniden başlat — 2x'te mevcut buffer çabuk tükenir
    if (hls && s > 1) {
        hls.startLoad(vd.currentTime);
    }
}

// ─── Subtitle engine ─────────────────────────────────────────────────────────
let cues = [], activeSub = @json(collect($subtitlesData)->search(fn($s)=>$s['is_default']));
const subEl = document.getElementById('vsub');

async function loadSub(idx) {
    cues = []; subEl.innerHTML = ''; subEl.classList.remove('on');
    if (idx < 0 || !SUBS[idx]) return;
    const subUrl = SUBS[idx].url;
    try {
        const r = await fetch(subUrl);
        if (!r.ok) {
            console.warn('[Sub] HTTP', r.status, subUrl);
            if (r.status >= 500) subEl.title = 'Altyazı sunucudan alınamadı';
            return;
        }
        const txt = await r.text();
        if (!txt.trim() || !txt.includes('-->')) {
            console.warn('[Sub] VTT formatı geçersiz:', subUrl);
            return;
        }
        cues = parseVTT(txt);
        console.log('[Sub] Yüklendi:', SUBS[idx].lang, '—', cues.length, 'satır');
        if (!cues.length) console.warn('[Sub] Parse boş sonuç:', subUrl);
        if (activeSub === idx) renderSub(vd.currentTime || 0);
    } catch(e) { console.warn('[Sub] Fetch hatası:', subUrl, e); }
}

function parseVTT(raw) {
    const out = [];
    // BOM ve baştaki boşlukları at, satır sonlarını normalize et
    const normalized = raw.replace(/^﻿/, '').replace(/\r\n?/g, '\n');
    const blocks = normalized.split(/\n{2,}/);
    for (const b of blocks) {
        const ls = b.trim().split('\n');
        const ti = ls.findIndex(l => l.includes('-->'));
        if (ti < 0) continue;
        const timeParts = ls[ti].split('-->');
        if (timeParts.length < 2) continue;
        const s = toSec(timeParts[0].trim());
        const e = toSec(timeParts[1].trim().split(/\s/)[0]);
        if (isNaN(s) || isNaN(e)) continue;
        const txt = ls.slice(ti + 1).join('\n')
            .replace(/<[^>]+>/g, '')
            .replace(/\{[^}]+\}/g, '')
            .replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&nbsp;/g, ' ')
            .trim();
        if (txt) out.push({ s, e, t: txt });
    }
    return out;
}

function toSec(t) {
    const p = t.replace(',','.').split(':');
    return p.length === 3 ? +p[0]*3600 + +p[1]*60 + parseFloat(p[2]) : +p[0]*60 + parseFloat(p[1]);
}

function renderSub(time) {
    // Aynı anda aktif tüm cue'ları topla (ikili konuşma desteği)
    const active = cues.filter(c => time >= c.s && time <= c.e);
    if (!active.length) { subEl.classList.remove('on'); subEl.innerHTML = ''; return; }
    subEl.classList.add('on');
    // Sadece içerik değiştiyse DOM'u güncelle (titreme önleme)
    const newHtml = active.map((c, i) =>
        `<span class="vsub-line${i > 0 ? ' vsub-b' : ''}">${c.t.replace(/\n/g,'<br>')}</span>`
    ).join('');
    if (subEl.innerHTML !== newHtml) subEl.innerHTML = newHtml;
}

function doSub(idx, menuEl) {
    activeSub = idx;
    loadSub(idx);
    // Tüm altyazı menülerindeki (mnu-set + mnu-sub) vmi'ları güncelle
    document.querySelectorAll('.vmi[data-i]').forEach(el => {
        const i = parseInt(el.dataset.i, 10);
        el.classList.toggle('on', i === idx);
    });
    // Tercihi kaydet — dil kodu veya 'off'
    PREF.sub = idx >= 0 && SUBS[idx] ? SUBS[idx].lang : 'off';
    closeMenus();
}

// Altyazı tercihini uygula: önce kayıtlı dil, sonra varsayılan, sonra kapalı
(function applySubPref() {
    const savedLang = PREF.sub;

    if (savedLang === 'off') {
        // Kullanıcı "kapalı" seçmişti
        activeSub = -1;
        return;
    }

    if (savedLang) {
        // Kayıtlı dil koduna göre subtitle bul
        const idx = SUBS.findIndex(s => s.lang === savedLang);
        if (idx >= 0) { activeSub = idx; loadSub(idx); return; }
    }

    // Kayıtlı tercih yoksa veya bulunamadıysa varsayılana dön
    if (activeSub !== false && activeSub >= 0) loadSub(activeSub);
})();

// ─── Altyazı stil özelleştirme ────────────────────────────────────────────────
const _SUB_SIZES = {
    small:  'clamp(.72rem,1.6vw,.95rem)',
    medium: 'clamp(.88rem,2.2vw,1.2rem)',
    large:  'clamp(1rem,2.8vw,1.5rem)',
    xlarge: 'clamp(1.2rem,3.5vw,1.9rem)',
};
const _SUB_BGS = {
    none: 'transparent',
    semi: 'rgba(0,0,0,.55)',
    full: 'rgba(0,0,0,.88)',
};

function applySubStyle(st) {
    if (!subEl) return;
    st = st || {};
    const sz  = _SUB_SIZES[st.size]  || _SUB_SIZES.medium;
    const clr = st.color || '#fff';
    const bg  = _SUB_BGS[st.bg]      || 'transparent';
    const hasBg = st.bg && st.bg !== 'none';
    const shadow = hasBg ? 'none' : '0 0 4px #000,0 1px 6px #000,1px 1px 0 #000,-1px 1px 0 #000,1px -1px 0 #000,-1px -1px 0 #000';
    const pad    = hasBg ? '1px 6px 2px' : '0 4px';
    subEl.style.setProperty('--sub-size',   sz);
    subEl.style.setProperty('--sub-color',  clr);
    subEl.style.setProperty('--sub-bg',     bg);
    subEl.style.setProperty('--sub-shadow', shadow);
    subEl.style.setProperty('--sub-pad',    pad);
    // İkinci konuşmacı — arka plan varsa aynı rengi hafif opak yap, yoksa klasik krem ton
    subEl.style.setProperty('--sub-color-b', hasBg ? clr : 'rgba(255,255,200,0.92)');
}

function setSubSize(sz, btn) {
    document.querySelectorAll('.sub-sz-btn').forEach(b => b.classList.remove('on'));
    if (btn) btn.classList.add('on');
    const st = PREF.subStyle; st.size = sz; PREF.subStyle = st;
    applySubStyle(st);
}

function setSubColor(clr, btn) {
    document.querySelectorAll('.sub-clr-btn').forEach(b => b.classList.remove('on'));
    if (btn) btn.classList.add('on');
    const st = PREF.subStyle; st.color = clr; PREF.subStyle = st;
    applySubStyle(st);
}

function setSubBg(bg, btn) {
    document.querySelectorAll('.sub-bg-btn').forEach(b => b.classList.remove('on'));
    if (btn) btn.classList.add('on');
    const st = PREF.subStyle; st.bg = bg; PREF.subStyle = st;
    applySubStyle(st);
}

// Kayıtlı tercihleri uygula + butonlarda aktif işareti koy
(function initSubStyle() {
    const st = PREF.subStyle;
    applySubStyle(st);
    const defSz  = st.size  || 'medium';
    const defClr = st.color || '#ffffff';
    const defBg  = st.bg    || 'none';
    document.querySelector(`.sub-sz-btn[data-sz="${defSz}"]`)?.classList.add('on');
    document.querySelector(`.sub-clr-btn[data-clr="${defClr}"]`)?.classList.add('on');
    document.querySelector(`.sub-bg-btn[data-bg="${defBg}"]`)?.classList.add('on');
})();

// ─── Controls ─────────────────────────────────────────────────────────────────
const vc = document.getElementById('vc');
const vmBackdrop = document.getElementById('vm-backdrop');
const vwEl = document.getElementById('vw');
let hideT = null, dragging = false;
vwEl.classList.add('ctrls-off');

/** Mobil / dokunmatik: boş alana tıklayınca kontroller aç-kapa. Sadece (pointer:coarse) yetmez; emülatör ve birçok tablet fine pointer raporlar. */
function useChromeToggle() {
    if (typeof window.matchMedia !== 'function') {
        return 'ontouchstart' in window || ((navigator.maxTouchPoints || 0) > 0);
    }
    if (window.matchMedia('(hover: none)').matches) return true;
    if (window.matchMedia('(max-width: 768px)').matches) return true;
    if ((navigator.maxTouchPoints || 0) > 0 && window.matchMedia('(pointer: coarse)').matches) return true;
    return false;
}

const ctrlHideMs = () => (useChromeToggle() ? 4000 : 3200);

function showCtrls() {
    vc.classList.add('on');
    vwEl.classList.remove('ctrls-off');
    document.getElementById('nico-input-row')?.classList.remove('ctrls-hidden');
    clearTimeout(hideT);
    hideT = setTimeout(() => {
        if (dragging || document.querySelector('.vmenu.on')) return;
        hideCtrls();
    }, ctrlHideMs());
}

function hideCtrls() {
    vc.classList.remove('on');
    vwEl.classList.add('ctrls-off');
    document.getElementById('nico-input-row')?.classList.add('ctrls-hidden');
    clearTimeout(hideT);
}

vwEl.addEventListener('mousemove', () => { if (!useChromeToggle()) showCtrls(); });
vwEl.addEventListener('touchstart', () => { if (!useChromeToggle()) showCtrls(); }, { passive: true });
vwEl.addEventListener('mouseleave', () => {
    if (useChromeToggle()) return;
    if (document.querySelector('.vmenu.on')) return;
    hideCtrls();
});

/* Bazı tarayıcılar aynı dokunuşta iki click üretebilir */
let chromeTapLock = 0;
function applyChromeTapToggle() {
    if (document.querySelector('.vmenu.on')) {
        closeMenus();
        return;
    }
    if (vc.classList.contains('on')) hideCtrls();
    else showCtrls();
}

vwEl.addEventListener('click', e => {
    if (e.target.closest('.cb,.vmenu,.vnx,.vp-wrap,.vdrop,#vm-backdrop,.vcb,#vm-mobile-backdrop')) return;
    if (!useChromeToggle()) {
        showCtrls();
        return;
    }
    const now = Date.now();
    if (now - chromeTapLock < 450) return;
    chromeTapLock = now;
    applyChromeTapToggle();
});

function doPlay() {
    if (window._imaAdPending) return;
    if (!vd.src && !vd.currentSrc) { applyDubPref(); return; }
    if (vd.paused) vd.play().catch(() => { vd.muted = true; vd.play().then(showUnmute).catch(() => {}); });
    else vd.pause();
}

vd.addEventListener('play',  () => { document.getElementById('cb-play-i').className = 'bi bi-pause-fill'; });
/* pause: ikon güncelle + kontrolleri göster; zamanlayıcıyı SİLME (showCtrls kendi kuruyordu, clear hemen ardından kapatmayı iptal ediyordu) */
vd.addEventListener('pause', () => {
    document.getElementById('cb-play-i').className = 'bi bi-play-fill';
    showCtrls();
});

// Seek
function seek(s) {
    vd.currentTime = Math.max(MAIN_SKIP_SEC, Math.min(vd.duration || 0, vd.currentTime + s));
    flash(s < 0 ? 'l' : 'r', s);
}
function flash(side, secs) {
    const el = document.getElementById('rf-' + side);
    if (!el) return;
    const lbl = el.querySelector('.vrf-sec');
    if (lbl) lbl.textContent = Math.abs(secs || 10) + ' saniye';
    el.classList.remove('go'); void el.offsetWidth; el.classList.add('go');
}

// Double tap (mobile)
let lastTap = 0;
document.getElementById('vw').addEventListener('touchend', e => {
    const now = Date.now();
    const vwRect = document.getElementById('vw').getBoundingClientRect();
    const x = e.changedTouches[0].clientX - vwRect.left;
    if (now - lastTap < 280) { e.preventDefault(); seek(x < vwRect.width / 2 ? -10 : 10); }
    lastTap = now;
}, { passive: false });

// Double click (desktop)
vwEl.addEventListener('dblclick', e => {
    if (e.target.closest('.cb,.vmenu,.vnx,.vp-wrap,.vdrop,#vm-backdrop,#aniskip-btn,#skip-seg-btn')) return;
    const x = e.clientX - vwEl.getBoundingClientRect().left;
    seek(x < vwEl.offsetWidth / 2 ? -10 : 10);
});

// Hold to 2x speed (mobile long-press + desktop mousedown hold)
let _holdTimer = null, _holding2x = false, _prevRate = 1;
const _holdDelay = 400;
const _holdInd = document.getElementById('hold-ind');
function _startHold() {
    clearTimeout(_holdTimer);
    _holdTimer = setTimeout(() => {
        _prevRate = vd.playbackRate;
        vd.playbackRate = 2;
        _holding2x = true;
        if (_holdInd) _holdInd.style.display = 'block';
    }, _holdDelay);
}
function _endHold() {
    clearTimeout(_holdTimer);
    _holdTimer = null;
    if (_holding2x) {
        vd.playbackRate = _prevRate;
        _holding2x = false;
        if (_holdInd) _holdInd.style.display = 'none';
    }
}
vwEl.addEventListener('touchstart', e => {
    if (e.target.closest('.cb,.vmenu,.vnx,.vp-wrap,.vdrop,#aniskip-btn,#skip-seg-btn')) return;
    _startHold();
}, { passive: true });
vwEl.addEventListener('touchend',    _endHold);
vwEl.addEventListener('touchcancel', _endHold);
vwEl.addEventListener('touchmove',   _endHold, { passive: true });
// Tarayıcının "Video İndir / Kaydet" context menüsünü engelle
vwEl.addEventListener('contextmenu', e => e.preventDefault());
vd.addEventListener('contextmenu',   e => e.preventDefault());
vwEl.addEventListener('mousedown', e => {
    if (e.button !== 0 || e.target.closest('.cb,.vmenu,.vnx,.vp-wrap,.vdrop,#aniskip-btn,#skip-seg-btn')) return;
    _startHold();
});
vwEl.addEventListener('mouseup',     _endHold);
vwEl.addEventListener('mouseleave',  _endHold);

// Next-ep link tıklandığında fullscreen flag'i aktar
if (NXT_URL) {
    document.addEventListener('click', e => {
        if (!(e.target instanceof Element)) return;
        const a = e.target.closest('a');
        if (!a) return;
        const going = a.href === NXT_URL || a.closest('#vnx') || a.classList.contains('pnav-next');
        if (going && (document.fullscreenElement || document.webkitFullscreenElement)) {
            sessionStorage.setItem('axe_auto_fs', '1');
        }
    });
}

// Progress
const vpbar = document.getElementById('vpbar');
const vpfill = document.getElementById('vpfill');
const vpbuf  = document.getElementById('vpbuf');
const vptip  = document.getElementById('vptip');
const vtimeEl = document.getElementById('vtime');

const _wmCover = document.getElementById('wm-cover');
// Mid-roll watermark: her 5 dakikada bir 8 saniyeliğine göster (5:04-5:12, 10:04-10:12 ...)
const WM_MIDROLL_INTERVAL = 300; // saniye (5 dakika)
const WM_MIDROLL_OFFSET   = 4;   // interval başından kaç saniye sonra açılsın
const WM_MIDROLL_DURATION = 8;   // kaç saniye görünsün
function _wmShouldShow(t) {
    if (!_wmCover) return false;
    // Başlangıç kapağı (ilk N saniye)
    if (WM_COVER_SECS > 0 && t < MAIN_SKIP_SEC + WM_COVER_SECS) return true;
    // Mid-roll aralıkları
    const mark = Math.floor(t / WM_MIDROLL_INTERVAL);
    if (mark < 1) return false;
    const windowStart = mark * WM_MIDROLL_INTERVAL + WM_MIDROLL_OFFSET;
    const windowEnd   = windowStart + WM_MIDROLL_DURATION;
    return t >= windowStart && t < windowEnd;
}
function upProgress() {
    if (!vd.duration) return;
    // Yasaklı bölge: rakip intro — asla izletme
    if (MAIN_SKIP_SEC > 0 && vd.currentTime < MAIN_SKIP_SEC) {
        vd.currentTime = MAIN_SKIP_SEC;
        return;
    }
    // Watermark cover: başlangıç + mid-roll
    if (_wmCover) {
        const shouldShow = _wmShouldShow(vd.currentTime);
        if (shouldShow && _wmCover.classList.contains('hide')) {
            _wmCover.style.display = 'flex';
            _wmCover.classList.remove('hide');
        } else if (shouldShow && _wmCover.style.display === 'none') {
            _wmCover.style.display = 'flex';
            _wmCover.classList.remove('hide');
        } else if (!shouldShow && !_wmCover.classList.contains('hide')) {
            _wmCover.classList.add('hide');
            setTimeout(() => { if(_wmCover && _wmCover.classList.contains('hide')) _wmCover.style.display = 'none'; }, 650);
        }
    }
    if (dragging) return;
    const p = vd.currentTime / vd.duration;
    vpfill.style.width = (p * 100) + '%';
    if (vd.buffered.length) vpbuf.style.width = (vd.buffered.end(vd.buffered.length-1)/vd.duration*100) + '%';
    vtimeEl.textContent = fmt(vd.currentTime) + ' / ' + fmt(vd.duration);
    renderSub(vd.currentTime);
    if (HAS_NXT && vd.duration && vd.duration - vd.currentTime <= 30) triggerNext();
}
vd.addEventListener('timeupdate', upProgress);

// ── Skip Segments ────────────────────────────────────────────────────────────
const EPISODE_ID_FOR_SKIP = {{ $ep->id }};
let skipSegments = [];
let activeSegTo  = null;
let seekFromSec  = null; // track seek start for recording skip events

// Fetch segments — intro tespiti (1 kişi bile ileri sardıysa yeter)
fetch(`/api/episodes/${EPISODE_ID_FOR_SKIP}/skip-segments`)
  .then(r => r.json())
  .then(d => {
    skipSegments = d.segments || [];
    // skip-seg verisini ANISKIP formatına çevir (öncelik: manuel/aniskip > skip-seg)
    if (!ANISKIP && skipSegments.length) {
      const s = skipSegments[0];
      ANISKIP = { op: { start: s.from, end: s.to } };
    }
    renderSkipMarkers();
  }).catch(() => {});

function renderSkipMarkers() {
  document.querySelectorAll('.vp-skip-mark').forEach(el => el.remove());
  if (!vd.duration || !skipSegments.length) return;
  skipSegments.forEach(seg => {
    const pct = (seg.from / vd.duration) * 100;
    const mark = document.createElement('div');
    mark.className = 'vp-skip-mark';
    mark.style.left = pct + '%';
    mark.title = 'İntro bölgesi';
    document.getElementById('vpbar').appendChild(mark);
  });
}

vd.addEventListener('loadedmetadata', renderSkipMarkers);

function checkSkipSegment(t) { /* skip-seg artık ANISKIP'e merge edildi */ }
function skipToSegmentEnd() {}

// ── AniSkip ──────────────────────────────────────────────────────────────────
let aniSkipActiveType = null; // 'op' | 'ed' | null

// Fetch AniSkip async if blade didn't supply it (first-time visit for this anime)
if (!ANISKIP) {
  fetch('/api/aniskip/{{ $anime->slug }}/{{ $seasonModel->season_number }}/{{ $ep->episode_number }}')
    .then(r => r.json())
    .then(d => { if (d.aniskip) ANISKIP = d.aniskip; })
    .catch(() => {});
}

function checkAniSkip(t) {
  const btn = document.getElementById('aniskip-btn');
  if (!btn || !ANISKIP) return;
  let type = null;
  if (ANISKIP.op && t >= ANISKIP.op.start && t < ANISKIP.op.end)       type = 'op';
  else if (ANISKIP.ed && t >= ANISKIP.ed.start && t < ANISKIP.ed.end)  type = 'ed';

  if (type !== aniSkipActiveType) {
    aniSkipActiveType = type;
    if (type) {
      if (type === 'ed' && HAS_NXT) {
        triggerNext();
        btn.classList.remove('visible');
      } else {
        const lbl = document.getElementById('aniskip-label');
        if (lbl) lbl.textContent = type === 'op' ? 'İntroyu Atla' : 'Outroyu Atla';
        btn.classList.add('visible');
      }
    } else {
      btn.classList.remove('visible');
    }
  }
}

function skipAniSkip() {
  if (!aniSkipActiveType || !ANISKIP) return;
  const end = ANISKIP[aniSkipActiveType]?.end;
  if (end != null) vd.currentTime = end;
  aniSkipActiveType = null;
  document.getElementById('aniskip-btn')?.classList.remove('visible');
}

// Hook into timeupdate
const _origUpProgress = upProgress;
vd.removeEventListener('timeupdate', upProgress);
vd.addEventListener('timeupdate', () => {
  _origUpProgress();
  checkSkipSegment(vd.currentTime);
  checkAniSkip(vd.currentTime);
  _captureFrame();
});

// Record skip events when user seeks forward >= 5s
// ── Seek thumbnail frame cache ────────────────────────────────────────────────
const _thumbCache = {}, _thumbImgs = {}, _THUMB_INT = 15;
const _vptipTime  = document.getElementById('vptip-time');
const _vptipThumb = document.getElementById('vptip-thumb');
const _vptipCtx   = _vptipThumb?.getContext('2d');
let   _pendingPct = null; // seek position while dragging (not applied yet)

function _captureFrame() {
    if (vd.readyState < 2 || dragging) return;
    const bucket = Math.floor(vd.currentTime / _THUMB_INT);
    if (_thumbCache[bucket]) return;
    try {
        const tc = document.createElement('canvas');
        tc.width = 160; tc.height = 90;
        tc.getContext('2d').drawImage(vd, 0, 0, 160, 90);
        _thumbCache[bucket] = tc.toDataURL('image/jpeg', 0.6);
    } catch(_) {}
}

function _showTip(pct) {
    const t = (vd.duration || 0) * pct;
    if (_vptipTime) _vptipTime.textContent = fmt(t);
    vptip.style.left = (pct * 100) + '%';
    const hasThumbs = Object.keys(_thumbCache).length > 0;
    if (_vptipThumb) _vptipThumb.style.display = hasThumbs ? 'block' : 'none';
    if (!_vptipCtx || !hasThumbs) return;
    const bucket = Math.floor(t / _THUMB_INT);
    const keys   = Object.keys(_thumbCache).map(Number);
    const nearest = keys.reduce((a, b) => Math.abs(b - bucket) < Math.abs(a - bucket) ? b : a);
    if (!_thumbImgs[nearest]) {
        _thumbImgs[nearest] = new Image();
        _thumbImgs[nearest].src = _thumbCache[nearest];
    }
    const img = _thumbImgs[nearest];
    if (img.complete) _vptipCtx.drawImage(img, 0, 0, 160, 90);
    else img.onload = () => _vptipCtx.drawImage(img, 0, 0, 160, 90);
}

function _hideTip() {
    vptip.classList.remove('force-show');
}

function _applyPendingSeek(fromSec) {
    if (_pendingPct === null) return;
    const toSec = clampSeek((vd.duration || 0) * _pendingPct);
    vd.currentTime = toSec;
    // Record skip event
    if (fromSec !== null && toSec - fromSec >= 5) {
        fetch(`/api/episodes/${EPISODE_ID_FOR_SKIP}/skip-event`, {
            method: 'POST',
            headers: {'Content-Type': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name=csrf-token]')?.content || ''},
            body: JSON.stringify({from_sec: Math.round(fromSec), to_sec: Math.round(toSec)})
        }).catch(() => {});
    }
    _pendingPct = null;
}

// Hover: just show tip (no seek)
vpbar.addEventListener('mousemove', e => {
    const r = vpbar.getBoundingClientRect();
    const p = Math.max(0, Math.min(1, (e.clientX - r.left) / r.width));
    if (!dragging) _showTip(p);
});
vpbar.addEventListener('mouseleave', () => { if (!dragging) _hideTip(); });

function clampSeek(t) { return Math.max(MAIN_SKIP_SEC, Math.min(vd.duration || 0, t)); }

// Drag: update visual + tip, seek only on release
function _seekVisual(pct) {
    _pendingPct = pct;
    vpfill.style.width = (pct * 100) + '%';
    vtimeEl.textContent = fmt(clampSeek((vd.duration || 0) * pct)) + ' / ' + fmt(vd.duration);
    vptip.classList.add('force-show');
    _showTip(pct);
}

function _pctFromMouse(e) { const r = vpbar.getBoundingClientRect(); return Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)); }
function _pctFromTouch(e) { const r = vpbar.getBoundingClientRect(); return Math.max(0, Math.min(1, (e.touches[0].clientX - r.left) / r.width)); }

vpbar.addEventListener('mousedown', e => {
    dragging = true;
    seekFromSec = vd.currentTime;
    _seekVisual(_pctFromMouse(e));
    const up = () => {
        dragging = false;
        _hideTip();
        _applyPendingSeek(seekFromSec);
        seekFromSec = null;
        document.removeEventListener('mousemove', mv);
        document.removeEventListener('mouseup', up);
    };
    const mv = ev => _seekVisual(_pctFromMouse(ev));
    document.addEventListener('mousemove', mv);
    document.addEventListener('mouseup', up);
});
vpbar.addEventListener('touchstart', e => {
    dragging = true;
    seekFromSec = vd.currentTime;
    _seekVisual(_pctFromTouch(e));
    const up = () => {
        dragging = false;
        _hideTip();
        _applyPendingSeek(seekFromSec);
        seekFromSec = null;
        document.removeEventListener('touchmove', mv);
        document.removeEventListener('touchend', up);
    };
    const mv = ev => _seekVisual(_pctFromTouch(ev));
    document.addEventListener('touchmove', mv, { passive: true });
    document.addEventListener('touchend', up);
}, { passive: true });

// Volume
function doVol(v) { vd.volume=parseFloat(v); vd.muted=(v==0); updVol(); document.getElementById('cb-vvr').style.setProperty('--v',(v*100)+'%'); }
function doMute() { vd.muted=!vd.muted; if(!vd.muted&&vd.volume===0) vd.volume=1; updVol(); }
function updVol() {
    const lv = vd.muted ? 0 : vd.volume, vi = document.getElementById('cb-vol-i');
    vi.className = lv===0?'bi bi-volume-mute-fill':lv<.5?'bi bi-volume-down-fill':'bi bi-volume-up-fill';
    document.getElementById('cb-vvr').style.setProperty('--v',(lv*100)+'%');
}

// Fullscreen
// Yatay kilit + çıkış için orientation API yardımcıları
function _lockLandscape() {
    try {
        const so = screen.orientation || screen.msOrientation;
        if (so && so.lock) {
            so.lock('landscape').catch(() => {});
        } else if (screen.lockOrientation) {
            screen.lockOrientation('landscape');
        }
    } catch(e) {}
}
function _unlockOrientation() {
    try {
        const so = screen.orientation || screen.msOrientation;
        if (so && so.unlock) so.unlock();
        else if (screen.unlockOrientation) screen.unlockOrientation();
    } catch(e) {}
}

function isIOS() {
    return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
}

function doFS() {
    const fsi = document.getElementById('cb-fs-i');
    const wrap = document.getElementById('vw');
    if (isIOS()) {
        const inFS = wrap.classList.contains('ios-fullscreen');
        if (!inFS) {
            wrap.classList.add('ios-fullscreen');
            document.body.classList.add('ios-fs-active');
            fsi.className = 'bi bi-fullscreen-exit';
            _lockLandscape();
        } else {
            wrap.classList.remove('ios-fullscreen');
            document.body.classList.remove('ios-fs-active');
            fsi.className = 'bi bi-fullscreen';
            _unlockOrientation();
        }
        return;
    }
    if (!document.fullscreenElement && !document.webkitFullscreenElement) {
        const fsReq = wrap.requestFullscreen || wrap.webkitRequestFullscreen;
        if (fsReq) {
            fsReq.call(wrap).catch(() => {});
        }
        fsi.className = 'bi bi-fullscreen-exit';
        _lockLandscape();
    } else {
        (document.exitFullscreen || document.webkitExitFullscreen)?.call(document);
        fsi.className = 'bi bi-fullscreen';
        _unlockOrientation();
    }
}
document.addEventListener('webkitfullscreenchange', () => {
    const inFS = !!(document.fullscreenElement || document.webkitFullscreenElement);
    document.getElementById('cb-fs-i').className = inFS ? 'bi bi-fullscreen-exit' : 'bi bi-fullscreen';
    PREF.fs = inFS;
    if (!inFS) _unlockOrientation();
});
document.addEventListener('fullscreenchange', () => {
    const inFS = !!document.fullscreenElement;
    document.getElementById('cb-fs-i').className = inFS ? 'bi bi-fullscreen-exit' : 'bi bi-fullscreen';
    PREF.fs = inFS;
    if (!inFS) _unlockOrientation();
});

// Dikey konuma dönünce fullscreen'den otomatik çık
if (screen.orientation) {
    screen.orientation.addEventListener('change', () => {
        const type = screen.orientation.type;
        if (type === 'portrait-primary' || type === 'portrait-secondary') {
            if (document.fullscreenElement || document.webkitFullscreenElement) {
                (document.exitFullscreen || document.webkitExitFullscreen)?.call(document);
            }
            const wrap = document.getElementById('vw');
            if (wrap && wrap.classList.contains('ios-fullscreen')) {
                wrap.classList.remove('ios-fullscreen');
                document.body.classList.remove('ios-fs-active');
                document.getElementById('cb-fs-i').className = 'bi bi-fullscreen';
                _unlockOrientation();
            }
        }
    });
}

// Menus
const vmMobileBackdrop = document.getElementById('vm-mobile-backdrop');
// Backdrop'ı vwEl'e taşı — fullscreen'de body'deki elemanlar görünmez, #vw içinde kalmalı
if (vmMobileBackdrop) vwEl.appendChild(vmMobileBackdrop);

const _isMobileMenu = () => window.matchMedia('(max-width:768px)').matches;

function openMenu(id) {
    const m = document.getElementById(id), was = m.classList.contains('on');
    closeMenus();
    if (!was) {
        const dropEl = m.closest('.vdrop');
        m.classList.add('on');
        if (_isMobileMenu()) {
            // Vmenu'yü taşı — fullscreen'de vwEl'e, normalde body'e (#vw overflow:hidden'dan kaçmak için)
            if (!m._origParent) {
                m._origParent = m.parentElement;
                m._origDrop   = dropEl;
                const fsEl = document.fullscreenElement || document.webkitFullscreenElement;
                (fsEl || document.body).appendChild(m);
            }
        } else {
            dropEl?.classList.add('drop-open');
        }
        if (vmMobileBackdrop) vmMobileBackdrop.classList.add('on');
        vmBackdrop?.classList.add('on');
        vc.classList.add('on');
        clearTimeout(hideT);
    }
}
function closeMenus() {
    const hadOpen = !!document.querySelector('.vmenu.on');
    document.querySelectorAll('.vmenu.on').forEach(m => {
        m.classList.remove('on');
        if (m._origParent) {
            m._origParent.appendChild(m);
            m._origDrop?.classList.remove('drop-open');
            delete m._origParent;
            delete m._origDrop;
        }
    });
    document.querySelectorAll('.vdrop.drop-open').forEach(d => d.classList.remove('drop-open'));
    vmBackdrop?.classList.remove('on');
    vmMobileBackdrop?.classList.remove('on');
    if (hadOpen) showCtrls();
}
document.addEventListener('click', e => {
    if (!(e.target instanceof Element)) return;
    if (e.target.closest('.vdrop') || e.target.closest('#vm-backdrop') || e.target.closest('.vmenu')) return;
    closeMenus();
});

// Buffer spinner (mid-play) + loading screen (ilk yükleme)
// Stall recovery: 5s waiting → loader restart; 8s more → full HLS reload
let _stallTimer = null, _stallAttempt = 0;
const _vsMsg = document.getElementById('vs-msg');
function _clearStall() {
    clearTimeout(_stallTimer); _stallTimer = null;
    if (_vsMsg) { _vsMsg.textContent = ''; _vsMsg.classList.remove('on'); }
}
function _tryStallRecover() {
    if (!hls || vd.paused) { _clearStall(); return; }
    _stallAttempt++;
    const ct = vd.currentTime;
    if (_stallAttempt === 1) {
        // İlk deneme: loading screen göster, HLS loader'ı mevcut pozisyondan yeniden başlat
        showVload();
        hls.startLoad(ct);
        if (_vsMsg) { _vsMsg.textContent = 'Yeniden bağlanıyor...'; _vsMsg.classList.add('on'); }
        _stallTimer = setTimeout(_tryStallRecover, 8000);
    } else {
        // İkinci deneme: HLS instance'ı yeniden oluştur (aynı URL, aynı pozisyon).
        // Bu da başarısız olursa evrensel failover ile sıradaki kaynağa geç.
        _stallAttempt = 0;
        const savedUrl = hls.url;
        hls.destroy(); hls = null;
        if (_vsMsg) { _vsMsg.textContent = 'Akış yeniden başlatılıyor...'; }
        loadHLS(savedUrl, ct, () => _failoverNext(ct));
    }
}
vd.addEventListener('waiting', () => {
    document.getElementById('vs').classList.add('on');
    if (hls && !vd.paused && !_stallTimer) {
        _stallAttempt = 0;
        _stallTimer = setTimeout(_tryStallRecover, 5000);
    }
});

// Seeking: hemen spinner göster, yeni pozisyon için loading zorla
let _seekStallTimer = null;
vd.addEventListener('seeking', () => {
    clearTimeout(_seekStallTimer);
    clearTimeout(_blackScreenTimer); _blackScreenTimer = null; // intro-skip / geri-sar false positive önle
    document.getElementById('vs').classList.add('on');
});
vd.addEventListener('seeked', () => {
    clearTimeout(_seekStallTimer);
    // HLS yeni pozisyon için buffer doldurmamışsa yükleyi zorla
    if (hls && vd.readyState < 3) {
        hls.startLoad(vd.currentTime);
    }
    // 3s sonra hâlâ readyState < 3 → stall recovery tetikle
    _seekStallTimer = setTimeout(() => {
        if (!vd.paused && vd.readyState < 3 && hls) {
            _stallAttempt = 0;
            _tryStallRecover();
        }
    }, 3000);
});

// ratechange: yüksek hızda HLS buffer'ı yeniden başlat
vd.addEventListener('ratechange', () => {
    if (!hls || vd.paused) return;
    if (vd.playbackRate > 1) {
        hls.startLoad(vd.currentTime);
    }
});

let _blackScreenTimer = null;
vd.addEventListener('playing', () => {
    _clearStall(); _stallAttempt = 0;
    clearTimeout(_seekStallTimer);
    document.getElementById('vs').classList.remove('on');
    hideVload();
    setTimeout(_captureFrame, 500);

    // Siyah ekran tespiti: 4s içinde currentTime ilerlemiyor → takılı kalmış
    clearTimeout(_blackScreenTimer);
    const _bsCheckTime = vd.currentTime;
    const _bsRate = vd.playbackRate || 1;
    _blackScreenTimer = setTimeout(() => {
        if (vd.paused) return;
        const q = vd.getVideoPlaybackQuality?.();
        const noFrames = q && q.totalVideoFrames === 0;
        // currentTime en az (rate * 1.5) saniye ilerlemiş olmalı
        const notAdvancing = vd.currentTime < _bsCheckTime + (_bsRate * 1.5);
        if (noFrames || notAdvancing) {
            console.warn('[Player] Siyah ekran / takılı:', { frames: q?.totalVideoFrames, timeDiff: vd.currentTime - _bsCheckTime, rate: _bsRate });
            const retryUrl = (hls && hls.url) || vd.currentSrc;
            const retryTime = Math.max(0, vd.currentTime - 0.5);
            if (retryUrl && hls) {
                // Aynı URL'yi bir kez yeniden dene; yine siyah kalırsa failover ile
                // sıradaki kaynağa geç (HEVC / bozuk codec siyah ekranını kırar)
                if (_bsRetryUrl === retryUrl) {
                    console.warn('[Player] Siyah ekran tekrarladı → failover');
                    _failoverNext(retryTime);
                } else {
                    _bsRetryUrl = retryUrl;
                    loadHLS(retryUrl, retryTime, () => _failoverNext(retryTime));
                }
            } else {
                _showBlackScreenHelp();
            }
        }
    }, 4000);
});
function _showBlackScreenHelp() {
    showToast(
        'Video görüntüsü gelmiyor. Tarayıcı donanım hızlandırmasını kapatın veya farklı kaynak deneyin.',
        10000
    );
    const nextSrc = document.querySelector('.src-tab:not(.on)[data-url]');
    if (nextSrc) nextSrc.click();
}
vd.addEventListener('canplay', () => {
    _clearStall();
    document.getElementById('vs').classList.remove('on');
});

// Next episode
let nxtStarted = false, nxtT = null, nxtCancelled = false;
function cancelNext() {
    clearInterval(nxtT);
    nxtStarted = false;
    nxtCancelled = true;
    const vnx = document.getElementById('vnx');
    if (vnx) vnx.classList.remove('on');
    const f = document.getElementById('vnx-fill');
    if (f) f.style.width = '0%';
}
function triggerNext() {
    if (!HAS_NXT || nxtStarted || nxtCancelled) return;
    nxtStarted = true;
    document.getElementById('vnx')?.classList.add('on');
    let pct = 0;
    nxtT = setInterval(() => {
        pct += 10;
        const f = document.getElementById('vnx-fill');
        if (f) f.style.width = pct + '%';
        if (pct >= 100) { clearInterval(nxtT); if (document.fullscreenElement || document.webkitFullscreenElement) sessionStorage.setItem('axe_auto_fs','1'); window.location.href = NXT_URL; }
    }, 500);
}
vd.addEventListener('pause', () => {
    clearInterval(nxtT); nxtStarted = false;
    document.getElementById('vnx')?.classList.remove('on');
});

// Keyboard
document.addEventListener('keydown', e => {
    if (['INPUT','TEXTAREA'].includes(e.target.tagName)) return;
    switch(e.code) {
        case 'Space': case 'KeyK': e.preventDefault(); doPlay(); break;
        case 'ArrowLeft':  e.preventDefault(); seek(-5); break;
        case 'ArrowRight': e.preventDefault(); seek(5);  break;
        case 'KeyJ': seek(-10); break;
        case 'KeyL': seek(10);  break;
        case 'ArrowUp':   e.preventDefault(); doVol(Math.min(1, vd.volume + 0.1)); break;
        case 'ArrowDown': e.preventDefault(); doVol(Math.max(0, vd.volume - 0.1)); break;
        case 'KeyM': doMute(); break;
        case 'KeyF': doFS(); break;
        case 'Slash': case 'KeyH': if (e.shiftKey || e.code === 'Slash') { e.preventDefault(); toggleKbHelp(); } break;
    }
});

// Keyboard shortcut help modal
function toggleKbHelp() {
    let modal = document.getElementById('kb-help-modal');
    if (modal) { modal.remove(); return; }
    modal = document.createElement('div');
    modal.id = 'kb-help-modal';
    modal.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,.82);z-index:9999;display:flex;align-items:center;justify-content:center;padding:16px;backdrop-filter:blur(10px)';
    modal.innerHTML = `
      <div style="background:#0e0e1a;border:1px solid rgba(255,255,255,.14);border-radius:20px;width:100%;max-width:440px;overflow:hidden">
        <div style="padding:16px 20px;border-bottom:1px solid rgba(255,255,255,.07);display:flex;justify-content:space-between;align-items:center">
          <span style="font-size:1rem;font-weight:800;color:#fff"><i class="bi bi-keyboard" style="color:var(--accent2)"></i> Klavye Kısayolları</span>
          <button onclick="document.getElementById('kb-help-modal')?.remove()" style="background:none;border:none;color:rgba(255,255,255,.4);font-size:1.1rem;cursor:pointer"><i class="bi bi-x-lg"></i></button>
        </div>
        <div style="padding:18px 20px;display:grid;grid-template-columns:1fr 1fr;gap:8px">
          ${[
            ['Space / K', 'Oynat / Durdur'],
            ['J', '← 10 saniye'],
            ['L', '→ 10 saniye'],
            ['← →', '← → 5 saniye'],
            ['↑ ↓', 'Ses Aç / Kıs'],
            ['M', 'Sessiz'],
            ['F', 'Tam Ekran'],
            ['?', 'Bu yardım'],
          ].map(([k,v])=>`
            <div style="display:flex;align-items:center;gap:8px;padding:8px;background:rgba(255,255,255,.03);border-radius:8px;border:1px solid rgba(255,255,255,.06)">
              <kbd style="background:rgba(0,245,255,.1);border:1px solid rgba(0,245,255,.25);color:var(--accent2);border-radius:6px;padding:3px 8px;font-size:.75rem;font-weight:800;font-family:monospace;white-space:nowrap">${k}</kbd>
              <span style="font-size:.78rem;color:rgba(255,255,255,.65)">${v}</span>
            </div>`).join('')}
        </div>
        <div style="padding:10px 20px 14px;text-align:center;color:rgba(255,255,255,.25);font-size:.72rem">Herhangi bir yere tıkla veya ? tuşuna bas</div>
      </div>`;
    document.body.appendChild(modal);
    modal.addEventListener('click', e => { if (e.target === modal) modal.remove(); });
}

// Sidebar season switch
function swS(n, btn) {
    document.querySelectorAll('[id^="psl"]').forEach(el => el.style.display = 'none');
    document.querySelectorAll('.pst').forEach(b => b.classList.remove('on'));
    document.getElementById('psl' + n).style.display = 'block';
    btn.classList.add('on');
}

// Sayfa yüklenince: sidebar scroll + fullscreen tercihi
window.addEventListener('load', () => {
    // Sidebar: mevcut bölüme scroll (sayfa scroll değil)
    const nowEp = document.getElementById('now-ep');
    if (nowEp) {
        const list = nowEp.closest('.ps-list');
        if (list) {
            const targetTop = nowEp.offsetTop - list.offsetTop;
            list.scrollTop = Math.max(0, targetTop - list.clientHeight / 2 + nowEp.clientHeight / 2);
        }
    }

    // Fullscreen tercihi: önceki tercih (PREF.fs) veya next-ep geçişinden gelen tek seferlik flag
    const _autoFs = sessionStorage.getItem('axe_auto_fs') === '1';
    if (_autoFs) sessionStorage.removeItem('axe_auto_fs');
    if (PREF.fs || _autoFs) {
        setTimeout(() => {
            document.getElementById('vw')?.requestFullscreen?.().catch(() => { PREF.fs = false; });
        }, 800);
    }
});

// Helpers
function fmt(s) {
    if (!s || isNaN(s)) return '0:00';
    const h=Math.floor(s/3600), m=Math.floor((s%3600)/60), sc=Math.floor(s%60);
    return h>0 ? `${h}:${pad(m)}:${pad(sc)}` : `${m}:${pad(sc)}`;
}
function pad(n) { return String(n).padStart(2,'0'); }

// ─── COMMENT SYSTEM ───────────────────────────────────────────────────────────
const CMT_EP_ID   = {{ $ep->id }};
const CMT_EP_TYPE  = 'episode';
const CMT_CSRF     = '{{ csrf_token() }}';
const CMT_LOGGED      = {{ auth()->check() ? 'true' : 'false' }};
const CMT_ME_ID       = {{ auth()->id() ?? 0 }};
const CMT_HAS_GIF     = {{ (auth()->check() && auth()->user()->hasPerk('comment_gif')) ? 'true' : 'false' }};
const CMT_MAX_CHARS   = {{ (auth()->check() && auth()->user()->hasPerk('extended_comments')) ? 1000 : 500 }};
const CMT_USER_URL = '{{ url("/u") }}';
const CMT_AVA_HTML = {!! json_encode(
    auth()->check()
        ? (auth()->user()->avatar
            ? '<img src="' . \App\Support\MediaUrl::fromStoragePath(auth()->user()->avatar) . '" style="width:100%;height:100%;object-fit:cover">'
            : mb_substr(auth()->user()->name ?? '?', 0, 1))
        : '?'
) !!};
const CMT_URLS    = {
    store:     '{{ route('comments.store') }}',
    like:      (id) => `/comments/${id}/like`,
    index:     '{{ route('comments.index') }}',
    gifSearch: '{{ route('comments.gif-search') }}',
};

let cmtPage       = 1;
let cmtLoading    = false;
let cmtSelectedGif = null;
let cmtReplyTo    = null; // { id, name }
let gifSearchTimer = null;

// Initial load
document.addEventListener('DOMContentLoaded', () => { loadComments(true); });

async function loadComments(reset = false) {
    if (cmtLoading) return;
    if (reset) { cmtPage = 1; document.getElementById('cmt-list').innerHTML = ''; }
    cmtLoading = true;

    try {
        const url = `${CMT_URLS.index}?type=${CMT_EP_TYPE}&id=${CMT_EP_ID}&page=${cmtPage}`;
        const r   = await fetch(url);
        const d   = await r.json();

        const list = document.getElementById('cmt-list');
        if (d.data.length === 0 && cmtPage === 1) {
            document.getElementById('cmt-empty').style.display = 'block';
        } else {
            document.getElementById('cmt-empty').style.display = 'none';
            d.data.forEach(c => list.insertAdjacentHTML('beforeend', renderComment(c)));
        }

        document.getElementById('cmt-load-more').style.display = d.has_more ? 'block' : 'none';
        if (d.has_more) cmtPage++;
        if (d.total !== undefined) {
            const lbl = document.getElementById('cmt-count-lbl');
            if (lbl) lbl.textContent = d.total + ' yorum';
            updateCmtTabBadge(d.total);
        }
    } finally {
        cmtLoading = false;
    }
}

function renderComment(c, isReply = false) {
    const avaClass = c.user?.role === 'admin' ? 'cmt-ava admin' : 'cmt-ava';
    const name = c.user?.name ?? 'Silinmiş Kullanıcı';

    // Avatar + frame ring
    const frame = c.user?.profile_frame;
    const avaInner = c.user?.avatar
        ? `<img src="${c.user.avatar}" alt="${escHtml(name)}" style="width:100%;height:100%;object-fit:cover">`
        : `<span>${escHtml(name.charAt(0).toUpperCase() || '?')}</span>`;
    // Frame ring: wrapper div with ::before pseudo-element (stays within bounds, no overflow clip issue)
    const avaHtml = frame
        ? `<div class="cmt-ava-wrap fr-${frame}"><div class="${avaClass}">${avaInner}</div></div>`
        : `<div class="${avaClass}">${avaInner}</div>`;

    const isOwnComment = c.user?.id === CMT_ME_ID;
    const followBtn = CMT_LOGGED && c.user?.id && !isOwnComment
        ? `<button class="cmt-follow-btn${c.user?.is_following?' following':''}" data-uid="${c.user.id}" data-follow-url="${CMT_USER_URL}/${c.user.id}/follow" onclick="cmtFollow(this,event)" title="${c.user?.is_following?'Takip Ediliyor':'Takip Et'}">${c.user?.is_following?'<i class="bi bi-check2"></i>':'<i class="bi bi-person-plus"></i>'}</button>`
        : '';

    // Username: gradient + effect classes on <a>
    const colorClass  = c.user?.username_color  ? ` username-color-${c.user.username_color}`   : '';
    const effectClass = c.user?.username_effect ? ` username-effect-${c.user.username_effect}` : '';
    const glitchAttr  = c.user?.username_effect === 'glitch' ? ` data-text="${escHtml(name)}"` : '';
    const nameHtml = c.user?.id
        ? `<a href="${CMT_USER_URL}/${c.user.id}" class="cmt-name${colorClass}${effectClass}" data-uid="${c.user.id}"${glitchAttr} style="text-decoration:none">${escHtml(name)}</a>${followBtn}`
        : `<span class="cmt-name">${escHtml(name)}</span>`;

    const adminBadge = c.user?.role === 'admin' ? `<span class="cmt-badge cmt-badge-admin">Admin</span>` : '';
    const adminLabel = c.user?.admin_badge ? `<span class="cmt-badge cmt-badge-staff">${escHtml(c.user.admin_badge)}</span>` : '';
    const customBadge = c.user?.profile_badge ? `<span class="premium-badge user-badge-custom">${escHtml(c.user.profile_badge)}</span>` : '';
    const rankBadge = c.user?.watch_rank ? `<span class="cmt-badge" style="background:rgba(255,255,255,.05);border:1px solid ${escHtml(c.user.watch_rank.color)}44;color:${escHtml(c.user.watch_rank.color)};font-size:.62rem"><i class="bi ${escHtml(c.user.watch_rank.icon)}"></i> ${escHtml(c.user.watch_rank.label)}</span>` : '';
    const pinnedBadge = c.is_pinned ? `<span class="cmt-badge cmt-badge-pinned"><i class="bi bi-pin-fill"></i> Sabitlendi</span>` : '';
    const likeClass = c.is_liked ? 'cmt-action-btn liked' : 'cmt-action-btn';
    const likeIcon  = c.is_liked ? 'bi-heart-fill' : 'bi-heart';
    // Replies to a reply go to the top-level parent (flat thread model)
    const replyTargetId = isReply ? (c.parent_id ?? c.id) : c.id;
    const replyBtn = CMT_LOGGED ? `<button class="cmt-action-btn" onclick="showReplyForm(${replyTargetId},'${escHtml(name)}')"><i class="bi bi-reply"></i> Yanıtla</button>` : '';

    const gifHtml  = c.gif_url ? `<img src="${c.gif_url}" alt="gif" class="cmt-gif" loading="lazy">` : '';
    const textHtml = c.content ? `<div class="cmt-text">${linkifyMentions(escHtml(c.content))}</div>` : '';
    const sigHtml  = c.user?.comment_signature
        ? `<span class="comment-signature">— ${escHtml(c.user.comment_signature)}</span>` : '';

    const repliesHtml = (!isReply && c.replies?.length) ? `
      <div class="cmt-replies" id="replies-${c.id}">
        ${c.replies.map(r => renderComment(r, true)).join('')}
      </div>` : (!isReply ? `<div class="cmt-replies" id="replies-${c.id}" style="display:none"></div>` : '');

    // comment_bg and comment_glow — always use comment-wrap class when either is set
    const bg   = c.user?.comment_bg;
    const glow = c.user?.comment_glow;
    const wrapClass = (bg || glow) ? `cmt-item comment-wrap` : `cmt-item`;
    const bgAttr   = bg   ? ` data-bg="${bg}"`     : '';
    const glowAttr = glow ? ` data-glow="${glow}"` : '';

    return `
    <div class="${wrapClass}" id="cmt-${c.id}"${bgAttr}${glowAttr}>
      ${avaHtml}
      <div class="cmt-body">
        <div class="cmt-meta">
          ${nameHtml}
          ${adminBadge}${adminLabel}${customBadge}${rankBadge}${pinnedBadge}
          <span class="cmt-time">${c.created_at}</span>
        </div>
        ${textHtml}
        ${gifHtml}
        ${sigHtml}
        <div class="cmt-actions">
          <button class="${likeClass}" id="like-btn-${c.id}" onclick="toggleLike(${c.id})">
            <i class="bi ${likeIcon}" id="like-icon-${c.id}"></i>
            <span id="like-count-${c.id}">${c.like_count}</span>
          </button>
          ${replyBtn}
        </div>
        ${repliesHtml}
      </div>
    </div>`;
}

function cmtPendingMsg(reason) {
    if (reason === 'rude')   return '🚫 Yorumunuz uygunsuz ifade içerdiği için moderatör onayına alındı.';
    if (reason === 'spoiler') return '⚠️ Yorumunuz spoiler içerdiği için moderatör onayına alındı.';
    return '⏳ Yorumunuz incelemeye alındı, onaylandıktan sonra yayımlanacak.';
}

async function submitComment() {
    if (!CMT_LOGGED) return;
    const input   = document.getElementById('cmt-input');
    const content = input.value.trim();
    if (!content && !cmtSelectedGif) return;
    if (content.length > CMT_MAX_CHARS) {
        showToast(`Yorum en fazla ${CMT_MAX_CHARS} karakter olabilir.`);
        return;
    }

    const btn = document.getElementById('cmt-submit-btn');
    btn.disabled = true;
    const origHTML = btn.innerHTML;
    if (content) btn.innerHTML = '<i class="bi bi-robot"></i> AI İnceliyor...';

    try {
        const body = {
            commentable_type: CMT_EP_TYPE,
            commentable_id:   CMT_EP_ID,
            content:          content,
            gif_url:          cmtSelectedGif,
            parent_id:        cmtReplyTo?.id ?? null,
        };

        const r = await fetch(CMT_URLS.store, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': CMT_CSRF },
            body: JSON.stringify(body),
        });
        const d = await r.json();

        if (!r.ok || d.error) { showToast(d.error || 'Hata oluştu.'); return; }

        input.value = '';
        input.style.height = '';
        clearGif();
        clearReplyTarget();

        if (d.pending) {
            showToast(cmtPendingMsg(d.pending_reason));
            return;
        }

        const list = document.getElementById('cmt-list');
        if (cmtReplyTo) {
            let repliesDiv = document.getElementById(`replies-${cmtReplyTo.id}`);
            if (repliesDiv) {
                repliesDiv.style.display = 'block';
                repliesDiv.insertAdjacentHTML('beforeend', renderComment(d.comment, true));
            }
        } else {
            document.getElementById('cmt-empty').style.display = 'none';
            list.insertAdjacentHTML('afterbegin', renderComment(d.comment));
        }
    } finally {
        btn.disabled = false;
        btn.innerHTML = origHTML;
    }
}

function linkifyMentions(html) {
    const searchBase = '{{ route('search') }}';
    return html.replace(/@([A-Za-z0-9_]{2,30})/g, (m, u) =>
        `<a href="${searchBase}?q=%40${u}" class="cmt-mention">@${u}</a>`
    );
}

async function cmtFollow(btn, e) {
    e.preventDefault(); e.stopPropagation();
    if (!CMT_LOGGED) { window.location = '{{ route('frontend.login') }}'; return; }
    const url = btn.dataset.followUrl;
    try {
        const r = await fetch(url, { method:'POST', headers:{'X-CSRF-TOKEN':CMT_CSRF,'Accept':'application/json'} });
        const d = await r.json();
        const f = d.following;
        btn.className = `cmt-follow-btn${f?' following':''}`;
        btn.innerHTML = f ? '<i class="bi bi-check2"></i>' : '<i class="bi bi-person-plus"></i>';
        btn.title = f ? 'Takip Ediliyor' : 'Takip Et';
    } catch(err) {}
}

async function toggleLike(id) {
    if (!CMT_LOGGED) { window.location = '{{ route('frontend.login') }}'; return; }
    const r = await fetch(`/comments/${id}/like`, {
        method: 'POST',
        headers: { 'X-CSRF-TOKEN': CMT_CSRF, 'Content-Type': 'application/json' },
    });
    const d = await r.json();
    if (!d.ok) return;
    const btn  = document.getElementById(`like-btn-${id}`);
    const icon = document.getElementById(`like-icon-${id}`);
    const cnt  = document.getElementById(`like-count-${id}`);
    btn.classList.toggle('liked', d.liked);
    icon.className = d.liked ? 'bi bi-heart-fill' : 'bi bi-heart';
    cnt.textContent = d.like_count;
}

function showReplyForm(parentId, parentName) {
    // Önceki yanıt formunu temizle
    document.querySelectorAll('.reply-form-wrap').forEach(el => el.remove());
    cmtReplyTo = { id: parentId, name: parentName };

    const form = `
    <div class="reply-form-wrap" id="reply-form-${parentId}">
      <div class="cmt-ava" style="width:28px;height:28px;font-size:.68rem;overflow:hidden">${CMT_AVA_HTML}</div>
      <textarea class="reply-input" id="reply-input-${parentId}" placeholder="@${escHtml(parentName)} yanıtla..." rows="2" oninput="autoResize(this)"></textarea>
      <button class="reply-submit-btn" onclick="submitReply(${parentId})"><i class="bi bi-send-fill"></i></button>
    </div>`;

    const repliesDiv = document.getElementById(`replies-${parentId}`);
    if (repliesDiv) {
        repliesDiv.style.display = 'block';
        repliesDiv.insertAdjacentHTML('beforeend', form);
        document.getElementById(`reply-input-${parentId}`)?.focus();
    }
}

async function submitReply(parentId) {
    const input   = document.getElementById(`reply-input-${parentId}`);
    const content = input?.value?.trim();
    if (!content) return;
    await submitCommentWithData({ content, parent_id: parentId });
    document.getElementById(`reply-form-${parentId}`)?.remove();
    cmtReplyTo = null;
}

async function submitCommentWithData(extra) {
    const body = {
        commentable_type: CMT_EP_TYPE,
        commentable_id:   CMT_EP_ID,
        content:          extra.content ?? '',
        gif_url:          extra.gif_url ?? null,
        parent_id:        extra.parent_id ?? null,
    };
    const r = await fetch(CMT_URLS.store, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': CMT_CSRF },
        body: JSON.stringify(body),
    });
    const d = await r.json();
    if (!r.ok || d.error) { showToast(d.error || 'Hata oluştu.', 'error'); return; }
    if (d.pending) { showToast(cmtPendingMsg(d.pending_reason)); return; }

    if (extra.parent_id) {
        const repliesDiv = document.getElementById(`replies-${extra.parent_id}`);
        if (repliesDiv) { repliesDiv.style.display='block'; repliesDiv.insertAdjacentHTML('beforeend', renderComment(d.comment, true)); }
    } else {
        document.getElementById('cmt-empty').style.display = 'none';
        document.getElementById('cmt-list').insertAdjacentHTML('afterbegin', renderComment(d.comment));
    }
}

function clearReplyTarget() {
    cmtReplyTo = null;
    document.querySelectorAll('.reply-form-wrap').forEach(el => el.remove());
}

// GIF Picker
function toggleGifPicker() {
    const p = document.getElementById('gif-picker');
    if (p.style.display === 'none') {
        p.style.display = 'block';
        if (!document.getElementById('gif-search-input').value) searchGif('anime');
        document.getElementById('gif-search-input').focus();
    } else {
        p.style.display = 'none';
    }
}

function searchGif(q) {
    clearTimeout(gifSearchTimer);
    gifSearchTimer = setTimeout(async () => {
        if (!q.trim()) q = 'anime';
        document.getElementById('gif-results').innerHTML = '<div class="gif-loading"><i class="bi bi-arrow-repeat"></i> Aranıyor...</div>';
        try {
            const r = await fetch(`${CMT_URLS.gifSearch}?q=${encodeURIComponent(q)}`);
            const d = await r.json();
            if (d.error === 'no_key') {
                document.getElementById('gif-results').innerHTML = '<div class="gif-loading" style="font-size:.8rem;line-height:1.6">GIF özelliği için admin panelinden<br><strong>Giphy API key</strong> tanımlanmalı.</div>';
                return;
            }
            if (!d.results?.length) {
                document.getElementById('gif-results').innerHTML = '<div class="gif-loading">Sonuç bulunamadı.</div>';
                return;
            }
            document.getElementById('gif-results').innerHTML = d.results.map(g =>
                `<img src="${g.preview}" data-full="${g.url}" alt="${escHtml(g.title)}" onclick="selectGif('${g.url}')" loading="lazy">`
            ).join('');
        } catch(e) {
            document.getElementById('gif-results').innerHTML = '<div class="gif-loading">GIF yüklenemedi.</div>';
        }
    }, 400);
}

function selectGif(url) {
    cmtSelectedGif = url;
    document.getElementById('cmt-gif-img').src = url;
    document.getElementById('cmt-gif-preview').style.display = 'block';
    document.getElementById('gif-picker').style.display = 'none';
}

function clearGif() {
    cmtSelectedGif = null;
    document.getElementById('cmt-gif-img').src = '';
    document.getElementById('cmt-gif-preview').style.display = 'none';
}

// Helpers
function autoResize(el) {
    el.style.height = 'auto';
    el.style.height = Math.min(el.scrollHeight, 180) + 'px';
}

function updateCharCount() {
    const el  = document.getElementById('cmt-input');
    const cnt = document.getElementById('cmt-char-count');
    if (!el || !cnt) return;
    const len = el.value.length;
    cnt.textContent = len + ' / ' + CMT_MAX_CHARS;
    cnt.style.color = len > CMT_MAX_CHARS * .9 ? (len >= CMT_MAX_CHARS ? '#ff4f4f' : '#ffbf00') : 'rgba(255,255,255,.25)';
}

function escHtml(s) {
    return String(s ?? '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,'&#39;');
}

function showToast(msg, type, duration) {
    duration = (typeof type === 'number' ? type : duration) || 3500;
    const colors = { error: 'rgba(255,45,125,.15)', warning: 'rgba(251,191,36,.12)' };
    const borders = { error: 'rgba(255,45,125,.4)', warning: 'rgba(251,191,36,.3)' };
    const textClr = { error: 'var(--accent)', warning: '#fbbf24' };
    const bg  = colors[type]  || 'rgba(0,245,255,.15)';
    const bdr = borders[type] || 'rgba(0,245,255,.35)';
    const clr = textClr[type] || 'var(--accent2)';
    const t = document.createElement('div');
    t.innerHTML = msg;
    t.style.cssText = `position:fixed;bottom:24px;left:50%;transform:translateX(-50%);background:${bg};border:1px solid ${bdr};color:${clr};padding:12px 24px;border-radius:10px;font-size:.86rem;font-weight:700;z-index:99999;backdrop-filter:blur(12px);white-space:nowrap;animation:toast-in .28s cubic-bezier(.22,1,.36,1) forwards`;
    document.body.appendChild(t);
    setTimeout(() => t.remove(), duration);
}

// ── Tab switch ────────────────────────────────────────────────────────────────
function switchTab(name, btn) {
    document.querySelectorAll('.eb-tab').forEach(t => t.classList.remove('on'));
    document.querySelectorAll('.eb-panel').forEach(p => p.classList.remove('on'));
    btn.classList.add('on');
    const panel = document.getElementById('panel-' + name);
    if (panel) panel.classList.add('on');
    if (name === 'cmt') {
        const list = document.getElementById('cmt-list');
        if (list && !list.children.length) loadComments(true);
    }
    if (name === 'notes') {
        loadNotes();
    }
}

// Badge güncelleme (loadComments'tan çağırılır)
function updateCmtTabBadge(count) {
    const badge = document.getElementById('tab-cmt-badge');
    if (!badge) return;
    if (count > 0) { badge.textContent = count; badge.style.display = ''; }
    else badge.style.display = 'none';
}

// ── Açıklama expand/collapse ──────────────────────────────────────────────────
function toggleDesc() {
    const el  = document.getElementById('ep-desc');
    const btn = document.getElementById('ep-expand-btn');
    if (!el || !btn) return;
    const expanded = el.classList.toggle('expanded');
    btn.innerHTML = expanded
        ? 'Daha Az Göster <i class="bi bi-chevron-up"></i>'
        : 'Devamını Oku <i class="bi bi-chevron-down"></i>';
}

// ── AI Panel ──────────────────────────────────────────────────────────────────
@auth
const CSRF_TOKEN = document.querySelector('meta[name=csrf-token]')?.content || '';
const AI_ANIME = @json($anime->title);
const AI_EP_NUM = @json($ep->episode_number);
const AI_EP_TITLE = @json($ep->title ?? '');
const AI_EP_DESC = @json($ep->description ?? $anime->description ?? '');
let aiEpAnalyzed = false;
let playerAiMsgs = [{role:'user',content:'Şu an ' + AI_ANIME + ' izliyorum, ' + AI_EP_NUM + '. bölümdeyim.'}];

async function loadEpAi() {
    if (aiEpAnalyzed) return;
    const btn = document.getElementById('ai-ep-btn');
    const loader = document.getElementById('ai-ep-loader');
    const result = document.getElementById('ai-ep-result');
    if (!btn) return;
    btn.style.display = 'none';
    loader.style.display = 'flex';
    try {
        const res = await fetch('{{ route("ai.episode-info") }}', {
            method: 'POST',
            headers: {'Content-Type': 'application/json', 'X-CSRF-TOKEN': CSRF_TOKEN},
            body: JSON.stringify({
                anime_title: AI_ANIME,
                episode_number: AI_EP_NUM,
                episode_title: AI_EP_TITLE,
                description: AI_EP_DESC
            })
        });
        const data = await res.json();
        loader.style.display = 'none';
        if (data.info) {
            result.textContent = data.info;
            result.style.display = 'block';
            aiEpAnalyzed = true;
        } else {
            btn.style.display = '';
            btn.textContent = '⚠ Analiz yapılamadı, tekrar dene';
        }
    } catch(e) {
        loader.style.display = 'none';
        btn.style.display = '';
    }
}

function aiPlayerAsk(q) {
    document.getElementById('ai-player-inp').value = q;
    sendPlayerAiMsg();
}

async function sendPlayerAiMsg() {
    const inp = document.getElementById('ai-player-inp');
    const msgs = document.getElementById('ai-player-msgs');
    const send = document.getElementById('ai-player-send');
    const txt = inp.value.trim();
    if (!txt) return;
    inp.value = '';
    send.disabled = true;

    // User bubble
    const ub = document.createElement('div');
    ub.style.cssText = 'align-self:flex-end;max-width:85%;background:linear-gradient(135deg,rgba(255,45,125,.18),rgba(184,77,255,.12));border:1px solid rgba(255,45,125,.25);border-radius:10px 10px 2px 10px;padding:9px 12px;font-size:.83rem;color:var(--text);line-height:1.5';
    ub.textContent = txt;
    msgs.appendChild(ub);

    playerAiMsgs.push({role: 'user', content: txt});

    // Typing
    const tb = document.createElement('div');
    tb.style.cssText = 'display:flex;gap:4px;padding:10px 13px;align-self:flex-start';
    tb.innerHTML = '<div style="width:7px;height:7px;border-radius:50%;background:var(--accent3);animation:aip-b .9s ease-in-out infinite"></div><div style="width:7px;height:7px;border-radius:50%;background:var(--accent3);animation:aip-b .9s .18s ease-in-out infinite"></div><div style="width:7px;height:7px;border-radius:50%;background:var(--accent3);animation:aip-b .9s .36s ease-in-out infinite"></div>';
    msgs.appendChild(tb);
    msgs.scrollTop = msgs.scrollHeight;

    try {
        const res = await fetch('{{ route("ai.chat") }}', {
            method: 'POST',
            headers: {'Content-Type': 'application/json', 'X-CSRF-TOKEN': CSRF_TOKEN},
            body: JSON.stringify({messages: playerAiMsgs})
        });
        const data = await res.json();
        tb.remove();
        const reply = data.reply || data.error || 'Bir hata oluştu.';
        playerAiMsgs.push({role: 'assistant', content: reply});
        const ab = document.createElement('div');
        ab.style.cssText = 'align-self:flex-start;max-width:92%;background:linear-gradient(135deg,rgba(184,77,255,.12),rgba(0,245,255,.07));border:1px solid rgba(184,77,255,.2);border-radius:10px 10px 10px 2px;padding:9px 12px;font-size:.83rem;color:var(--text);line-height:1.55;white-space:pre-wrap';
        ab.textContent = reply;
        msgs.appendChild(ab);
    } catch(e) {
        tb.remove();
    }
    send.disabled = false;
    msgs.scrollTop = msgs.scrollHeight;
}
@endauth

// ── Video izleme takibi ───────────────────────────────────────────────────────
window.addEventListener('load', function() {
    if (typeof TrackWatch === 'function') {
        TrackWatch(
            {{ $anime->id }},
            {{ $ep->id }},
            {{ $seasonModel->season_number }},
            {{ $ep->episode_number }}
        );
    }
});

// ── Continue watching ─────────────────────────────────────────────────────────
@auth
(function(){
    const vd = document.querySelector('video');
    if (!vd) return;
    const CSRF_T = document.querySelector('meta[name=csrf-token]')?.content||'';
    let lastSent = 0;

    function sendContinue() {
        const sec = Math.floor(vd.currentTime);
        if (sec < 5 || sec === lastSent) return;
        lastSent = sec;
        const total = Math.floor(vd.duration)||0;
        const pct = total>0 ? Math.min(100,Math.round(sec/total*100)) : 0;
        fetch('{{ route("continue.update") }}', {
            method:'POST',
            headers:{'Content-Type':'application/json','X-CSRF-TOKEN':CSRF_T},
            keepalive:true,
            body:JSON.stringify({
                anime_id:{{ $anime->id }},
                episode_id:{{ $ep->id }},
                season_number:{{ $seasonModel->season_number }},
                episode_number:{{ $ep->episode_number }},
                seconds:sec, total, percent:pct
            })
        }).catch(()=>{});
    }

    setInterval(sendContinue, 30000);
    vd.addEventListener('pause', sendContinue);
    window.addEventListener('beforeunload', sendContinue);
    document.addEventListener('visibilitychange', ()=>{ if(document.hidden) sendContinue(); });
})();
@endauth

// ── Episode like/dislike ─────────────────────────────────────────────────────
@auth
async function voteEpisode(vote) {
    const CSRF_T = document.querySelector('meta[name=csrf-token]')?.content||'';
    const res = await fetch('{{ route("episode.vote", $ep) }}', {
        method:'POST',
        headers:{'Content-Type':'application/json','X-CSRF-TOKEN':CSRF_T},
        body:JSON.stringify({vote})
    });
    const d = await res.json();

    document.getElementById('like-cnt').textContent = d.likes;
    document.getElementById('dislike-cnt').textContent = d.dislikes;

    const lb = document.getElementById('btn-like');
    const db = document.getElementById('btn-dislike');

    lb.style.borderColor    = d.my_vote===1 ? '#3fb950' : '#30363d';
    lb.style.background     = d.my_vote===1 ? 'rgba(63,185,80,.15)' : 'transparent';
    lb.style.color          = d.my_vote===1 ? '#3fb950' : 'var(--text2)';
    document.getElementById('like-icon').className = d.my_vote===1 ? 'bi bi-hand-thumbs-up-fill' : 'bi bi-hand-thumbs-up';

    db.style.borderColor    = d.my_vote===-1 ? '#f85149' : '#30363d';
    db.style.background     = d.my_vote===-1 ? 'rgba(248,81,73,.15)' : 'transparent';
    db.style.color          = d.my_vote===-1 ? '#f85149' : 'var(--text2)';
    document.getElementById('dislike-icon').className = d.my_vote===-1 ? 'bi bi-hand-thumbs-down-fill' : 'bi bi-hand-thumbs-down';
}
@else
function voteEpisode(){ window.location='{{ route("frontend.login") }}'; }
@endauth

function showPlayerLoginPrompt() {
    window.location = '{{ route("frontend.login") }}?redirect={{ urlencode(request()->fullUrl()) }}';
}

// ── Bölüm Notları ────────────────────────────────────────────────────────────
@auth
const NOTE_EPISODE_ID = {{ $ep->id }};
const NOTE_CSRF = document.querySelector('meta[name=csrf-token]')?.content||'';
let currentNoteTs = null;

function captureTimestamp() {
    const vd = document.getElementById('vd');
    if (vd && !isNaN(vd.currentTime) && vd.currentTime > 0) {
        currentNoteTs = Math.floor(vd.currentTime);
        const m = Math.floor(currentNoteTs / 60);
        const s = currentNoteTs % 60;
        document.getElementById('note-ts-label').textContent = `${m}:${s.toString().padStart(2,'0')} anında`;
    }
}

async function saveNote() {
    const content = document.getElementById('note-input').value.trim();
    if (!content) return;

    try {
        const res = await fetch(`/episode/${NOTE_EPISODE_ID}/note`, {
            method:'POST',
            headers:{'Content-Type':'application/json','X-CSRF-TOKEN':NOTE_CSRF},
            body: JSON.stringify({ content, timestamp_at: currentNoteTs })
        });
        const d = await res.json();
        if (d.ok) {
            document.getElementById('note-input').value = '';
            currentNoteTs = null;
            document.getElementById('note-ts-label').textContent = 'Şu anki zaman';
            prependNote(d.note);
        }
    } catch(e) {}
}

async function loadNotes() {
    const list = document.getElementById('notes-list');
    if (list.dataset.loaded) return;
    list.dataset.loaded = '1';
    try {
        const res = await fetch(`/episode/${NOTE_EPISODE_ID}/notes`);
        const d = await res.json();
        renderNotes(d.notes || []);
    } catch(e) {}
}

function renderNotes(notes) {
    const list = document.getElementById('notes-list');
    const empty = document.getElementById('notes-empty');
    const badge = document.getElementById('tab-notes-badge');
    list.innerHTML = '';
    if (!notes.length) {
        empty.style.display = 'block';
        return;
    }
    empty.style.display = 'none';
    if (badge) { badge.textContent = notes.length; badge.style.display = ''; }
    notes.forEach(n => prependNote(n, true));
}

function prependNote(n, append = false) {
    const empty = document.getElementById('notes-empty');
    const list  = document.getElementById('notes-list');
    const badge = document.getElementById('tab-notes-badge');
    empty.style.display = 'none';
    const el = document.createElement('div');
    el.id = `note-${n.id}`;
    el.style.cssText = 'background:rgba(255,215,0,.06);border:1px solid rgba(255,215,0,.15);border-radius:9px;padding:10px 12px;position:relative';
    el.innerHTML = `
        ${n.timestamp_label ? `<div style="font-size:.68rem;color:#ffd700;font-weight:700;margin-bottom:5px"><i class="bi bi-clock"></i> ${n.timestamp_label}</div>` : ''}
        <div style="font-size:.84rem;color:var(--text2);line-height:1.5">${escHtml(n.content)}</div>
        <div style="display:flex;justify-content:space-between;align-items:center;margin-top:6px">
          <span style="font-size:.65rem;color:var(--text3)">${n.created_at}</span>
          <button onclick="deleteNote(${n.id})" style="background:none;border:none;color:var(--text3);cursor:pointer;font-size:.75rem;padding:2px 6px" title="Sil"><i class="bi bi-trash"></i></button>
        </div>`;
    if (append) list.appendChild(el);
    else list.prepend(el);
    if (badge) {
        const cnt = list.children.length;
        badge.textContent = cnt;
        badge.style.display = cnt ? '' : 'none';
    }
}

async function deleteNote(id) {
    if (!confirm('Notu sil?')) return;
    try {
        await fetch(`/notes/${id}`, {
            method:'DELETE',
            headers:{'X-CSRF-TOKEN':NOTE_CSRF}
        });
        document.getElementById(`note-${id}`)?.remove();
        const list  = document.getElementById('notes-list');
        const badge = document.getElementById('tab-notes-badge');
        if (!list.children.length) {
            document.getElementById('notes-empty').style.display = 'block';
            if (badge) badge.style.display = 'none';
        } else if (badge) badge.textContent = list.children.length;
    } catch(e) {}
}

@endauth
</script>

@auth
<script>
// ── Share modal ────────────────────────────────────────────
const SHARE_ANIME_SLUG  = '{{ $anime->slug }}';
const SHARE_ANIME_TITLE = {!! json_encode($anime->title) !!};
const SHARE_COVER       = {!! json_encode($anime->coverUrl ?? '') !!};
const SHARE_SEASON      = {{ $seasonModel->season_number }};
const SHARE_EP          = {{ $ep->episode_number }};
const SHARE_EP_TITLE    = {!! json_encode($ep->title ?? '') !!};
const SHARE_CSRF        = '{{ csrf_token() }}';
const SHARE_API_USERS   = '{{ url("/search") }}';
const SHARE_QUICK_URL   = '{{ route("messages.quick-share") }}';

let shareSelectedUser = null;
let shareSearchTimer  = null;

function openShareModal() {
    document.getElementById('share-modal-overlay').style.display = 'flex';
    document.getElementById('share-search').value = '';
    document.getElementById('share-results').innerHTML = '';
    setShareSelected(null);
    setTimeout(() => document.getElementById('share-search').focus(), 100);
}

function closeShareModal() {
    document.getElementById('share-modal-overlay').style.display = 'none';
}

function shareSearch(q) {
    clearTimeout(shareSearchTimer);
    q = q.trim();
    if (!q) { document.getElementById('share-results').innerHTML = ''; return; }
    shareSearchTimer = setTimeout(async () => {
        try {
            const r = await fetch(`/api/users/search?q=${encodeURIComponent(q)}`, {
                headers: { 'Accept': 'application/json', 'X-CSRF-TOKEN': SHARE_CSRF }
            });
            if (!r.ok) throw new Error();
            const users = await r.json();
            renderShareResults(users);
        } catch(e) {
            // fallback: search via user card endpoint pattern not possible, show nothing
            document.getElementById('share-results').innerHTML = '';
        }
    }, 350);
}

function renderShareResults(users) {
    const el = document.getElementById('share-results');
    if (!users.length) { el.innerHTML = '<div style="font-size:.78rem;color:rgba(255,255,255,.3);text-align:center;padding:8px">Kullanıcı bulunamadı</div>'; return; }
    el.innerHTML = users.map(u => `
      <div onclick="setShareSelected(${JSON.stringify(u).replace(/</g,'\\u003c').replace(/"/g,'&quot;')})" style="display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:10px;cursor:pointer;transition:background .15s" onmouseover="this.style.background='rgba(255,255,255,.06)'" onmouseout="this.style.background=''">
        <div style="width:32px;height:32px;border-radius:50%;background:linear-gradient(135deg,var(--accent2),var(--accent));display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:800;color:#fff;flex-shrink:0;overflow:hidden">
          ${u.avatar ? `<img src="${u.avatar}" style="width:100%;height:100%;object-fit:cover">` : (u.name||'?').charAt(0).toUpperCase()}
        </div>
        <div>
          <div style="font-size:.84rem;font-weight:700;color:#fff">${escHtml(u.name||'')}</div>
          ${u.username ? `<div style="font-size:.7rem;color:rgba(255,255,255,.35)">@${escHtml(u.username)}</div>` : ''}
        </div>
      </div>`).join('');
}

function setShareSelected(user) {
    shareSelectedUser = user;
    const el = document.getElementById('share-selected');
    const btn = document.getElementById('share-send-btn');
    if (!user) {
        el.style.display = 'none';
        btn.disabled = true; btn.style.opacity = '.5'; btn.style.cursor = 'default';
        return;
    }
    el.style.display = 'block';
    el.innerHTML = `<div style="display:flex;align-items:center;gap:8px;padding:8px 12px;background:rgba(0,245,255,.06);border:1px solid rgba(0,245,255,.2);border-radius:10px">
      <i class="bi bi-person-check" style="color:var(--accent2)"></i>
      <span style="font-size:.82rem;color:#fff">Kime: <strong>${escHtml(user.name||'')}</strong></span>
      <button onclick="setShareSelected(null)" style="margin-left:auto;background:none;border:none;color:rgba(255,255,255,.3);cursor:pointer;font-size:.8rem"><i class="bi bi-x"></i></button>
    </div>`;
    document.getElementById('share-results').innerHTML = '';
    document.getElementById('share-search').value = '';
    btn.disabled = false; btn.style.opacity = '1'; btn.style.cursor = 'pointer';
}

async function doShareSend() {
    if (!shareSelectedUser) return;
    const vd = document.getElementById('vd');
    const ts = (document.getElementById('share-ts-chk')?.checked && vd)
        ? Math.floor(vd.currentTime) : 0;

    const payload = JSON.stringify({
        slug: SHARE_ANIME_SLUG,
        title: SHARE_ANIME_TITLE,
        cover: SHARE_COVER,
        s: SHARE_SEASON,
        e: SHARE_EP,
        et: SHARE_EP_TITLE,
        ts: ts
    });

    const btn = document.getElementById('share-send-btn');
    btn.disabled = true; btn.textContent = 'Gönderiliyor…';

    try {
        const r = await fetch(SHARE_QUICK_URL, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': SHARE_CSRF, 'Accept': 'application/json' },
            body: JSON.stringify({ to_user_id: shareSelectedUser.id, body: 'ANIMESHARE::' + payload }),
        });
        const d = await r.json();
        if (d.ok) {
            closeShareModal();
            showToast('Paylaşıldı! <a href="/messages/' + d.conversation_id + '" style="color:var(--accent2);font-weight:700">Konuşmaya git →</a>', 4000);
        } else {
            showToast('Gönderilemedi.');
        }
    } catch(e) {
        showToast('Bağlantı hatası.');
    }
    btn.disabled = false; btn.textContent = 'Gönder';
}
</script>
@endauth

{{-- ═══════════════════════════════════════════════════════════════
     SOSYAL ÖZELLİKLER JS: NicoNico + Tahminler + Watch Party + First-Watch
     ═══════════════════════════════════════════════════════════════ --}}
<script>
const SOCIAL_EPISODE_ID     = {{ $ep->id }};
const SOCIAL_CSRF           = document.querySelector('meta[name="csrf-token"]')?.content ?? '';
const SOCIAL_MY_USER_ID     = {{ auth()->id() ?? 'null' }};
const SOCIAL_FOLLOWING_IDS  = @auth @json(\App\Models\UserFollow::where('follower_id', auth()->id())->pluck('following_id')->toArray()) @else [] @endauth;

// ──────────────────────────────────────────────────────────────
// NicoNico Timestamp Yorumları
// ──────────────────────────────────────────────────────────────
let nicoComments    = [];     // [{id, timestamp_sec, body, color, username, user_id}]
let nicoActive      = [];     // ekranda aktif uçuşanlar
let nicoEnabled     = localStorage.getItem('nico_pref') === '1'; // default OFF
let nicoFollowedOnly = false;

function applyNicoState() {
    const row   = document.getElementById('nico-input-row');
    const btn   = document.getElementById('nico-toggle-btn');
    const layer = document.getElementById('nico-layer');
    if (nicoEnabled) {
        row?.classList.remove('nico-off');
        btn?.classList.add('on');
        if (layer) layer.style.display = '';
    } else {
        row?.classList.add('nico-off');
        btn?.classList.remove('on');
        if (layer) layer.style.display = 'none';
        // Ekranda uçan yorumları temizle
        document.querySelectorAll('#nico-layer > div').forEach(el => el.remove());
        nicoActive = [];
    }
}

function toggleNico() {
    nicoEnabled = !nicoEnabled;
    localStorage.setItem('nico_pref', nicoEnabled ? '1' : '0');
    applyNicoState();
    if (nicoEnabled && nicoComments.length === 0) loadNicoComments();
}

function toggleNicoFilter() {
    nicoFollowedOnly = !nicoFollowedOnly;
    document.getElementById('nico-filter-btn')?.classList.toggle('on', nicoFollowedOnly);
}

async function loadNicoComments() {
    try {
        const r = await fetch(`/episode/${SOCIAL_EPISODE_ID}/timestamp-comments`);
        const d = await r.json();
        nicoComments = d.comments || [];
    } catch(e) {}
}

function nicoTick() {
    if (!nicoEnabled) return;
    const vd = document.getElementById('vd');
    if (!vd || vd.paused) return;
    const now = Math.floor(vd.currentTime);

    const toShow = nicoComments.filter(c =>
        c.timestamp_sec === now && !nicoActive.find(a => a.id === c.id) &&
        (!nicoFollowedOnly || c.user_id === SOCIAL_MY_USER_ID || SOCIAL_FOLLOWING_IDS.includes(c.user_id))
    );
    toShow.forEach(c => spawnNicoComment(c));

    nicoActive = nicoActive.filter(a => document.getElementById('nico-' + a.id));
}

function spawnNicoComment(c) {
    const layer = document.getElementById('nico-layer');
    if (!layer) return;

    const el = document.createElement('div');
    el.id = 'nico-' + c.id;
    el.textContent = c.body;
    const topPct = 5 + Math.random() * 80;
    el.style.cssText = `
        position:absolute;
        top:${topPct}%;
        left:100%;
        white-space:nowrap;
        font-size:clamp(.75rem,2vw,1rem);
        font-weight:700;
        color:${c.color};
        text-shadow:1px 1px 3px rgba(0,0,0,.9);
        pointer-events:none;
        animation:nicofly 8s linear forwards;
        z-index:18;
    `;
    layer.appendChild(el);
    nicoActive.push({ id: c.id });
    el.addEventListener('animationend', () => el.remove());
}

// CSS animasyonu ekle
(function() {
    if (document.getElementById('nico-keyframes')) return;
    const s = document.createElement('style');
    s.id = 'nico-keyframes';
    s.textContent = '@keyframes nicofly{from{transform:translateX(0)}to{transform:translateX(calc(-100% - 100vw))}}';
    document.head.appendChild(s);
})();

// Yorum gönder
async function sendNicoComment() {
    if (!IS_AUTH) { showToast('Yorum yazmak için giriş yapmalısın.'); return; }
    const input = document.getElementById('nico-input');
    const color = document.getElementById('nico-color-pick')?.value ?? '#ffffff';
    const body  = input?.value.trim();
    if (!body) return;

    const vd = document.getElementById('vd');
    const ts = vd ? Math.floor(vd.currentTime) : 0;

    try {
        const r = await fetch(`/episode/${SOCIAL_EPISODE_ID}/timestamp-comments`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': SOCIAL_CSRF, 'Accept': 'application/json' },
            body: JSON.stringify({ timestamp_sec: ts, body, color }),
        });
        let d;
        try { d = await r.json(); } catch(_) {
            console.error('NicoNico HTTP ' + r.status, r.statusText);
            showToast('Sunucu hatası (' + r.status + '). migrate_run.php çalıştırıldı mı?');
            return;
        }
        if (d.ok) {
            input.value = '';
            spawnNicoComment({ id: 'tmp-' + Date.now(), timestamp_sec: ts, body, color, username: 'sen' });
            nicoComments.push({ id: d.id, timestamp_sec: ts, body, color });
        } else {
            showToast(d.error || d.message || 'Gönderilemedi.');
        }
    } catch(e) { showToast('Ağ hatası: ' + e.message); }
}

// Video timeupdate ile NicoNico tick
document.addEventListener('DOMContentLoaded', () => {
    applyNicoState();
    if (nicoEnabled) loadNicoComments();
    const vd = document.getElementById('vd');
    if (vd) {
        let lastNicoSec = -1;
        vd.addEventListener('timeupdate', () => {
            const s = Math.floor(vd.currentTime);
            if (s !== lastNicoSec) { lastNicoSec = s; nicoTick(); }
        });
    }
});

// ──────────────────────────────────────────────────────────────
// Tahmin Oyunu
// ──────────────────────────────────────────────────────────────
let myPredictionId = null;

async function loadPredictions() {
    try {
        const r = await fetch(`/episode/${SOCIAL_EPISODE_ID}/predictions`);
        const d = await r.json();
        myPredictionId = d.my_prediction;
        renderPredictions(d.predictions || []);
        const badge = document.getElementById('tab-predict-badge');
        if (badge && d.predictions?.length) {
            badge.textContent = d.predictions.length;
            badge.style.display = '';
        }
    } catch(e) {}
}

function renderPredictions(preds) {
    const list  = document.getElementById('predictions-list');
    const empty = document.getElementById('predictions-empty');
    if (!list) return;

    if (!preds.length) {
        list.innerHTML = '';
        if (empty) empty.style.display = '';
        return;
    }
    if (empty) empty.style.display = 'none';

    list.innerHTML = preds.map(p => {
        const cls  = p.is_correct === true ? 'correct' : p.is_correct === false ? 'wrong' : '';
        const icon = p.is_correct === true ? '✅' : p.is_correct === false ? '❌' : '';
        const voteCls = p.voted ? 'voted' : '';
        return `
        <div class="pred-item ${cls}" id="pred-${p.id}">
          <div style="display:flex;align-items:flex-start;gap:8px">
            <div style="flex:1;font-size:.84rem;color:${p.is_correct===false?'rgba(255,255,255,.45)':'#fff'};line-height:1.4">
              ${icon} ${escHtml(p.body)}
            </div>
            <button class="pred-vote-btn ${voteCls}" onclick="votePrediction(${p.id},this)">
              <i class="bi bi-arrow-up"></i> ${p.vote_count}
            </button>
          </div>
          <div style="font-size:.7rem;color:rgba(255,255,255,.3);margin-top:6px">@${escHtml(p.username||'anonim')} · ${escHtml(p.created_at)}</div>
        </div>`;
    }).join('');
}

async function submitPrediction() {
    const input = document.getElementById('predict-input');
    const body  = input?.value.trim();
    if (!body || body.length < 5) { showToast('En az 5 karakter yaz.'); return; }

    try {
        const r = await fetch(`/episode/${SOCIAL_EPISODE_ID}/predictions`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': SOCIAL_CSRF, 'Accept': 'application/json' },
            body: JSON.stringify({ body }),
        });
        const d = await r.json();
        if (d.ok) {
            input.value = '';
            showToast('Tahmin kaydedildi!');
            loadPredictions();
        } else {
            showToast(d.error || 'Gönderilemedi.');
        }
    } catch(e) { showToast('Bağlantı hatası.'); }
}

async function votePrediction(id, btn) {
    try {
        const r = await fetch(`/predictions/${id}/vote`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': SOCIAL_CSRF, 'Accept': 'application/json' },
            body: '{}',
        });
        const d = await r.json();
        btn.classList.toggle('voted', d.voted);
        btn.innerHTML = `<i class="bi bi-arrow-up"></i> ${d.vote_count}`;
    } catch(e) {}
}

// ──────────────────────────────────────────────────────────────
// İlk Kez İzleyenler
// ──────────────────────────────────────────────────────────────
let firstWatchRegistered = false;

async function fetchFirstWatchCount() {
    try {
        const r = await fetch(`/episode/${SOCIAL_EPISODE_ID}/first-watch-count`);
        const d = await r.json();
        const badge = document.getElementById('firstwatch-badge');
        const cnt   = document.getElementById('firstwatch-count');
        if (badge && cnt) {
            if (d.count > 0) {
                cnt.textContent = d.count;
                badge.style.display = '';
            } else {
                badge.style.display = 'none';
            }
        }
    } catch(e) {}
}

async function registerFirstWatch(isFirst) {
    if (firstWatchRegistered) return;
    firstWatchRegistered = true;
    try {
        await fetch(`/episode/${SOCIAL_EPISODE_ID}/first-watch`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': SOCIAL_CSRF, 'Accept': 'application/json' },
            body: JSON.stringify({ is_first_time: isFirst }),
        });
        fetchFirstWatchCount();
    } catch(e) {}
}

// Kullanıcı videoyu ilk 30 saniyesinde izlemeye başlarsa "ilk kez izleyen" sayıl
document.addEventListener('DOMContentLoaded', () => {
    fetchFirstWatchCount();
    setInterval(fetchFirstWatchCount, 60000); // Her dakika güncelle

    const vd = document.getElementById('vd');
    if (vd && IS_AUTH) {
        vd.addEventListener('play', () => {
            if (vd.currentTime < 30) registerFirstWatch(true);
        }, { once: true });
    }
});

// ──────────────────────────────────────────────────────────────
// Watch Party
// ──────────────────────────────────────────────────────────────
let partyRoomCode      = null;
let partyIsHost        = false;
let partySyncInterval  = null;

function openPartyModal() {
    const bg = document.getElementById('party-modal-bg');
    if (bg) { bg.classList.add('open'); document.body.style.overflow = 'hidden'; }
    document.getElementById('party-create-view').style.display = '';
    document.getElementById('party-room-view').style.display   = 'none';
    document.getElementById('party-private').onchange = function() {
        document.getElementById('party-pw-wrap').style.display = this.checked ? '' : 'none';
    };
    if (partyRoomCode) showPartyRoom(partyRoomCode);
}

function closePartyModal() {
    const bg = document.getElementById('party-modal-bg');
    if (bg) { bg.classList.remove('open'); document.body.style.overflow = ''; }
}

async function createParty() {
    const isPrivate = document.getElementById('party-private')?.checked ?? false;
    const password  = document.getElementById('party-pw')?.value.trim() ?? '';
    try {
        const r = await fetch('/party/create', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': SOCIAL_CSRF, 'Accept': 'application/json' },
            body: JSON.stringify({ episode_id: SOCIAL_EPISODE_ID, is_private: isPrivate, password: password || null }),
        });
        const d = await r.json();
        if (d.ok) {
            partyRoomCode = d.room_code;
            partyIsHost   = true;
            showPartyRoom(d.room_code);
            startPartySync();
        } else {
            showToast(d.error || 'Oda oluşturulamadı.');
        }
    } catch(e) { showToast('Bağlantı hatası.'); }
}

async function joinParty() {
    const code = document.getElementById('party-join-code')?.value.trim().toUpperCase();
    if (!code || code.length < 4) { showToast('Geçerli bir oda kodu gir.'); return; }
    const password = prompt('Şifreli bir oda ise şifre gir (boş bırak)') ?? '';
    try {
        const r = await fetch(`/party/${code}/join`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': SOCIAL_CSRF, 'Accept': 'application/json' },
            body: JSON.stringify({ password }),
        });
        const d = await r.json();
        if (d.ok) {
            partyRoomCode = code;
            partyIsHost   = false;
            showPartyRoom(code);
            startPartySync();
            // Sunucudaki pozisyona sıçra
            const vd = document.getElementById('vd');
            if (vd && d.current_sec > 0) {
                vd.currentTime = d.current_sec;
                if (d.is_playing) vd.play().catch(()=>{});
                else vd.pause();
            }
            renderPartyMembers(d.members || []);
        } else {
            showToast(d.error || 'Katılınamadı.');
        }
    } catch(e) { showToast('Bağlantı hatası.'); }
}

function showPartyRoom(code) {
    document.getElementById('party-create-view').style.display = 'none';
    document.getElementById('party-room-view').style.display   = '';
    document.getElementById('party-room-code').textContent     = code;
    const fab = document.getElementById('party-fab');
    if (fab) { fab.style.display = ''; fab.innerHTML = `<i class="bi bi-people-fill" style="color:#ff2d7d"></i> Oda: ${code}`; }
}

function copyRoomCode() {
    if (!partyRoomCode) return;
    navigator.clipboard?.writeText(partyRoomCode).then(() => showToast('Oda kodu kopyalandı!'));
}

function renderPartyMembers(members) {
    const el = document.getElementById('party-members-list');
    if (!el) return;
    el.innerHTML = members.map(m => `
        <div style="display:flex;align-items:center;gap:6px;padding:5px 10px;background:rgba(255,255,255,.06);border-radius:20px;font-size:.76rem;color:#fff">
            ${m.is_host ? '<i class="bi bi-star-fill" style="color:#ffd700;font-size:.65rem"></i>' : ''}
            ${escHtml(m.name || m.username || '?')}
        </div>`).join('');
}

function startPartySync() {
    if (partySyncInterval) clearInterval(partySyncInterval);
    partySyncInterval = setInterval(doPartySync, 3000);
}

async function doPartySync() {
    if (!partyRoomCode) return;
    const vd = document.getElementById('vd');
    try {
        const body = partyIsHost
            ? { current_sec: Math.floor(vd?.currentTime ?? 0), is_playing: !(vd?.paused ?? true) }
            : {};
        const r = await fetch(`/party/${partyRoomCode}/sync`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': SOCIAL_CSRF, 'Accept': 'application/json' },
            body: JSON.stringify(body),
        });
        const d = await r.json();
        renderPartyMembers(d.members || []);

        // Non-host: senkronize ol (2 saniyeden fazla sapma varsa)
        if (!partyIsHost && vd) {
            const diff = Math.abs(vd.currentTime - d.current_sec);
            if (diff > 2) vd.currentTime = d.current_sec;
            if (d.is_playing && vd.paused)  vd.play().catch(()=>{});
            if (!d.is_playing && !vd.paused) vd.pause();
        }
    } catch(e) {}
}

async function leaveParty() {
    if (!partyRoomCode) return;
    if (partySyncInterval) { clearInterval(partySyncInterval); partySyncInterval = null; }
    try {
        await fetch(`/party/${partyRoomCode}/leave`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': SOCIAL_CSRF },
            body: '{}',
        });
    } catch(e) {}
    partyRoomCode = null;
    const fab = document.getElementById('party-fab');
    if (fab) { fab.style.display = 'none'; }
    closePartyModal();
    showToast('Odadan çıkıldı.');
}

// Watch Party FAB'ini video yüklendikten sonra göster
document.addEventListener('DOMContentLoaded', () => {
    const fab = document.getElementById('party-fab');
    if (fab) setTimeout(() => { fab.style.display = ''; }, 2000);
    loadPredictions();
});

// ── Ruh Hali Motoru ──────────────────────────────────────────────────────────
vd.addEventListener('ended', () => {
    setTimeout(() => {
        const mo = document.getElementById('mood-overlay');
        if (mo) mo.classList.add('on');
    }, 800);
});

async function fetchMood(mood) {
    document.getElementById('mood-picker').style.display = 'none';
    const res = document.getElementById('mood-results');
    const grid = document.getElementById('mood-grid');
    res.style.display = 'block';
    grid.innerHTML = '<div style="grid-column:1/-1;text-align:center;padding:20px;color:rgba(255,255,255,.3)"><i class="bi bi-hourglass"></i></div>';

    const labels = { sad:'😭 Ağlatacak animeler', funny:'🤣 Güldürecek animeler', hype:'🔥 Heyecan verici animeler', think:'🧠 Düşündürücü animeler', romance:'😍 Romantik animeler', scary:'👻 Korkutucu animeler' };
    document.getElementById('mood-results-title').textContent = labels[mood] || 'Öneriler';

    try {
        const r = await fetch('/mood/recommend', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': SOCIAL_CSRF, 'Accept': 'application/json' },
            body: JSON.stringify({ mood }),
        });
        const d = await r.json();
        if (!d.animes?.length) { grid.innerHTML = '<div style="grid-column:1/-1;text-align:center;color:rgba(255,255,255,.3);font-size:.82rem">Öneri bulunamadı.</div>'; return; }
        grid.innerHTML = d.animes.map(a => `
          <a href="${a.url}" class="mood-anime-card">
            ${a.cover ? `<img src="${escHtml(a.cover)}" alt="${escHtml(a.title)}">` : `<div style="width:100%;aspect-ratio:2/3;background:rgba(255,255,255,.05);display:flex;align-items:center;justify-content:center"><i class="bi bi-film" style="font-size:2rem;color:rgba(255,255,255,.15)"></i></div>`}
            <div class="mac-t">${escHtml(a.title)}</div>
          </a>`).join('');
    } catch(e) {
        grid.innerHTML = '<div style="grid-column:1/-1;color:rgba(255,80,80,.7);font-size:.82rem;text-align:center">Hata oluştu.</div>';
    }
}

function closeMoodOverlay() {
    const mo = document.getElementById('mood-overlay');
    if (mo) mo.classList.remove('on');
}

// ── Ambiyans Işığı ───────────────────────────────────────────────────────────
(function(){
    const pwMain = document.querySelector('.pw-main');
    const ac  = document.getElementById('ambi-canvas');
    if (!ac || !pwMain) return;
    const ctx = ac.getContext('2d', { willReadFrequently: false });
    let raf = null, _last = 0;
    // Varsayılan: açık. Kullanıcı kapatırsa '0' saklanır.
    let enabled = localStorage.getItem('axe_ambi') !== '0';

    function applyState() {
        pwMain.classList.toggle('ambi-on', enabled);
        const tog = document.getElementById('ambi-toggle');
        if (tog) tog.classList.toggle('on', enabled);
        if (enabled) start(); else stop();
    }

    function start() {
        if (raf) return;
        function tick(ts) {
            if (!enabled) { raf = null; return; }
            if (ts - _last > 80) {
                _last = ts;
                if (!vd.paused && !vd.ended && vd.readyState >= 2) {
                    try { ctx.drawImage(vd, 0, 0, 32, 18); } catch(e) {}
                }
            }
            raf = requestAnimationFrame(tick);
        }
        raf = requestAnimationFrame(tick);
    }

    function stop() {
        if (raf) { cancelAnimationFrame(raf); raf = null; }
        ctx.clearRect(0, 0, 32, 18);
    }

    window.toggleAmbi = function() {
        enabled = !enabled;
        localStorage.setItem('axe_ambi', enabled ? '1' : '0');
        applyState();
        closeMenus();
    };

    applyState();
})();

// ── Sidebar tab switcher ──────────────────────────────────────────────────────
let sbLoaded = false;
function switchSideTab(tab) {
    ['eps','spoiler'].forEach(t => {
        document.getElementById('tab-' + t)?.classList.toggle('on', t === tab);
        document.getElementById('tc-' + t)?.classList.toggle('on', t === tab);
    });
    if (tab === 'spoiler' && !sbLoaded) { sbLoaded = true; loadSpoilerBoxes(); }
}

// ── Spoiler Kilitli Kutu ──────────────────────────────────────────────────────
async function loadSpoilerBoxes() {
    const panel = document.getElementById('sb-panel');
    try {
        const r = await fetch(`/episode/${SOCIAL_EPISODE_ID}/spoiler-boxes`, {
            headers: { 'Accept': 'application/json' },
        });
        const d = await r.json();
        renderSpoilerBoxes(d.boxes || []);
    } catch(e) {
        panel.innerHTML = '<div style="text-align:center;padding:24px;color:rgba(255,80,80,.5);font-size:.8rem">Yüklenemedi.</div>';
    }
}

function renderSpoilerBoxes(boxes) {
    const panel = document.getElementById('sb-panel');
    if (!boxes.length) {
        panel.innerHTML = '<div style="text-align:center;padding:32px 12px;color:rgba(255,255,255,.25);font-size:.8rem"><i class="bi bi-lock" style="font-size:2rem;display:block;margin-bottom:8px"></i>Henüz spoiler kutusu yok.<br>İlk sen ekle!</div>';
        return;
    }
    panel.innerHTML = boxes.map(b => `
      <div class="sb-item ${b.is_spoiler ? 'is-spoiler' : ''}" id="sb-${b.id}">
        ${b.is_spoiler ? `<div class="sb-spoiler-mask" onclick="revealSpoiler(${b.id})"><i class="bi bi-exclamation-triangle"></i> Spoiler — görmek için tıkla</div>` : ''}
        <div class="sb-body">${escHtml(b.body)}</div>
        <div class="sb-meta">
          <span>${escHtml(b.name || b.username || '?')}</span>
          <span>${b.created_at}</span>
          <button class="sb-like-btn ${b.liked ? 'on' : ''}" id="sblbtn-${b.id}" onclick="likeSpoilerBox(${b.id})">
            <i class="bi bi-heart-fill"></i> <span id="sblcnt-${b.id}">${b.likes}</span>
          </button>
        </div>
      </div>`).join('');
}

function revealSpoiler(id) {
    const mask = document.querySelector(`#sb-${id} .sb-spoiler-mask`);
    if (mask) mask.remove();
}

async function likeSpoilerBox(id) {
    if (!IS_AUTH) { window.location.href = '{{ route('frontend.login') }}'; return; }
    const r = await fetch(`/spoiler-box/${id}/like`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': SOCIAL_CSRF, 'Accept': 'application/json' },
        body: JSON.stringify({}),
    });
    const d = await r.json();
    document.getElementById('sblcnt-' + id).textContent = d.likes;
    document.getElementById('sblbtn-' + id)?.classList.toggle('on', d.liked);
}

async function submitSpoilerBox() {
    const inp  = document.getElementById('sb-inp');
    const body = inp?.value.trim();
    if (!body || body.length < 3) return;
    inp.disabled = true;
    try {
        const r = await fetch(`/episode/${SOCIAL_EPISODE_ID}/spoiler-boxes`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': SOCIAL_CSRF, 'Accept': 'application/json' },
            body: JSON.stringify({ body }),
        });
        const d = await r.json();
        if (d.ok) {
            inp.value = '';
            loadSpoilerBoxes();
            showToast(d.is_spoiler ? '⚠️ Spoiler içerik olarak işaretlendi.' : '✅ Yorum eklendi.');
        } else {
            showToast(d.error || 'Hata oluştu.');
        }
    } catch(e) {
        showToast('Bağlantı hatası.');
    } finally {
        inp.disabled = false;
    }
}
</script>
@endpush
