<?php
declare(strict_types=1);
require __DIR__.'/../api/bootstrap.php';
header('Content-Type: text/html; charset=utf-8');header('Cache-Control: no-store, private');header('X-Robots-Tag: noindex, nofollow, noarchive');header('X-Frame-Options: DENY');
header("Content-Security-Policy: default-src 'self'; style-src 'self'; form-action 'self'; frame-ancestors 'none'; base-uri 'none'");
set_exception_handler(function(Throwable $e): void {error_log('Hugo admin: '.$e->getMessage());http_response_code(503);echo 'Painel temporariamente indisponível. Tente novamente.';});
session_name('hugo_admin');session_start(['use_strict_mode'=>true,'cookie_httponly'=>true,'cookie_secure'=>(!empty($_SERVER['HTTPS'])&&$_SERVER['HTTPS']!=='off'),'cookie_samesite'=>'Strict','cookie_path'=>'/admin/']);
$pdo=db();
if(!$pdo->query("SELECT 1 FROM admin_users WHERE username='admin'")->fetchColumn()){
 $s=$pdo->prepare('INSERT OR IGNORE INTO admin_users(username,password_hash) VALUES(?,?)');$s->execute(['admin',password_hash('0000',PASSWORD_DEFAULT)]);
}
$user=$pdo->query("SELECT * FROM admin_users WHERE username='admin'")->fetch();
if(!isset($_SESSION['csrf']))$_SESSION['csrf']=bin2hex(random_bytes(32));
if(isset($_SESSION['admin']) && (time()-($_SESSION['last_seen']??0)>1800 || ($_SESSION['version']??0)!==(int)$user['version']))unset($_SESSION['admin']);
$logged=($_SESSION['admin']??false)===true;if($logged)$_SESSION['last_seen']=time();
$error='';$notice=$_SESSION['notice']??'';unset($_SESSION['notice']);
function post(string $k): string {return isset($_POST[$k])&&is_string($_POST[$k])?trim($_POST[$k]):'';}
function csrf_field(): void {echo '<input type="hidden" name="csrf" value="'.e($_SESSION['csrf']).'">';}
function finish(string $message,string $view='leads'): never {$_SESSION['notice']=$message;header('Location: /admin/?view='.$view,true,303);exit;}
function date_input(string $key,string $fallback): string {
 $v=isset($_GET[$key])&&is_string($_GET[$key])?$_GET[$key]:$fallback;$d=DateTimeImmutable::createFromFormat('!Y-m-d',$v);return $d&&$d->format('Y-m-d')===$v?$v:$fallback;
}
$statuses=['novo'=>'Novo','em_atendimento'=>'Em atendimento','proposta'=>'Proposta enviada','ganho'=>'Ganho','perdido'=>'Perdido'];
if($_SERVER['REQUEST_METHOD']==='POST'){
 if(!hash_equals($_SESSION['csrf'],post('csrf'))){http_response_code(403);$error='Sessão inválida. Atualize a página e tente novamente.';}
 elseif(post('action')==='login'&&!$logged){
  $now=time();$bucket='admin-login:'.hash('sha256',$_SERVER['REMOTE_ADDR']??'unknown');
  $s=$pdo->prepare('DELETE FROM rate_limits WHERE bucket=? AND expires<?');$s->execute([$bucket,$now]);
  $s=$pdo->prepare('INSERT INTO rate_limits(bucket,hits,expires) VALUES(?,1,?) ON CONFLICT(bucket) DO UPDATE SET hits=hits+1 RETURNING hits');$s->execute([$bucket,$now+900]);$hits=(int)$s->fetchColumn();$s->closeCursor();
  if($hits>5){http_response_code(429);$error='Muitas tentativas. Aguarde 15 minutos.';}
  elseif(post('username')==='admin'&&strlen(post('password'))<=1024&&password_verify(post('password'),$user['password_hash'])){
   session_regenerate_id(true);$_SESSION['csrf']=bin2hex(random_bytes(32));$_SESSION['admin']=true;$_SESSION['version']=(int)$user['version'];$_SESSION['last_seen']=time();
   $s=$pdo->prepare('DELETE FROM rate_limits WHERE bucket=?');$s->execute([$bucket]);finish('Bem-vindo ao painel.');
  }else{$error='Usuário ou senha incorretos.';}
 }elseif(!$logged){http_response_code(401);$error='Entre para continuar.';}
 elseif(post('action')==='logout'){
  $_SESSION=[];session_destroy();setcookie(session_name(),'', ['expires'=>time()-3600,'path'=>'/admin/','httponly'=>true,'samesite'=>'Strict','secure'=>(!empty($_SERVER['HTTPS'])&&$_SERVER['HTTPS']!=='off')]);header('Location: /admin/',true,303);exit;
 }elseif(post('action')==='password'){
  $new=post('new_password');
  if(!password_verify(post('current_password'),$user['password_hash']))$error='Senha atual incorreta.';
  elseif(strlen($new)<4||strlen($new)>128||$new!==post('confirm_password'))$error='Use de 4 a 128 caracteres e repita a nova senha corretamente.';
  else{$s=$pdo->prepare("UPDATE admin_users SET password_hash=?,version=version+1 WHERE username='admin'");$s->execute([password_hash($new,PASSWORD_DEFAULT)]);$_SESSION['version']=(int)$user['version']+1;session_regenerate_id(true);$_SESSION['csrf']=bin2hex(random_bytes(32));finish('Senha alterada. Outros acessos foram encerrados.','settings');}
 }elseif(post('action')==='email'){
  $sender=post('email_sender');$list=preg_split('/[\s,;]+/',post('email_recipients'),-1,PREG_SPLIT_NO_EMPTY);$list=array_values(array_unique($list));$enabled=post('email_enabled')==='1';
  if(count($list)>10)$error='Cadastre até 10 destinatários.';
  foreach(array_merge($list,$sender!==''?[$sender]:[]) as $address)if(strlen($address)>254||!filter_var($address,FILTER_VALIDATE_EMAIL)||preg_match('/[\r\n]/',$address))$error='Confira os endereços de e-mail.';
  if($enabled&&(!$list||$sender===''))$error='Para ativar, informe remetente e destinatários.';
  if(!$error){$pdo->beginTransaction();save_setting($pdo,'email_sender',$sender);save_setting($pdo,'email_recipients',json_encode($list));save_setting($pdo,'email_enabled',$enabled?'1':'0');$pdo->commit();finish('Configuração salva. Será aplicada aos novos leads.','settings');}
 }elseif(post('action')==='status'){
  if(!isset($statuses[post('status')]))$error='Status inválido.';
  else{$s=$pdo->prepare('UPDATE leads SET status=? WHERE id=?');$s->execute([post('status'),(int)post('id')]);finish('Status atualizado.');}
 }elseif(post('action')==='retry'){
  deliver_notification($pdo,(int)post('id'),true);finish('Tentativa processada. Confira o resultado abaixo.','notifications');
 }
}
$view=isset($_GET['view'])&&is_string($_GET['view'])?$_GET['view']:'leads';if(!in_array($view,['leads','pages','settings','notifications'],true))$view='leads';
$from=date_input('from',gmdate('Y-m-d',strtotime('-29 days')));$to=date_input('to',gmdate('Y-m-d'));if($from>$to){[$from,$to]=[$to,$from];}
$until=(new DateTimeImmutable($to))->modify('+1 day')->format('Y-m-d');$where='created_at >= :from AND created_at < :until';$params=['from'=>$from,'until'=>$until];
$search=isset($_GET['q'])&&is_string($_GET['q'])?mb_substr(trim($_GET['q']),0,120):'';
$status=isset($_GET['status'])&&is_string($_GET['status'])&&isset($statuses[$_GET['status']])?$_GET['status']:'';
if($search!==''){$where.=' AND (nome LIKE :q OR telefone LIKE :q OR tema LIKE :q OR cidade LIKE :q OR pagina_origem LIKE :q OR empresa LIKE :q)';$params['q']='%'.$search.'%';}
if($status!==''){$where.=' AND status=:status';$params['status']=$status;}
if($logged&&($_GET['export']??'')==='csv'){
 header('Content-Type: text/csv; charset=utf-8');header('Content-Disposition: attachment; filename="leads-hugo.csv"');
 $s=$pdo->prepare('SELECT id,created_at,nome,empresa,telefone,email,tipo_evento,tema,tema_inicial,cidade,estado,pagina_origem,utm_source,utm_medium,utm_campaign,status FROM leads WHERE '.$where.' ORDER BY id DESC');$s->execute($params);
 $stream=fopen('php://output','w');fwrite($stream,"\xEF\xBB\xBF");$header=false;
 while($r=$s->fetch()){if(!$header){fputcsv($stream,array_keys($r),';','"','');$header=true;}foreach($r as &$v){$v=(string)$v;if(preg_match('/^[\s]*[=+@-]/u',$v))$v="'".$v;}unset($v);fputcsv($stream,array_values($r),';','"','');}fclose($stream);exit;
}
?><!doctype html><html lang="pt-BR"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="robots" content="noindex,nofollow"><title>Painel | Hugo Santos</title><link rel="stylesheet" href="/assets/css/admin.css"></head><body>
<header><a href="/admin/" class="brand">Hugo Santos <small>Área administrativa</small></a><?php if($logged): ?><form method="post"><?php csrf_field(); ?><input type="hidden" name="action" value="logout"><button>Sair</button></form><?php endif ?></header>
<main><?php if($notice): ?><p class="notice" role="status"><?= e($notice) ?></p><?php endif ?><?php if($error): ?><p class="error" role="alert"><?= e($error) ?></p><?php endif ?>
<?php if(!$logged): ?><section class="login"><h1>Entrar no painel</h1><p>Leads, acessos e notificações em um só lugar.</p><form method="post"><?php csrf_field(); ?><input type="hidden" name="action" value="login"><label>Usuário<input name="username" autocomplete="username" required maxlength="120"></label><label>Senha<input name="password" type="password" autocomplete="current-password" required maxlength="128"></label><button class="primary">Entrar</button></form></section>
<?php else: ?><nav aria-label="Painel"><?php foreach(['leads'=>'Leads','pages'=>'Acessos por página','notifications'=>'Notificações','settings'=>'Configurações'] as $key=>$label): ?><a <?= $key===$view?'aria-current="page"':'' ?> href="/admin/?view=<?= $key ?>"><?= $label ?></a><?php endforeach ?></nav>
<?php if(password_verify('0000',$user['password_hash'])): ?><p class="notice">A senha inicial está ativa. Você pode alterá-la em <a href="/admin/?view=settings">Configurações</a>.</p><?php endif ?>
<?php if(in_array($view,['leads','pages'],true)): ?><form method="get" class="filters"><input type="hidden" name="view" value="<?= e($view) ?>"><label>De<input type="date" name="from" value="<?= e($from) ?>"></label><label>Até<input type="date" name="to" value="<?= e($to) ?>"></label><?php if($view==='leads'): ?><label>Buscar<input name="q" value="<?= e($search) ?>" placeholder="Nome, tema, cidade ou página"></label><label>Status<select name="status"><option value="">Todos</option><?php foreach($statuses as $key=>$label): ?><option value="<?= $key ?>" <?= $status===$key?'selected':'' ?>><?= e($label) ?></option><?php endforeach ?></select></label><?php endif ?><button>Filtrar</button></form><p class="muted">Datas e horários em UTC. Período inclusivo.</p><?php endif ?>
<?php if($view==='leads'):
 $s=$pdo->prepare('SELECT count(*) FROM leads WHERE '.$where);$s->execute($params);$total=(int)$s->fetchColumn();$page=max(1,min(max(1,(int)ceil($total/25)),(int)($_GET['page']??1)));$offset=($page-1)*25;
 $s=$pdo->prepare('SELECT * FROM leads WHERE '.$where.' ORDER BY id DESC LIMIT 25 OFFSET '.$offset);$s->execute($params);$leads=$s->fetchAll();
 ?><div class="heading"><h1>Leads <span><?= $total ?></span></h1><a class="button" href="/admin/?<?= e(http_build_query(['view'=>'leads','from'=>$from,'to'=>$to,'q'=>$search,'status'=>$status,'export'=>'csv'])) ?>">Exportar CSV</a></div>
 <?php if(!$leads): ?><p>Nenhum lead neste filtro.</p><?php endif ?>
 <?php foreach($leads as $lead): ?><article class="lead"><div class="heading"><h2>#<?= (int)$lead['id'] ?> · <?= e($lead['nome']) ?></h2><span><?= e($lead['created_at']) ?></span></div><p><strong><?= e($lead['tema']) ?></strong> · <?= e($lead['cidade']) ?><?= $lead['estado']?' / '.e($lead['estado']):'' ?> · <?= e($lead['telefone']) ?></p><p class="muted"><?= e($lead['pagina_origem']) ?></p><details><summary>Ver detalhes e atualizar status</summary><dl><?php foreach(['empresa'=>'Empresa','email'=>'E-mail','tipo_evento'=>'Formato','tema_inicial'=>'Tema sugerido','data_evento'=>'Data do evento','participantes'=>'Participantes','referrer'=>'Origem','utm_source'=>'UTM origem','utm_medium'=>'UTM meio','utm_campaign'=>'Campanha'] as $key=>$label): ?><dt><?= e($label) ?></dt><dd><?= e((string)($lead[$key]??''))?:'Não informado' ?></dd><?php endforeach ?></dl><form method="post" class="inline"><?php csrf_field(); ?><input type="hidden" name="action" value="status"><input type="hidden" name="id" value="<?= (int)$lead['id'] ?>"><label>Status<select name="status"><?php foreach($statuses as $key=>$label): ?><option value="<?= $key ?>" <?= $lead['status']===$key?'selected':'' ?>><?= e($label) ?></option><?php endforeach ?></select></label><button>Salvar status</button><a target="_blank" rel="noopener noreferrer" href="https://wa.me/<?= e(strlen($lead['telefone'])<=11?'55'.$lead['telefone']:$lead['telefone']) ?>">Abrir WhatsApp</a></form></details><p>Status: <?= e($statuses[$lead['status']]??$lead['status']) ?></p></article><?php endforeach ?>
 <p>Página <?= $page ?> de <?= max(1,(int)ceil($total/25)) ?></p><div class="inline"><?php foreach([$page-1=>'Anterior',$page+1=>'Próxima'] as $n=>$label): if($n<1||$n>ceil($total/25))continue; ?><a href="/admin/?<?= e(http_build_query(['view'=>'leads','from'=>$from,'to'=>$to,'q'=>$search,'status'=>$status,'page'=>$n])) ?>"><?= $label ?></a><?php endforeach ?></div>
