<?php
// index.php - Calculadora Científica com logging em calculadora.log
// Se for POST com log_entry, grava no ficheiro e devolve JSON
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['log_entry'])) {
    $entry = trim($_POST['log_entry']);
    // simples sanitização (remove linhas novas perigosas)
    $entry = str_replace(array("\r","\n"), ' ', $entry);
    $logfile = __DIR__ . '/calculadora.log';
    $line = sprintf("[%s] %s\n", date('Y-m-d H:i:s'), $entry);
    file_put_contents($logfile, $line, FILE_APPEND | LOCK_EX);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode(['ok' => true]);
    exit;
}
?>
<!DOCTYPE html>
<html lang="pt-PT">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Calculadora Científica — Reiko Edition</title>
<style>
:root{
  --bg:#0b0f14; --panel:#0f1720; --muted:#9aa6bb; --text:#e6eef6;
  --accent:#00d1c5; --accent-2:#7cf0e0; --danger:#ff6b6b; --card-radius:12px;
  --sidebar:#16181c; --btn-bg:#1f2a36;
}
*{box-sizing:border-box}
html,body{height:100%; margin:0; font-family:Inter, "Segoe UI", Roboto, system-ui, Arial; background:var(--bg); color:var(--text);}
.app{display:flex; min-height:100vh;}
.sidebar{
  width:260px; background:linear-gradient(180deg,var(--sidebar),#0e1114); padding:22px; border-right:1px solid rgba(255,255,255,0.03);
  display:flex; flex-direction:column; gap:14px;
}
.logo{font-weight:900; color:var(--accent); font-size:18px; letter-spacing:0.6px}
.menu{display:flex; flex-direction:column; gap:8px; margin-top:8px}
.menu a{ text-decoration:none; color:var(--text); background:var(--btn-bg); padding:10px 12px; border-radius:999px; display:block; font-weight:700; text-align:left; transition:all .12s; border:1px solid rgba(255,255,255,0.02) }
.menu a:hover{ transform:translateY(-3px); color:#021016; background:linear-gradient(180deg,var(--accent), #06b7a9) }

.container{flex:1; padding:26px; display:grid; grid-template-columns: 480px 1fr; gap:20px}
@media(max-width:980px){ .container{ grid-template-columns: 1fr } .sidebar{ width:100%; order: -1; flex-direction:row; align-items:center; padding:12px } .menu{ flex-direction:row; gap:6px; overflow:auto } .menu a{ white-space:nowrap } }

.card{
  background: linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01));
  padding:16px; border-radius:12px; border:1px solid rgba(255,255,255,0.03);
}

