import re
O='/home/claude/ei/overlay/'
def rep(p,a,b,rx=False):
    s=open(O+p).read()
    if rx:
        s,n=re.subn(a,lambda m:b,s,count=1,flags=re.S); assert n==1,(p,a)
    else:
        assert s.count(a)==1,(p,a); s=s.replace(a,b)
    open(O+p,'w').write(s)
rep('app/Models/User.php','public function isAdmin():bool{return $this->role===\'admin\';}',
 r'''public function isAdmin():bool{return $this->role==='admin';}
 public function reseller(){return $this->belongsTo(User::class,'reseller_id');}
 public function clients(){return $this->hasMany(User::class,'reseller_id');}
 public function brandName():string{return $this->reseller?->brand?:$this->brand?:'EventInvitation by RiansGroup';}''')
rep('app/Models/Invitation.php','(!$u->plan_expires_at||$u->plan_expires_at->isFuture())','(!($u->reseller??$u)->plan_expires_at||($u->reseller??$u)->plan_expires_at->isFuture())')
c='app/Http/Controllers/InvitationController.php'
rep(c,'if($u->plan_expires_at?->isPast()||$u->invitations()->count()>=config("invitation.plans.$u->plan.limit"))',
 r'''$o=$u->reseller??$u;$used=\App\Models\Invitation::whereIn('user_id',\App\Models\User::where('reseller_id',$o->id)->pluck('id')->push($o->id))->count();
  if($o->plan_expires_at?->isPast()||$used>=config("invitation.plans.$o->plan.limit"))''')
rep(c,"'title'=>'required|max:120',","'title'=>'required|max:120','type'=>'required|in:'.implode(',',array_keys(config('invitation.types'))),'lang'=>'required|in:id,en',")
rep(c,"$i->update(['title'=>$v['title'],","$i->update(['type'=>$v['type'],'lang'=>$v['lang'],'remind'=>$r->boolean('remind'),'title'=>$v['title'],")
rep('app/Http/Controllers/AdminController.php',"$r->validate(['plan'=>'in:basic,premium,eksklusif']);$u->plan=$r->plan;",
 "$r->validate(['plan'=>'in:basic,premium,eksklusif,reseller']);$u->plan=$r->plan;if(!$u->isAdmin())$u->role=$r->plan==='reseller'?'reseller':'user';")
rep('app/Http/Controllers/PaymentController.php','$u->plan=$o->plan;',"$u->plan=$o->plan;if($o->plan==='reseller')$u->role='reseller';")
rep('app/Http/Middleware/Ei.php',"if($need==='admin'&&!$u?->isAdmin())abort(403);","if($need==='admin'&&!$u?->isAdmin())abort(403);if($need==='reseller'&&!in_array($u?->role,['reseller','admin']))abort(403);")
open(O+'routes/invitation.php','a').write(r'''Route::middleware(['auth','verified',Ei::class.':reseller'])->prefix('reseller')->group(function(){
 $R=\App\Http\Controllers\ResellerController::class;
 Route::get('/',[$R,'index'])->name('reseller');Route::post('/brand',[$R,'brand'])->name('reseller.brand');
 Route::post('/clients',[$R,'add'])->name('reseller.add');Route::post('/clients/{c}/toggle',[$R,'toggle'])->name('reseller.toggle');
});
''')
L='resources/views/layouts/ei.blade.php'
rep(L,'<b>EventInvitation</b> <small>by RiansGroup</small>',"<b>{{auth()->check()?auth()->user()->brandName():'EventInvitation by RiansGroup'}}</b>")
rep(L,"@if(auth()->user()->isAdmin())","@if(in_array(auth()->user()->role,['reseller','admin']))<a href=\"{{route('reseller')}}\">Reseller</a>@endif@if(auth()->user()->isAdmin())")
rep(L,'© {{date(\'Y\')}} EventInvitation by RiansGroup','© {{date(\'Y\')}} {{auth()->check()?auth()->user()->brandName():\'EventInvitation by RiansGroup\'}}')
rep('resources/views/admin/index.blade.php','<b>{{$t[0]}}</b> <button','<b>{{$t[0]}}</b> <small>{{$t[7]}}</small> <button')
E='resources/views/invitations/edit.blade.php'
rep(E,'<label>Tema (mengganti',r'''<label>Jenis acara</label><select name="type">@foreach(config('invitation.types') as $k=>$ty)<option value="{{$k}}" @selected($i->type===$k)>{{$ty['n']}}</option>@endforeach</select>
<label>Bahasa undangan (tamu juga bisa beralih EN/ID)</label><select name="lang"><option value="id" @selected($i->lang==='id')>Indonesia</option><option value="en" @selected($i->lang==='en')>English</option></select>
<label><input type="checkbox" name="remind" value="1" style="width:auto" @checked($i->remind)> Kirim pengingat WhatsApp otomatis ke daftar tamu (H-1 &amp; hari-H)</label>
<label>Tema (mengganti''')
rep(E,'<select name="theme">.*?</select>',r'''<select name="theme">@foreach(collect(config('invitation.themes'))->groupBy(fn($x)=>$x[7],true) as $cat=>$g)<optgroup label="{{$cat}}">@foreach($g as $k=>$tm)@if(!in_array($k,App\Models\Invitation::off())||$k===$i->theme)<option value="{{$k}}" @selected($i->theme===$k)>{{$tm[0]}}</option>@endif @endforeach</optgroup>@endforeach</select>''',True)
rep(E,'<label>Tema (mengganti tema mengembalikan warna ke bawaan tema)</label>','<label>Tema (mengganti tema mengembalikan warna ke bawaan tema)</label>')
# controller tampil publik
P='app/Http/Controllers/PublicController.php'
rep(P,r'public function show\(.*?(?=\n public function rsvp)',r'''public function show(Request $r,Invitation $i){$i->load('user.reseller');$own=auth()->id()===$i->user_id;abort_unless($i->active()||$own,404);
  if(!$own)$i->increment('views');
  $d=$i->data??[];$t=config("invitation.themes.$i->theme")??config('invitation.themes.glass');
  $lang=in_array($r->query('lang'),['id','en'])?$r->query('lang'):($i->lang??'id');
  $tgl=!empty($d['date'])?\Carbon\Carbon::parse($d['date'])->locale($lang)->translatedFormat($lang==='en'?'l, F j, Y':'l, d F Y'):'';
  return view('public.show',['i'=>$i,'d'=>$d,'t'=>$t,'to'=>$r->query('to'),'lang'=>$lang,'L'=>config("invitation.i18n.$lang"),'ty'=>config('invitation.types.'.($i->type??'wedding')),'tgl'=>$tgl,'brand'=>$i->user->brandName(),
   'c'=>['b'=>$d['bg']??$t[1],'p'=>$d['pri']??$t[2],'t'=>$d['txt']??$t[3]],
   'wishes'=>$i->wishes()->where('is_hidden',false)->latest()->take(30)->get(),'hadir'=>$i->rsvps()->where('status','Hadir')->sum('guests')]);}''',True)