<?php elseif($view==='pages'):
 $s=$pdo->prepare('SELECT url,count(*) AS views,count(DISTINCT session_id) AS visitors FROM page_views WHERE created_at>=? AND created_at<? GROUP BY url');$s->execute([$from,$until]);$views=array_column($s->fetchAll(),null,'url');
 $s=$pdo->prepare('SELECT pagina_origem,count(*) AS leads FROM leads WHERE created_at>=? AND created_at<? GROUP BY pagina_origem');$s->execute([$from,$until]);$counts=array_column($s->fetchAll(),'leads','pagina_origem');$urls=array_unique(array_merge(array_column(data('pages'),'url'),array_keys($views),array_keys($counts)));
 ?><h1>Acessos e leads por página</h1><p>Acessos e visitantes incluem somente a medição autorizada. Leads incluem todos os pedidos registrados. Não calculamos uma taxa geral usando populações diferentes.</p><div class="stats"><p><strong><?= array_sum(array_column($views,'views')) ?></strong> acessos consentidos</p><p><strong><?= array_sum($counts) ?></strong> leads registrados</p></div><div class="table-wrap"><table><thead><tr><th>Página</th><th>Acessos consentidos</th><th>Visitantes por sessão</th><th>Leads</th></tr></thead><tbody><?php foreach($urls as $url): ?><tr><td><?= e($url) ?></td><td><?= (int)($views[$url]['views']??0) ?></td><td><?= (int)($views[$url]['visitors']??0) ?></td><td><?= (int)($counts[$url]??0) ?></td></tr><?php endforeach ?></tbody></table></div>