/* display */
.display{ background:linear-gradient(180deg,#07131a,#0c1720); padding:16px; border-radius:10px; min-height:120px; color:var(--text) }
.expr{ color:var(--muted); min-height:22px; word-break:break-all }
.res{ font-size:32px; margin-top:8px; color:var(--accent); font-weight:800; word-break:break-all }

/* controls */
.controls{ display:flex; gap:8px; flex-wrap:wrap; margin-top:12px }
.btn{ background:transparent; border:1px solid rgba(255,255,255,0.04); color:var(--text); padding:8px 12px; border-radius:10px; cursor:pointer; font-weight:700 }
.btn.primary{ background:linear-gradient(180deg,var(--accent), #06b7a9); color:#021016; border:none }
.btn.ghost{ border-style:dashed }

/* keys */
.keys{ display:grid; grid-template-columns: repeat(6, 1fr); gap:10px; margin-top:14px }
.key{ background:linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01)); padding:12px; border-radius:10px; text-align:center; cursor:pointer; font-weight:700; border:1px solid rgba(255,255,255,0.02) }
.key.fn{ color:#ffd8a8 } .key.op{ color:var(--accent-2) } .key.danger{ color:var(--danger) }
.key.wide{ grid-column: span 2 }

/* right column */
.history{ max-height:520px; overflow:auto; padding:8px; display:flex; flex-direction:column; gap:8px }
.hist-item{ display:flex; justify-content:space-between; gap:8px; align-items:center; padding:8px; background:rgba(255,255,255,0.02); border-radius:8px }
.small{ font-size:13px; color:var(--muted) }
.footer{ margin-top:12px; display:flex; justify-content:space-between; align-items:center; gap:10px; color:var(--muted) }

/* light theme */
body.light{ --bg:#f5f7fb; --panel:#ffffff; --muted:#556073; --text:#0b1220; --accent:#0b9fa6; --accent-2:#06969a; --sidebar:#ffffff; --btn-bg:#eef2f6 }
body.light .menu a:hover{ color:#fff; }
</style>
</head>
<body>
<div class="app">
  <aside class="sidebar">
    <div class="logo">Reiko · Calculadora</div>
    <nav class="menu">
      <a href="#" id="menuHome">Início</a>
      <a href="#" id="menuCalc">Calculadora</a>
      <a href="#" id="menuLogs">Logs</a>
      <a href="#" id="menuAbout">Sobre</a>
    </nav>

    <div style="margin-top:auto; display:flex; gap:8px; align-items:center">
      <button id="themeToggle" class="btn ghost">Tema</button>
      <button id="exportLog" class="btn">Exportar Log</button>
    </div>
  </aside>

  <main class="container">
    <!-- LEFT: calculadora -->
    <section class="card">
      <div style="display:flex;justify-content:space-between;align-items:center">
        <div style="font-weight:900; color:var(--accent)">Calculadora Científica</div>
        <div class="small">Modo: <span id="modeLabel">DEG</span></div>
      </div>

      <div class="display" id="display">
        <div class="expr" id="expr"></div>
        <div class="res" id="res">0</div>
      </div>

      <div class="controls">
        <button class="btn" id="mc">MC</button>
        <button class="btn" id="mr">MR</button>
        <button class="btn" id="mplus">M+</button>
        <button class="btn" id="mminus">M-</button>
        <button class="btn" id="ans">ANS</button>
        <button class="btn" id="copy">Copiar</button>
        <button class="btn danger" id="clear">C</button>
        <button class="btn" id="del">⌫</button>
      </div>

      <div class="keys" id="keys">
        <div class="key fn" data-val="sin(">sin</div>
        <div class="key fn" data-val="cos(">cos</div>
        <div class="key fn" data-val="tan(">tan</div>
        <div class="key fn" data-val="asin(">asin</div>
        <div class="key fn" data-val="acos(">acos</div>
        <div class="key fn" data-val="atan(">atan</div>

        <div class="key fn" data-val="ln(">ln</div>
        <div class="key fn" data-val="log10(">log</div>
        <div class="key fn" data-val="sqrt(">√</div>
        <div class="key op" data-val="(">(</div>
        <div class="key op" data-val=")">)</div>
        <div class="key op" data-val="^">^</div>

        <div class="key" data-val="7">7</div>
        <div class="key" data-val="8">8</div>
        <div class="key" data-val="9">9</div>
        <div class="key op" data-val="/">÷</div>
        <div class="key op" data-val="%">%</div>
        <div class="key" data-val="factorial()">n!</div>

        <div class="key" data-val="4">4</div>
        <div class="key" data-val="5">5</div>
        <div class="key" data-val="6">6</div>
        <div class="key op" data-val="*">×</div>
        <div class="key" data-val="pi">π</div>
        <div class="key" data-val="e">e</div>

        <div class="key" data-val="1">1</div>
        <div class="key" data-val="2">2</div>
        <div class="key" data-val="3">3</div>
        <div class="key op" data-val="-">−</div>
        <div class="key" data-val="abs(">abs</div>
        <div class="key" data-val="rnd()">rnd</div>

        <div class="key wide" data-val="0">0</div>
        <div class="key" data-val=".">.</div>
        <div class="key op" data-val="+">+</div>
        <div class="key" data-val="1/(" title="inverse">1/x</div>
        <div class="key op" data-val="!">!</div>

        <div class="key wide primary" id="equals">=</div>
        <div class="key" data-val="pow(">pow(</div>
        <div class="key" data-val="root(">root(</div>
        <div class="key" data-val=",">,</div>
        <div class="key" data-val="pi/2">π/2</div>
      </div>
    </section>

    <!-- RIGHT: histórico + logs -->
    <section class="card">
      <div style="display:flex;justify-content:space-between;align-items:center">
        <div style="font-weight:900; color:var(--accent)">Histórico (local)</div>
        <div class="small">Últimos cálculos</div>
      </div>

      <div class="history" id="history">
        <div style="padding:12px;color:var(--muted)">Sem histórico — faz um cálculo.</div>
      </div>

      <div class="footer">
        <div class="small">Os resultados são gravados em <code>calculadora.log</code> no servidor.</div>
        <div><button id="clearHist" class="btn ghost">Limpar histórico</button></div>
      </div>
    </section>
  </main>
</div>

<script>
// estado
let expr = '';
let lastAns = 0;
let memory = 0;
let mode = localStorage.getItem('calc_mode') || 'DEG';
const hist = [];

// elementos
const exprEl = document.getElementById('expr');
const resEl = document.getElementById('res');
const historyEl = document.getElementById('history');
const modeLabel = document.getElementById('modeLabel');

// utilitários
const pad = n => String(n).padStart(2,'0');
function factorialNum(n){
  n = Math.floor(n);
  if(n < 0) return NaN;
  let r = 1; for(let i=2;i<=n;i++) r *= i;
  return r;
}
function toRad(v){ return v * Math.PI / 180; }
function sin(x){ return mode==='DEG' ? Math.sin(toRad(x)) : Math.sin(x); }
function cos(x){ return mode==='DEG' ? Math.cos(toRad(x)) : Math.cos(x); }
function tan(x){ return mode==='DEG' ? Math.tan(toRad(x)) : Math.tan(x); }
function asin(x){ return mode==='DEG' ? Math.asin(x) * 180/Math.PI : Math.asin(x); }
function acos(x){ return mode==='DEG' ? Math.acos(x) * 180/Math.PI : Math.acos(x); }
function atan(x){ return mode==='DEG' ? Math.atan(x) * 180/Math.PI : Math.atan(x); }
function ln(x){ return Math.log(x); }
function log10(x){ return Math.log10 ? Math.log10(x) : Math.log(x)/Math.LN10; }
function sqrt(x){ return Math.sqrt(x); }
function abs(x){ return Math.abs(x); }
function rnd(){ return Math.random(); }
function pow(a,b){ return Math.pow(a,b); }
function root(base,n){ return Math.pow(base, 1/(n||2)); }

// render UI
function render(){
  exprEl.textContent = expr;
  resEl.textContent = (Number.isFinite(lastAns) ? String(lastAns) : (lastAns === 0 && expr === '' ? '0' : 'Erro'));
  modeLabel.textContent = mode;
}
function pushHistory(e, r){
  hist.unshift({expr:e, result:r});
  if(hist.length>200) hist.pop();
  renderHistory();
  // envia para servidor para logging
  const text = `${e} = ${r}`;
  navigator.sendBeacon ? navigator.sendBeacon(location.href, new URLSearchParams({log_entry: text})) 
    : fetch(location.href, {method:'POST', headers:{'Content-Type':'application/x-www-form-urlencoded'}, body: 'log_entry='+encodeURIComponent(text)});
}
function renderHistory(){
  if(hist.length===0){
    historyEl.innerHTML = '<div style="padding:12px;color:var(--muted)">Sem histórico — faz um cálculo.</div>';
    return;
  }
  historyEl.innerHTML = '';
  hist.forEach((it, idx) => {
    const div = document.createElement('div'); div.className = 'hist-item';
    const left = document.createElement('div'); left.innerHTML = `<div style="font-weight:700">${it.expr}</div><div class="small">${it.result}</div>`;
    const btns = document.createElement('div'); btns.style.display='flex'; btns.style.gap='6px';
    const use = document.createElement('button'); use.className='btn'; use.textContent='Usar'; use.onclick = ()=> { expr = it.expr; lastAns = it.result; render(); };
    const copy = document.createElement('button'); copy.className='btn'; copy.textContent='Copiar'; copy.onclick = ()=> navigator.clipboard?.writeText(String(it.result));
    btns.appendChild(use); btns.appendChild(copy);
    div.appendChild(left); div.appendChild(btns);
    historyEl.appendChild(div);
  });
}

// avaliação (segura-ish)
function evaluateExpression(input){
  let code = input.replace(/÷/g,'/').replace(/×/g,'*').replace(/–/g,'-').replace(/π/g,'pi');
  code = code.replace(/\bpi\b/g, '('+Math.PI+')');
  code = code.replace(/\be\b/g, '('+Math.E+')');
  // ^ -> pow
  code = code.replace(/(\b[\d\.eE\-\+\(\)]+)\s*\^\s*([\d\.eE\-\+\(\)]+)/g, 'pow($1,$2)');
  // percent e postfix factorial
  code = code.replace(/([\d\.\)]+)\s*%/g, '($1/100)');
  code = code.replace(/(\d+(\.\d+)?)\s*!/g, 'factorialNum($1)');

  // substituir 'log(' por log10(
  code = code.replace(/\blog\(/g, 'log10(');

  // sandbox: expõe as funções definidas
  const context = { sin,cos,tan,asin,acos,atan,ln,log10,sqrt,abs,rnd,pow,root,factorialNum };
  const sandbox = `"use strict"; const {sin,cos,tan,asin,acos,atan,ln,log10,sqrt,abs,rnd,pow,root,factorialNum} = this; return (${code});`;
  try{
    const fn = new Function(sandbox).bind(context);
    return fn();
  }catch(e){
    // fallback
    try{
      return Function('return ('+code+')')();
    }catch(e2){
      throw e2;
    }
  }
}

// ações
document.getElementById('keys').addEventListener('click', (ev)=>{
  const k = ev.target.closest('.key'); if(!k) return;
  if(k.id === 'equals' || k.classList.contains('primary')){ calcEquals(); return; }
  const v = k.dataset.val;
  if(!v) return;
  if(v === 'factorial()') expr += '!';
  else expr += v;
  render();
});

document.getElementById('clear').addEventListener('click', ()=>{ expr=''; lastAns=0; render(); });
document.getElementById('del').addEventListener('click', ()=>{ expr=expr.slice(0,-1); render(); });
document.getElementById('copy').addEventListener('click', ()=> navigator.clipboard?.writeText(String(lastAns)));

document.getElementById('mc').addEventListener('click', ()=> { memory = 0; render(); });
document.getElementById('mr').addEventListener('click', ()=> { expr += String(memory); render(); });
document.getElementById('mplus').addEventListener('click', ()=> { memory = (Number(memory)||0) + (Number(lastAns)||0); render(); });
document.getElementById('mminus').addEventListener('click', ()=> { memory = (Number(memory)||0) - (Number(lastAns)||0); render(); });
document.getElementById('ans').addEventListener('click', ()=> { expr += String(lastAns); render(); });

document.getElementById('themeToggle').addEventListener('click', ()=>{
  document.body.classList.toggle('light');
  localStorage.setItem('calc_theme', document.body.classList.contains('light') ? 'light' : 'dark');
});
document.getElementById('exportLog').addEventListener('click', ()=>{
  // descarrega calculadora.log
  fetch('calculadora.log').then(r=>{
    if(!r.ok) throw new Error('Não existe log ou não é acessível');
    return r.blob();
  }).then(blob=>{
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a'); a.href = url; a.download = 'calculadora.log'; a.click();
    URL.revokeObjectURL(url);
  }).catch(err=> alert('Erro ao exportar log: '+err.message));
});

document.getElementById('clearHist').addEventListener('click', ()=>{ hist.length = 0; renderHistory(); });

document.getElementById('menuLogs').addEventListener('click', (e)=> {
  // abre /calculadora.log numa nova tab (se existir)
  window.open('calculadora.log','_blank');
});

// calculo
function calcEquals(){
  if(!expr) return;
  try{
    const v = evaluateExpression(expr);
    const n = (typeof v === 'number') ? v : Number(v);
    lastAns = Number.isFinite(n) ? n : NaN;
    pushHistory(expr, lastAns);
    render();
  }catch(e){
    lastAns = NaN;
    resEl.textContent = 'Erro';
  }
}

// teclado
window.addEventListener('keydown', (e)=>{
  if(e.key === 'Enter'){ calcEquals(); e.preventDefault(); return; }
  if(e.key === 'Escape'){ expr=''; lastAns=0; render(); return; }
  if(e.key === 'Backspace'){ expr = expr.slice(0,-1); render(); return; }
  const allowed = '0123456789.+-*/()%!,^';
  if(allowed.includes(e.key)) { expr += e.key; render(); return; }
  if(e.key.toLowerCase() === 's'){ expr += 'sin('; render(); return; }
  if(e.key.toLowerCase() === 'c'){ expr += 'cos('; render(); return; }
  if(e.key.toLowerCase() === 't'){ expr += 'tan('; render(); return; }
  if(e.key.toLowerCase() === 'l'){ expr += 'ln('; render(); return; }
  if(e.key.toLowerCase() === 'g'){ expr += 'log10('; render(); return; }
});

// inicialização
(function init(){
  const savedTheme = localStorage.getItem('calc_theme');
  if(savedTheme === 'light') document.body.classList.add('light');
  mode = localStorage.getItem('calc_mode') || mode;
  render();
  renderHistory();
})();
</script>
</body>
</html>