# tampilan publik
V='resources/views/public/show.blade.php'
rep(V,r'@php\(\$c=\[[^\n]*\n','',True); rep(V,r'@php\(\$tgl=[^\n]*\n','',True)
s=open(O+V).read(); head=s.split('<body>')[0].replace('<html lang="id">','<html lang="{{$lang}}">')
css=r'''.gw.s-solid{background:var(--b)}.s-solid::before{opacity:.18}.s-solid .g{background:rgba(255,255,255,.9);backdrop-filter:none;-webkit-backdrop-filter:none;border:1px solid var(--p);color:var(--t);box-shadow:0 6px 20px rgba(0,0,0,.08)}.s-solid .cd div{background:rgba(0,0,0,.06)}.s-solid input,.s-solid textarea,.s-solid select{background:#fff;border-color:var(--p)}.s-solid .nb{background:rgba(255,255,255,.9);color:var(--t)}
.gw.s-frame{background:var(--b)}.s-frame::before{opacity:.15}.s-frame .g{background:transparent;backdrop-filter:none;-webkit-backdrop-filter:none;border:1px solid var(--p);border-radius:6px;box-shadow:none}.s-frame .cv{margin:14px;border:3px double var(--p)}
.lg{position:absolute!important;top:12px;right:14px;z-index:5;font-size:11px;color:var(--t);border:1px solid var(--t);border-radius:99px;padding:3px 10px;text-decoration:none;background:rgba(255,255,255,.15)}
'''
head=head.replace('</style></head>',css+'</style></head>')
body=r'''<body>
<div class="gw s-{{$t[6]}}" style="--b:{{$c['b']}};--p:{{$c['p']}};--t:{{$c['t']}};--f:'{{$t[4]}}',serif">
<div class="pts">@for($k=0;$k<12;$k++)<i class="pt" style="left:{{$k*8+2}}%;animation-duration:{{9+$k%5*2}}s;animation-delay:-{{$k*1.7}}s;font-size:{{12+$k%4*4}}px">{{$t[5]}}</i>@endfor</div>
<a class="lg" href="?lang={{$lang==='en'?'id':'en'}}{{$to?'&to='.urlencode($to):''}}">{{$lang==='en'?'ID':'EN'}}</a>
<header class="cv {{$d['cs']??''}}" style="--ov:{{($d['ov']??55)/100}};@if(!empty($d['cov'])&&($d['uc']??true))background-image:url('{{asset('storage/'.$d['cov'])}}')@endif"><small>{{$d['tag']??$ty['tag'][$lang]}}</small><div><h1>{{$i->title}}</h1><p>{{$tgl}}</p></div>@if($d['sg']??true)<div><p>{{$L['to']}}</p><h2>{{$to?:$L['guest']}}</h2></div>@else<span></span>@endif</header>
@if(session('ok'))<section class="sec"><div class="g">{{session('ok')}}</div></section>@endif
@if(!empty($d['msg']))<section class="sec"><div class="g"><p>{{$d['msg']}}</p></div></section>@endif
@if($ty['p'])<section class="sec" data-s="p">@foreach(array_slice([['b',$ty['lb'][$lang][0]],['g',$ty['lb'][$lang][1]]],0,$ty['p']) as $x)<div class="g">@if(!empty($d[$x[0].'f']))<img class="ph" alt="" src="{{asset('storage/'.$d[$x[0].'f'])}}">@else<div class="ph"></div>@endif<h2>{{$d[$x[0].'n']??''}}</h2>@if(!empty($d[$x[0].'i']))<p>&#64;{{$d[$x[0].'i']}}</p>@endif<p><b>{{$x[1]}}</b></p><p>{{$d[$x[0].'p']??''}}</p><p>{{$d[$x[0].'o']??''}}</p></div>@if($x[0]==='b'&&$ty['p']>1)<h2>&amp;</h2>@endif @endforeach</section>@endif
@if(!empty($d['gal']))<section class="sec" data-s="gal"><div class="g"><h2>{{$L['gal']}}</h2><div class="gl">@foreach($d['gal'] as $s)<img alt="" src="{{asset('storage/'.$s)}}">@endforeach</div></div></section>@endif
<section class="sec" data-s="date"><div class="g"><h2>{{$L['date']}}</h2><div class="cd" data-cd="{{$d['date']??''}}">@foreach($L['days'] as $u)<div><b>0</b>{{$u}}</div>@endforeach</div><p>{{$tgl}}</p><a class="bt" href="{{route('ics',$i)}}">{{$L['cal']}}</a></div></section>
<section class="sec" data-s="loc">@foreach([[0,'time','place','addr'],[1,'time2','place2','addr2']] as $e)@if(!empty($d[$e[2]]))<div class="g"><h2>{{$ty['ev'][$lang][$e[0]]}}</h2><p><b>{{$tgl}}</b></p><p>{{$d[$e[1]]??''}}</p><p><b>{{$d[$e[2]]}}</b></p><p>{{$d[$e[3]]??''}}</p><a class="bt" target="_blank" rel="noopener" href="https://www.google.com/maps/search/?api=1&query={{urlencode($d[$e[2]].' '.($d[$e[3]]??''))}}">{{$L['map']}}</a></div>@endif @endforeach
<div class="g" id="rsvp"><h2>{{$L['rsvp']}}</h2><p>{{$hadir}} {{$L['rsvp_t']}}</p><form method="POST" action="{{route('rsvp',$i)}}">@csrf<input name="name" placeholder="{{$L['name']}}" required value="{{$to}}"><select name="status"><option value="Hadir">{{$L['yes']}}</option><option value="Tidak hadir">{{$L['no']}}</option></select><input type="number" name="guests" min="1" max="10" placeholder="{{$L['n']}}"><button class="bt">{{$L['send']}}</button></form></div>
@if(filter_var($d['live']??'',FILTER_VALIDATE_URL))<div class="g"><h2>{{$L['live']}}</h2><a class="bt" target="_blank" rel="noopener" href="{{$d['live']}}">{{$L['watch']}}</a></div>@endif
@if(!empty($d['gift']))<div class="g"><h2>{{$L['gift']}}</h2><p>{!!nl2br(e($d['gift']))!!}</p></div>@endif</section>
<section class="sec" data-s="wish"><div class="g"><h2>{{$L['wish']}}</h2><form method="POST" action="{{route('wish',$i)}}">@csrf<input name="name" placeholder="{{$L['name']}}" required value="{{$to}}"><textarea name="message" rows="3" placeholder="{{$L['wish_p']}}" required></textarea><button class="bt">{{$L['wish_s']}}</button></form>@foreach($wishes as $w)<p><b>{{$w->name}}</b><br>{{$w->message}}</p>@endforeach</div></section>
<footer style="padding:18px;font-size:11px;opacity:.8">{{$L['made']}} {{$brand}} · Design by HNS Creative Generation</footer>
<div class="nb">@foreach(array_combine(['p','gal','date','loc','wish'],$L['nav']) as $k=>$l)<a onclick="document.querySelector('[data-s={{$k}}]')?.scrollIntoView({behavior:'smooth'})">{{$l}}</a>@endforeach @if(filter_var($d['music']??'',FILTER_VALIDATE_URL))<audio loop src="{{$d['music']}}"></audio><a onclick="var a=this.previousElementSibling;a.paused?a.play():a.pause()">♫</a>@endif</div></div>
<script>document.querySelectorAll('.gw .g').forEach((e,k)=>e.classList.add('rv',['','z','l','r'][k%4]));const o=new IntersectionObserver(es=>es.forEach(x=>{if(x.isIntersecting){x.target.classList.add('in');o.unobserve(x.target)}}),{threshold:.12});document.querySelectorAll('.rv').forEach(e=>o.observe(e));
const cd=()=>document.querySelectorAll('[data-cd]').forEach(el=>{const n=Math.max(0,new Date(el.dataset.cd+'T09:00')-new Date())||0,v=[Math.floor(n/864e5),Math.floor(n/36e5)%24,Math.floor(n/6e4)%60,Math.floor(n/1e3)%60];el.querySelectorAll('b').forEach((b,k)=>b.textContent=v[k])});cd();setInterval(cd,1000);</script></body></html>
'''
open(O+V,'w').write(head+body)
print('ok')