<?php elseif($view==='settings'): ?><h1>Configurações</h1><section><h2>Notificações de novos leads</h2><p>Envie uma notificação para cada destinatário quando um novo lead for registrado. Use um remetente autorizado na hospedagem.</p><form method="post"><?php csrf_field(); ?><input type="hidden" name="action" value="email"><label class="check"><input type="checkbox" name="email_enabled" value="1" <?= setting($pdo,'email_enabled')==='1'?'checked':'' ?>> Ativar notificações</label><label>E-mail remetente<input type="email" name="email_sender" value="<?= e(setting($pdo,'email_sender')) ?>" maxlength="254" placeholder="E-mail autorizado na hospedagem"></label><label>Destinatários<textarea name="email_recipients" rows="5" maxlength="2600" placeholder="Um e-mail por linha, até 10"><?= e(implode("\n",json_decode(setting($pdo,'email_recipients','[]'),true)?:[])) ?></textarea></label><button class="primary">Salvar notificações</button></form><p class="muted">O envio usa o serviço de e-mail do servidor PHP. A hospedagem precisa habilitá-lo; cadastrar destinatários sozinho não configura o transporte. O painel registra aceitação pelo servidor ou falha, não confirmação de entrega na caixa postal. Notificações desativadas não geram envios retroativos.</p></section><section><h2>Alterar senha</h2><p>Usuário: admin</p><form method="post"><?php csrf_field(); ?><input type="hidden" name="action" value="password"><label>Senha atual<input type="password" name="current_password" autocomplete="current-password" required></label><label>Nova senha<input type="password" name="new_password" autocomplete="new-password" minlength="4" maxlength="128" required></label><label>Confirmar nova senha<input type="password" name="confirm_password" autocomplete="new-password" minlength="4" maxlength="128" required></label><button>Alterar senha</button></form></section>
<?php elseif($view==='notifications'):
 $rows=$pdo->query('SELECT * FROM lead_notifications ORDER BY id DESC LIMIT 100')->fetchAll();$names=['pending'=>'Pendente','sending'=>'Em processamento — verificar antes de reenviar','accepted'=>'Aceita pelo servidor','failed'=>'Falha no envio'];
 ?><h1>Notificações</h1><p>Últimas 100 notificações. Aceitação pelo servidor não confirma chegada à caixa de entrada. Falhas podem ser reenviadas após corrigir a configuração da hospedagem.</p><?php if(!$rows): ?><p>Nenhuma notificação registrada. Configure os destinatários para os próximos leads.</p><?php endif ?><div class="table-wrap"><table><thead><tr><th>Lead</th><th>Destinatário</th><th>Estado</th><th>Tentativas</th><th>Ação</th></tr></thead><tbody><?php foreach($rows as $r): ?><tr><td>#<?= (int)$r['lead_id'] ?></td><td><?= e($r['recipient']) ?></td><td><?= e($names[$r['state']]??$r['state']) ?></td><td><?= (int)$r['attempts'] ?></td><td><?php if(in_array($r['state'],['pending','failed'],true)): ?><form method="post"><?php csrf_field(); ?><input type="hidden" name="action" value="retry"><input type="hidden" name="id" value="<?= (int)$r['id'] ?>"><button>Tentar envio</button></form><?php endif ?></td></tr><?php endforeach ?></tbody></table></div>
<?php endif; endif ?></main></body></html>
