<?php
declare(strict_types=1);
require_once __DIR__ . '/app/Helpers/bootstrap.php';
require_once __DIR__ . '/app/Helpers/comment-images.php';
ob_start(static function (string $html): string {
    return language() !== 'de' ? str_replace('Noch keine Kommentare vorhanden.', t('comments.empty'), $html) : $html;
});
$commentUi = ['back'=>t('common.back_to_trip'),'title'=>t('trip.comments'),'all'=>t('trip.all_comments'),'trip'=>t('trip.to_trip'),'days'=>t('trip.to_days'),'items'=>t('trip.to_items'),'addTrip'=>t('comments.add_trip'),'addDay'=>t('comments.add_day'),'addItem'=>t('comments.add_item'),'forTrip'=>t('comments.for_trip'),'forDay'=>t('comments.for_day'),'forItem'=>t('comments.for_item'),'saved'=>t('comments.saved'),'empty'=>t('comments.empty'),'images'=>t('common.images'),'hint'=>t('common.images_hint'),'save'=>t('common.save'),'edit'=>t('common.edit'),'del'=>t('common.delete'),'bold'=>t('editor.bold'),'italic'=>t('editor.italic'),'list'=>t('editor.list'),'numbered'=>t('editor.numbered_list'),'link'=>t('editor.link'),'style'=>t('editor.style'),'normal'=>t('editor.normal'),'heading'=>t('editor.heading'),'small'=>t('editor.small_heading'),'singular'=>t('comments.singular'),'plural'=>t('trip.comments'),'close'=>t('common.close'),'previous'=>t('common.previous_image'),'next'=>t('common.next_image'),'imageAlt'=>t('comments.image_alt')];
ob_start(static function (string $html) use ($commentUi): string {
    if (language() === 'de') { return $html; }
    $script = '<script>(function(){const q=s=>document.querySelector(s),qa=s=>[...document.querySelectorAll(s)];const p=new URLSearchParams(location.search),view=p.get("view")||"all",scope=p.has("item")?"item":p.has("day")?"day":view;const x={back:"← Back to trip",title:"Comments",all:"All comments",trip:"About this trip",days:"For days",items:"For program items",addTrip:"Comment for trip",addDay:"Comment for day",addItem:"Comment for program item",forTrip:"Comments for trip",forDay:"Comments for day",forItem:"Comments for program item",saved:"Comment saved.",empty:"No comments yet.",images:"Images",hint:"(maximum 3, 10 MB each)",save:"Save",edit:"Edit",del:"Delete",bold:"Bold",italic:"Italic",list:"List",numbered:"1. List",link:"Link",style:"Text style…",normal:"Normal",heading:"Heading",small:"Small heading",singular:"Comment",plural:"Comments",close:"Close",previous:"Previous image",next:"Next image",imageAlt:"Image for comment"};document.title=x.title+" · TripTale";const back=q("a.back");if(back)back.textContent=x.back;const h1=q("main>h1");if(h1)h1.textContent=x.title;const summary=q(".comments-filter summary"),filter=scope==="item"?x.addItem:scope==="day"?x.addDay:view==="trip"?x.trip:view==="days"?x.days:view==="items"?x.items:x.all;if(summary)summary.textContent=filter+" ▾";qa(".comments-filter nav a").forEach((a,i)=>a.textContent=[x.all,x.trip,x.days,x.items][i]);qa(".success").forEach(e=>{if(e.textContent.trim()==="Kommentar gespeichert.")e.textContent=x.saved});const sections=qa("main>.section"),form=q("#comment-form");if(sections[0]&&form){sections[0].querySelector("h2").textContent=scope==="item"?x.addItem:scope==="day"?x.addDay:x.addTrip;}if(sections.length){const h=sections[sections.length-1].querySelector("h2");if(h)h.textContent=scope==="item"?x.forItem:scope==="day"?x.forDay:view==="trip"?x.forTrip:view==="days"?x.days:view==="items"?x.items:x.all;}if(form){const labels={bold:x.bold,italic:x.italic,insertUnorderedList:x.list,insertOrderedList:x.numbered};qa("[data-command]").forEach(b=>b.textContent=labels[b.dataset.command]||b.textContent);const link=q("#link");if(link)link.textContent=x.link;const style=q("#style");if(style){style.options[0].text=x.style;style.options[1].text=x.normal;style.options[2].text=x.heading;style.options[3].text=x.small;}const image=q("#images");if(image){const label=image.closest("label");if(label&&label.firstChild)label.firstChild.nodeValue=x.images+" ";const muted=label&&label.querySelector(".muted");if(muted)muted.textContent=x.hint;}qa("#comment-form button:not([type])").forEach(b=>b.textContent=x.save);}qa(".comment-group.trip-group summary>span:first-child").forEach(e=>e.textContent=x.trip);qa(".comment-subtitle").forEach(e=>e.textContent=e.textContent.includes("Programmpunkt")?x.forItem:x.forDay);qa(".comment-card").forEach(c=>{const edit=c.querySelector("a.button");if(edit)edit.textContent=x.edit;const del=c.querySelector("button.delete");if(del)del.textContent=x.del;});qa(".meta").forEach(e=>e.textContent=e.textContent.replace(/(\d+)\s+Kommentar(e)?/,(m,n,plural)=>n+" "+(plural?x.plural:x.singular)));qa(".comment-gallery-image").forEach(i=>i.alt=x.imageAlt);qa(".image-lightbox .lightbox-close").forEach(b=>b.setAttribute("aria-label",x.close));qa(".image-lightbox .lightbox-prev").forEach(b=>b.setAttribute("aria-label",x.previous));qa(".image-lightbox .lightbox-next").forEach(b=>b.setAttribute("aria-label",x.next));})();</script>';
    $script = preg_replace('/const x=\{.*?\};/', 'const x=' . json_encode($commentUi, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) . ';', $script, 1) ?? $script;
    return str_replace('</body>', $script . '</body>', $html);
});
ob_start(static function (string $html): string {
    $script = '<script>setTimeout(function(){var label=' . tjs('trip.day') . ';document.querySelectorAll(".comment-group:not(.trip-group) summary > span:first-child").forEach(function(el){var text=el.textContent.trim(),m=text.match(/^(?:Tag|Day)\\s+(\\d+)(?:\\s+·\\s+(?:Tag|Day)\\s+\\1)?$/i);if(m)el.textContent=label+" "+m[1];});},0);</script>';
    return str_replace('</body>', $script . '</body>', $html);
});
$user=require_login();$tripId=filter_input(INPUT_GET,'id',FILTER_VALIDATE_INT,['options'=>['min_range'=>1]]);if(!$tripId)exit('Reise nicht gefunden.');
if($user['role']==='main_admin'){$q=db()->prepare('SELECT id,title FROM '.table('trips').' WHERE id=:id');$q->execute([':id'=>$tripId]);}else{$q=db()->prepare('SELECT t.id,t.title FROM '.table('trips').' t WHERE t.id=:id AND (t.created_by=:creator OR EXISTS(SELECT 1 FROM '.table('trip_admins').' a WHERE a.trip_id=t.id AND a.user_id=:admin) OR EXISTS(SELECT 1 FROM '.table('trip_participants').' p WHERE p.trip_id=t.id AND p.user_id=:participant))');$q->execute([':id'=>$tripId,':creator'=>$user['id'],':admin'=>$user['id'],':participant'=>$user['id']]);}$trip=$q->fetch();if(!$trip){http_response_code(403);exit('Kein Zugriff.');}
$dayId=filter_input(INPUT_GET,'day',FILTER_VALIDATE_INT,['options'=>['min_range'=>1]]);$itemId=filter_input(INPUT_GET,'item',FILTER_VALIDATE_INT,['options'=>['min_range'=>1]]);$view=(string)($_GET['view']??'all');if(!in_array($view,['all','trip','days','items'],true))$view='all';$contextTitle='';
if($itemId){$q=db()->prepare('SELECT i.id,d.id AS day_id,d.day_number,COALESCE(i.title,a.name,ac.name,r.name,cp.name,\'Programmpunkt\') AS title FROM '.table('trip_day_items').' i JOIN '.table('trip_days').' d ON d.id=i.trip_day_id LEFT JOIN '.table('attractions').' a ON i.item_type=\'attraction\' AND a.id=i.reference_id LEFT JOIN '.table('accommodations').' ac ON i.item_type=\'accommodation\' AND ac.id=i.reference_id LEFT JOIN '.table('restaurants').' r ON i.item_type=\'restaurant\' AND r.id=i.reference_id LEFT JOIN '.table('custom_points').' cp ON i.item_type=\'catalog_custom\' AND cp.id=i.reference_id WHERE i.id=:item AND d.trip_id=:trip');$q->execute([':item'=>$itemId,':trip'=>$tripId]);$context=$q->fetch();if(!$context)exit('Programmpunkt nicht gefunden.');$dayId=(int)$context['day_id'];$view='item';$contextTitle='Tag '.$context['day_number'].' · '.$context['title'];}elseif($dayId){$q=db()->prepare('SELECT id,day_number,title FROM '.table('trip_days').' WHERE id=:day AND trip_id=:trip');$q->execute([':day'=>$dayId,':trip'=>$tripId]);$context=$q->fetch();if(!$context)exit('Tag nicht gefunden.');$view='day';$contextTitle='Tag '.$context['day_number'].' · '.$context['title'];}else{$context=null;}
$scope='c.trip_day_id IS NULL AND c.trip_day_item_id IS NULL';$scopeParams=[];if($dayId){$scope='c.trip_day_id=:day AND c.trip_day_item_id IS NULL';$scopeParams=[':day'=>$dayId];}if($itemId){$scope='c.trip_day_item_id=:item';$scopeParams=[':item'=>$itemId];}$returnView=$itemId?'items':($dayId?'days':($view==='trip'?'trip':'all'));$returnUrl='/trip-comments.php?id='.$tripId.($returnView!=='all'?'&view='.$returnView:'');$editId=filter_input(INPUT_GET,'comment',FILTER_VALIDATE_INT,['options'=>['min_range'=>1]]);$edit=['body'=>''];$editImages=[];
if($editId){$q=db()->prepare('SELECT c.id,c.body FROM '.table('trip_comments').' c WHERE c.id=:id AND c.trip_id=:trip AND c.user_id=:user AND '.$scope);$q->execute([':id'=>$editId,':trip'=>$tripId,':user'=>$user['id']]+$scopeParams);$edit=$q->fetch();if(!$edit)exit('Kommentar nicht gefunden.');$editImages=comment_image_paths($editId);}$error=null;
if($_SERVER['REQUEST_METHOD']==='POST'){verify_csrf();$action=(string)($_POST['action']??'save');$commentId=filter_input(INPUT_POST,'comment_id',FILTER_VALIDATE_INT,['options'=>['min_range'=>1]]);$deleteImageId=filter_input(INPUT_POST,'delete_image_id',FILTER_VALIDATE_INT,['options'=>['min_range'=>1]]);if($deleteImageId&&$commentId){$q=db()->prepare('SELECT ci.file_path FROM '.table('trip_comment_images').' ci JOIN '.table('trip_comments').' c ON c.id=ci.comment_id WHERE ci.id=:image AND c.id=:id AND c.trip_id=:trip AND c.user_id=:user');$q->execute([':image'=>$deleteImageId,':id'=>$commentId,':trip'=>$tripId,':user'=>$user['id']]);$image=$q->fetch();if(!$image)exit('Bild nicht gefunden.');$q=db()->prepare('DELETE FROM '.table('trip_comment_images').' WHERE id=:image');$q->execute([':image'=>$deleteImageId]);comment_remove_image_file((string)$image['file_path']);header('Location: '.$returnUrl.'&comment='.$commentId.'&image=deleted');exit;}if($action==='delete'&&$commentId){$q=db()->prepare('SELECT id FROM '.table('trip_comments').' WHERE id=:id AND trip_id=:trip AND user_id=:user');$q->execute([':id'=>$commentId,':trip'=>$tripId,':user'=>$user['id']]);if(!$q->fetch())exit('Kommentar nicht gefunden.');comment_remove_images_for_comment($commentId);$q=db()->prepare('DELETE FROM '.table('trip_comments').' WHERE id=:id AND trip_id=:trip AND user_id=:user');$q->execute([':id'=>$commentId,':trip'=>$tripId,':user'=>$user['id']]);header('Location: '.$returnUrl.'&deleted=1');exit;}$body=sanitize_rich_text((string)($_POST['body']??''));if($body==='')$error='Bitte einen Kommentar eingeben.';else{$targetId=0;if($commentId){$q=db()->prepare('UPDATE '.table('trip_comments').' c SET body=:body WHERE c.id=:id AND c.trip_id=:trip AND c.user_id=:user AND '.$scope);$q->execute([':body'=>$body,':id'=>$commentId,':trip'=>$tripId,':user'=>$user['id']]+$scopeParams);$targetId=$commentId;}else{$q=db()->prepare('INSERT INTO '.table('trip_comments').' (trip_id,trip_day_id,trip_day_item_id,user_id,body) VALUES (:trip,:day,:item,:user,:body)');$q->execute([':trip'=>$tripId,':day'=>$dayId?:null,':item'=>$itemId?:null,':user'=>$user['id'],':body'=>$body]);$targetId=(int)db()->lastInsertId();}$uploadError=comment_store_uploaded_images($targetId,$_FILES['images']??[]);if($uploadError!==null){$error=$uploadError;$editId=$targetId;$editImages=comment_image_paths($targetId);}else{header('Location: '.$returnUrl.'&saved=1');exit;}}}
$q=db()->prepare('SELECT c.*,u.first_name,u.last_name,u.profile_image,d.day_number,d.title AS day_title,COALESCE(i.title,a.name,ac.name,r.name,cp.name) AS item_title,COALESCE(i.image_path,a.image_path,ac.image_path,r.image_path,cp.image_path) AS item_image FROM '.table('trip_comments').' c JOIN '.table('users').' u ON u.id=c.user_id LEFT JOIN '.table('trip_days').' d ON d.id=c.trip_day_id LEFT JOIN '.table('trip_day_items').' i ON i.id=c.trip_day_item_id LEFT JOIN '.table('attractions').' a ON i.item_type=\'attraction\' AND a.id=i.reference_id LEFT JOIN '.table('accommodations').' ac ON i.item_type=\'accommodation\' AND ac.id=i.reference_id LEFT JOIN '.table('restaurants').' r ON i.item_type=\'restaurant\' AND r.id=i.reference_id LEFT JOIN '.table('custom_points').' cp ON i.item_type=\'catalog_custom\' AND cp.id=i.reference_id WHERE c.trip_id=:trip ORDER BY d.day_number,i.sort_order,c.created_at ASC');$q->execute([':trip'=>$tripId]);$all=$q->fetchAll();$imageMap=[];$q=db()->prepare('SELECT ci.comment_id,ci.id,ci.file_path FROM '.table('trip_comment_images').' ci JOIN '.table('trip_comments').' c ON c.id=ci.comment_id WHERE c.trip_id=:trip ORDER BY ci.sort_order,ci.id');$q->execute([':trip'=>$tripId]);foreach($q->fetchAll() as $image){$imageMap[(int)$image['comment_id']][]=$image;}foreach($all as &$comment){$comment['images']=$imageMap[(int)$comment['id']]??[];}unset($comment);
$comments=array_values(array_filter($all,static function(array $c)use($view,$dayId,$itemId):bool{if($itemId)return(int)$c['trip_day_item_id']===$itemId;if($dayId)return(int)$c['trip_day_id']===$dayId&&!$c['trip_day_item_id'];if($view==='trip')return!$c['trip_day_id']&&!$c['trip_day_item_id'];if($view==='days')return(bool)$c['trip_day_id']&&!$c['trip_day_item_id'];if($view==='items')return(bool)$c['trip_day_item_id'];return true;}));
$tripComments=[];$dayGroups=[];foreach($comments as $c){$d=(int)$c['trip_day_id'];$i=(int)$c['trip_day_item_id'];if(!$d){$tripComments[]=$c;continue;}if(!isset($dayGroups[$d]))$dayGroups[$d]=['number'=>(int)$c['day_number'],'title'=>(string)$c['day_title'],'comments'=>[],'items'=>[]];if(!$i){$dayGroups[$d]['comments'][]=$c;continue;}if(!isset($dayGroups[$d]['items'][$i]))$dayGroups[$d]['items'][$i]=['title'=>(string)($c['item_title']?:'Programmpunkt'),'image'=>(string)($c['item_image']??''),'comments'=>[]];$dayGroups[$d]['items'][$i]['comments'][]=$c;}
function comment_cards(array $comments,int $tripId,array $user,string $scopeTitle):void{foreach($comments as $c){$author=trim((string)$c['first_name'].' '.(string)$c['last_name']);$avatar=(string)($c['profile_image']?:'assets/images/triptale-profile-placeholder.png');$url='/trip-comments.php?id='.$tripId.($c['trip_day_item_id']?'&item='.(int)$c['trip_day_item_id']:($c['trip_day_id']?'&day='.(int)$c['trip_day_id']:'&view=trip')).'&comment='.(int)$c['id'];?><article class="comment-card"><div class="comment-card-header"><img class="comment-avatar" src="/<?=htmlspecialchars($avatar,ENT_QUOTES,'UTF-8')?>" alt=""><strong><?=htmlspecialchars($scopeTitle,ENT_QUOTES,'UTF-8')?></strong> – <?=htmlspecialchars($author,ENT_QUOTES,'UTF-8')?><span class="meta"><?=htmlspecialchars(date('d.m.Y H:i',strtotime((string)$c['created_at'])),ENT_QUOTES,'UTF-8')?></span></div><div class="comment-body"><?=render_rich_text((string)$c['body'])?></div><?php if(!empty($c['images'])):?><div class="comment-gallery"><?php foreach($c['images'] as $image):?><img class="comment-gallery-image" src="/<?=htmlspecialchars($image['file_path'],ENT_QUOTES,'UTF-8')?>" alt="Bild zum Kommentar"><?php endforeach;?></div><?php endif;?><?php if((int)$c['user_id']===(int)$user['id']):?><a class="button" href="<?=htmlspecialchars($url,ENT_QUOTES,'UTF-8')?>">Bearbeiten</a><form method="post" class="inline" onsubmit="return confirm('Diesen Kommentar wirklich löschen?');"><input type="hidden" name="csrf_token" value="<?=htmlspecialchars(csrf_token(),ENT_QUOTES,'UTF-8')?>"><input type="hidden" name="action" value="delete"><input type="hidden" name="comment_id" value="<?=(int)$c['id']?>"><button class="delete">Löschen</button></form><?php endif;?></article><?php }}
?><!doctype html><html lang="de"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Kommentare · TripTale</title><style>body{font-family:system-ui,sans-serif;background:#f4f6f8;margin:0;padding:28px;color:#17202a}main{max-width:850px;margin:auto;background:#fff;padding:26px;border-radius:14px}.button,button{display:inline-block;padding:9px 12px;background:#126e82;color:#fff;border:0;border-radius:7px;text-decoration:none;font:inherit;font-weight:700;margin-top:8px}.back{background:#e3ebee;color:#126e82}.comments-filter{position:relative;display:inline-block;margin:14px 0}.comments-filter summary{list-style:none;cursor:pointer;background:#126e82;color:#fff;padding:10px 14px;border-radius:7px;font-weight:700}.comments-filter summary::-webkit-details-marker{display:none}.comments-filter nav{position:absolute;z-index:10;min-width:220px;margin-top:6px;padding:8px;background:#fff;border:1px solid #d6e0e4;border-radius:10px;box-shadow:0 6px 20px #0002}.comments-filter nav a{display:block;padding:10px 12px;color:#17202a;text-decoration:none;border-radius:6px;font-weight:700}.comments-filter nav a:hover{background:#eaf3f4;color:#126e82}.section{margin:22px 0;padding:16px;background:#edf5f6;border-left:4px solid #75aeb9;border-radius:10px}.comment-overview{padding:0;background:#fff;border:0}.comment-group{margin:16px 0;padding:14px;background:#eaf2f8;border-left:6px solid #4c7897;border-radius:10px}.comment-group.trip-group{background:#e7f4f1;border-left-color:#126e82}.comment-group summary,.comment-item summary{list-style:none;cursor:pointer;font-weight:800}.comment-group summary::-webkit-details-marker,.comment-item summary::-webkit-details-marker{display:none}.comment-group summary{display:flex;justify-content:center;gap:10px;align-items:center}.comment-group[open]>summary{margin-bottom:10px}.comment-item{margin:12px 0 0 18px;padding:13px;background:#fbf2e5;border-left:6px solid #b77a2d;border-radius:9px}.comment-item[open]>summary{margin-bottom:10px}.comment-item-title{display:flex;justify-content:center;gap:10px;align-items:center;flex-wrap:wrap}.comment-thumb{width:56px;height:48px;object-fit:contain;background:#fff;border-radius:6px}.comment-item-image{display:block;width:100%;max-height:340px;object-fit:contain;background:#fff;border-radius:8px;margin:0 0 12px}.comment-subtitle{font-weight:700;color:#365c78;margin:6px 0 10px}.comment-item .comment-subtitle{color:#82511c}.comment-card{margin:10px 0;padding:13px;background:#fff;border:1px solid #d6e0e4;border-radius:8px}.comment-card-header{display:flex;justify-content:center;gap:10px;align-items:baseline;flex-wrap:wrap;margin-bottom:8px}.comment-body>*:last-child{margin-bottom:0}.comment-gallery,.edit-image-gallery{display:flex;gap:8px;flex-wrap:wrap;margin:12px 0}.comment-gallery img,.edit-image-gallery img{width:110px;height:90px;object-fit:contain;background:#f4f6f8;border-radius:7px}.comment-gallery-image{cursor:zoom-in}.image-lightbox{position:fixed;inset:0;z-index:50;display:none;align-items:center;justify-content:center;background:rgba(10,20,28,.9);padding:20px}.image-lightbox.open{display:flex}.image-lightbox img{max-width:calc(100vw - 80px);max-height:calc(100vh - 80px);object-fit:contain;border-radius:8px}.image-lightbox button{position:absolute;margin:0;background:#fff;color:#17202a}.lightbox-close{top:16px;right:18px}.lightbox-prev{left:14px}.lightbox-next{right:14px}.image-lightbox button[hidden]{display:none}.edit-image-gallery>div{position:relative}.image-delete{position:absolute;right:-7px;top:-8px;width:25px;height:25px;min-width:25px;padding:0;margin:0;border-radius:50%;background:#9d2d2d;color:#fff;line-height:21px;font-size:20px;font-weight:500;border:2px solid #fff}.image-upload{display:block;margin-top:12px;font-weight:700}.image-upload input{display:block;margin-top:5px}.comment-group .meta,.comment-item .meta{font-weight:400}.meta,.muted{color:#59636d;font-size:.9rem}.delete{background:#9d2d2d}.inline{display:inline;margin-left:8px}.toolbar{display:flex;gap:5px;flex-wrap:wrap;margin-top:8px;padding:7px;border:1px solid #b9c1c8;border-bottom:0;border-radius:7px 7px 0 0;background:#edf2f3}.toolbar button{margin:0;padding:6px 9px;background:#fff;color:#17202a;border:1px solid #b9c1c8;border-radius:4px}.editor{min-height:130px;padding:11px;border:1px solid #b9c1c8;border-radius:0 0 7px 7px}.success{background:#e6f5e9;padding:10px;border-radius:7px}@media(max-width:600px){body{padding:12px}main{padding:16px}.comment-item{margin-left:10px}.comment-group{padding:12px}.comment-card-header{display:block}.comment-card-header .meta{display:block;margin-top:3px}}</style></head><body><main><a class="button back" href="/trip.php?id=<?=$tripId?>">← Zurück zur Reise</a><h1>Kommentare</h1><p class="muted"><?=htmlspecialchars((string)$trip['title'],ENT_QUOTES,'UTF-8')?></p><?php $selectedLabel=$view==='trip'?'Zur Reise':($view==='days'?'Zu Tagen':($view==='items'?'Zu Programmpunkten':($itemId?'Zum Programmpunkt':($dayId?'Zum Tag':'Alle Kommentare'))));?><details class="comments-filter"><summary><?=htmlspecialchars($selectedLabel,ENT_QUOTES,'UTF-8')?> ▾</summary><nav><a href="?id=<?=$tripId?>">Alle Kommentare</a><a href="?id=<?=$tripId?>&view=trip">Zur Reise</a><a href="?id=<?=$tripId?>&view=days">Zu Tagen</a><a href="?id=<?=$tripId?>&view=items">Zu Programmpunkten</a></nav></details><?php if(isset($_GET['saved'])):?><p class="success">Kommentar gespeichert.</p><?php endif;?><?php if($error):?><p><?=htmlspecialchars($error,ENT_QUOTES,'UTF-8')?></p><?php endif;?><?php if($view==='trip'||$dayId||$itemId):?><section class="section"><h2><?=$itemId?'Kommentar zum Programmpunkt':($dayId?'Kommentar zum Tag':'Kommentar zur Reise')?></h2><?php if($contextTitle):?><p><?=htmlspecialchars($contextTitle,ENT_QUOTES,'UTF-8')?></p><?php endif;?><form method="post" enctype="multipart/form-data" id="comment-form"><input type="hidden" name="csrf_token" value="<?=htmlspecialchars(csrf_token(),ENT_QUOTES,'UTF-8')?>"><input type="hidden" name="comment_id" value="<?=(int)$editId?>"><input type="hidden" name="body" id="body-value"><div class="toolbar"><button type="button" data-command="bold"><b>Fett</b></button><button type="button" data-command="italic"><i>Kursiv</i></button><button type="button" data-command="insertUnorderedList">Liste</button><button type="button" data-command="insertOrderedList">1. Liste</button><button type="button" id="link">Link</button><select id="style"><option value="">Textstil…</option><option value="p">Normal</option><option value="h2">Überschrift</option><option value="h3">Kleine Überschrift</option></select></div><div id="editor" class="editor" contenteditable="true"><?=render_rich_text((string)($_POST['body']??$edit['body']))?></div><label class="image-upload">Bilder <span class="muted">(maximal 3, je 10 MB)</span><input type="file" id="images" data-existing="<?=count($editImages)?>" name="images[]" accept="image/jpeg,image/png,image/webp" multiple></label><?php if($editImages):?><div class="edit-image-gallery"><?php foreach($editImages as $image):?><div><img src="/<?=htmlspecialchars($image['file_path'],ENT_QUOTES,'UTF-8')?>" alt=""><button class="image-delete" type="submit" name="delete_image_id" value="<?=(int)$image['id']?>" aria-label="Bild löschen" title="Bild löschen" onclick="return confirm('Dieses Bild wirklich löschen?');">×</button></div><?php endforeach;?></div><?php endif;?><button>Speichern</button></form></section><?php endif;?><section class="section comment-overview"><h2><?=$view==='trip'?'Kommentare zur Reise':($dayId?'Kommentare zum Tag':($itemId?'Kommentare zum Programmpunkt':($view==='days'?'Kommentare zu Tagen':($view==='items'?'Kommentare zu Programmpunkten':'Alle Kommentare'))))?></h2><?php if(!$comments):?><p class="muted">Noch keine Kommentare vorhanden.</p><?php endif;?><?php if($tripComments):?><details class="comment-group trip-group"<?= $view==='trip'?' open':'' ?>><summary><span>Zur Reise</span><span class="meta"><?=count($tripComments)?> Kommentar<?=count($tripComments)===1?'':'e'?></span></summary><?php comment_cards($tripComments,$tripId,$user,'Zur Reise');?></details><?php endif;?><?php foreach($dayGroups as $day):$dayLabel='Tag '.$day['number'].($day['title']!==''?' · '.$day['title']:'');$dayOpen=$view==='days'||$dayId;$count=count($day['comments'])+array_sum(array_map(static fn(array $item):int=>count($item['comments']),$day['items']));?><details class="comment-group"<?=$dayOpen?' open':''?>><summary><span><?=htmlspecialchars($dayLabel,ENT_QUOTES,'UTF-8')?></span><span class="meta"><?=$count?> Kommentar<?=$count===1?'':'e'?></span></summary><?php if($day['comments']):?><p class="comment-subtitle">Kommentare zum Tag</p><?php comment_cards($day['comments'],$tripId,$user,$dayLabel);?><?php endif;?><?php foreach($day['items'] as $item):?><details class="comment-item"<?=($itemId&&$view==='item')?' open':''?>><summary><span class="comment-item-title"><?php if($item['image']):?><img class="comment-thumb" src="/<?=htmlspecialchars($item['image'],ENT_QUOTES,'UTF-8')?>" alt=""><?php endif;?><span><?=htmlspecialchars($item['title'],ENT_QUOTES,'UTF-8')?></span><span class="meta"><?=count($item['comments'])?> Kommentar<?=count($item['comments'])===1?'':'e'?></span></span></summary><?php if($item['image']):?><img class="comment-item-image" src="/<?=htmlspecialchars($item['image'],ENT_QUOTES,'UTF-8')?>" alt=""><?php endif;?><p class="comment-subtitle">Kommentare zum Programmpunkt</p><?php comment_cards($item['comments'],$tripId,$user,$item['title']);?></details><?php endforeach;?></details><?php endforeach;?></section></main><script>const e=document.getElementById('editor');if(e){document.querySelectorAll('[data-command]').forEach(b=>b.onclick=()=>{e.focus();document.execCommand(b.dataset.command,false);});document.getElementById('style').onchange=function(){if(this.value){e.focus();document.execCommand('formatBlock',false,'<'+this.value+'>');this.value='';}};document.getElementById('link').onclick=()=>{const u=prompt('https://');if(u){e.focus();document.execCommand('createLink',false,u);}};document.getElementById('comment-form').onsubmit=()=>document.getElementById('body-value').value=e.innerHTML;}document.querySelectorAll('.comment-overview > details.comment-group:not(.trip-group)').forEach(group=>group.addEventListener('toggle',()=>{if(group.open)document.querySelectorAll('.comment-overview > details.comment-group:not(.trip-group)').forEach(other=>{if(other!==group)other.removeAttribute('open');});}));document.querySelectorAll('details.comment-item').forEach(item=>item.addEventListener('toggle',()=>{if(item.open)document.querySelectorAll('details.comment-item').forEach(other=>{if(other!==item)other.removeAttribute('open');});}));const galleryImages=[...document.querySelectorAll('.comment-gallery-image')];if(galleryImages.length){let activeImages=[],activeImageIndex=0;const lightbox=document.createElement('div');lightbox.className='image-lightbox';lightbox.innerHTML='<button type="button" class="lightbox-close" aria-label="Schließen">×</button><button type="button" class="lightbox-prev" aria-label="Vorheriges Bild">‹</button><img alt="Bild zum Kommentar"><button type="button" class="lightbox-next" aria-label="Nächstes Bild">›</button>';document.body.append(lightbox);const image=lightbox.querySelector('img'),previous=lightbox.querySelector('.lightbox-prev'),next=lightbox.querySelector('.lightbox-next');const show=()=>{image.src=activeImages[activeImageIndex].src;previous.hidden=next.hidden=activeImages.length<2;};const close=()=>lightbox.classList.remove('open');galleryImages.forEach(imageElement=>imageElement.addEventListener('click',()=>{activeImages=[...imageElement.closest('.comment-gallery').querySelectorAll('.comment-gallery-image')];activeImageIndex=activeImages.indexOf(imageElement);show();lightbox.classList.add('open');}));previous.onclick=()=>{activeImageIndex=(activeImageIndex-1+activeImages.length)%activeImages.length;show();};next.onclick=()=>{activeImageIndex=(activeImageIndex+1)%activeImages.length;show();};lightbox.querySelector('.lightbox-close').onclick=close;lightbox.addEventListener('click',event=>{if(event.target===lightbox)close();});document.addEventListener('keydown',event=>{if(!lightbox.classList.contains('open'))return;if(event.key==='Escape')close();if(event.key==='ArrowLeft')previous.click();if(event.key==='ArrowRight')next.click();});}const imageInput=document.getElementById('images');if(imageInput){imageInput.addEventListener('change',()=>{const existing=Number(imageInput.dataset.existing||0);if(existing+imageInput.files.length>3){alert('Du kannst insgesamt höchstens drei Bilder speichern. Bereits vorhanden: '+existing+'.');imageInput.value='';}});}</script></body></html>
