#!/usr/bin/env bash
set -Eeuo pipefail

PORT=47885
BASE_URL="https://minike.com.br"
INSTALL_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/minike-local-ai"
CONFIG_FILE="$INSTALL_DIR/config.json"
AGENT_FILE="$INSTALL_DIR/mike_linux_agent.py"
APP_LAUNCHER="$INSTALL_DIR/abrir-mike-local.sh"
APP_ICON="$INSTALL_DIR/mike-local.svg"
LOG_FILE="$INSTALL_DIR/install.log"
VALIDATE_ONLY=0
[[ "${1:-}" == "--validate" ]] && VALIDATE_ONLY=1

cyan='\033[1;36m'
green='\033[1;32m'
yellow='\033[1;33m'
red='\033[1;31m'
reset='\033[0m'

stage() {
  local percent="$1"
  shift
  printf "${cyan}[%3s%%]${reset} %s\n" "$percent" "$*"
  mkdir -p "$INSTALL_DIR"
  printf "[%3s%%] %s\n" "$percent" "$*" >>"$LOG_FILE"
}

action() {
  printf "\n${yellow}===============================================================${reset}\n"
  printf "${yellow}  ACAO NECESSARIA${reset}\n"
  printf "${yellow}===============================================================${reset}\n"
  printf "  %s\n" "$1"
  printf "  %s\n" "$2"
  printf "${yellow}===============================================================${reset}\n\n"
}

install_package() {
  local package="$1"
  if command -v apt-get >/dev/null 2>&1; then
    sudo apt-get update && sudo apt-get install -y "$package"
  elif command -v dnf >/dev/null 2>&1; then
    sudo dnf install -y "$package"
  elif command -v yum >/dev/null 2>&1; then
    sudo yum install -y "$package"
  elif command -v pacman >/dev/null 2>&1; then
    sudo pacman -Sy --noconfirm "$package"
  else
    action "Gerenciador de pacotes nao reconhecido." "Instale manualmente: $package"
    return 1
  fi
}

clear 2>/dev/null || true
printf "${cyan}===============================================================${reset}\n"
printf "${cyan}                   MIKE IA LOCAL - MINIKE${reset}\n"
printf "${cyan}===============================================================${reset}\n"
printf "  Instalador automatico para Linux x86_64/arm64\n"
printf "  Mostra progresso, modelo escolhido e acoes necessarias.\n"
printf "${cyan}===============================================================${reset}\n\n"

stage 5 "Detectando distribuicao, arquitetura e recursos"
OS_NAME="$(. /etc/os-release 2>/dev/null && printf '%s' "${PRETTY_NAME:-Linux}" || uname -s)"
ARCH="$(uname -m)"
RAM_GB="$(awk '/MemTotal/{printf "%.0f", $2/1024/1024}' /proc/meminfo 2>/dev/null || printf '0')"
CORES="$(getconf _NPROCESSORS_ONLN 2>/dev/null || printf '1')"
FREE_GB="$(df -Pk "$HOME" | awk 'NR==2{printf "%.0f", $4/1024/1024}')"
GPU="CPU"
command -v nvidia-smi >/dev/null 2>&1 && GPU="NVIDIA"
lspci 2>/dev/null | grep -Eqi 'AMD|Radeon' && GPU="AMD/Radeon"

printf "  Sistema: %s\n  Arquitetura: %s\n  RAM: %s GB\n  CPU: %s threads\n  Disco livre: %s GB\n  GPU: %s\n\n" \
  "$OS_NAME" "$ARCH" "$RAM_GB" "$CORES" "$FREE_GB" "$GPU"

if [[ "$VALIDATE_ONLY" == "1" ]]; then
  stage 100 "Validacao do instalador Linux concluida"
  printf "  Nenhuma instalacao ou download foi executado.\n"
  exit 0
fi

case "$ARCH" in
  x86_64|amd64|aarch64|arm64) ;;
  *)
    action "Arquitetura nao suportada automaticamente: $ARCH" "Use Linux x86_64 ou arm64."
    exit 10
    ;;
esac

command -v curl >/dev/null 2>&1 || install_package curl
command -v python3 >/dev/null 2>&1 || install_package python3

MODEL="qwen2.5:0.5b"
if (( RAM_GB >= 32 && FREE_GB >= 18 )); then
  MODEL="qwen2.5:7b"
elif (( RAM_GB >= 16 && FREE_GB >= 8 )); then
  MODEL="qwen2.5:3b"
elif (( RAM_GB >= 7 && FREE_GB >= 3 )); then
  MODEL="qwen2.5:1.5b"
fi

stage 18 "Modelo escolhido para este computador: $MODEL"
if ! command -v ollama >/dev/null 2>&1; then
  stage 28 "Instalando Ollama pelo instalador oficial"
  curl -fsSL https://ollama.com/install.sh | sh
else
  stage 28 "Ollama existente sera reutilizado"
fi

stage 42 "Iniciando o motor local"
if command -v systemctl >/dev/null 2>&1; then
  sudo systemctl enable --now ollama >/dev/null 2>&1 || true
fi
if ! curl -fsS http://127.0.0.1:11434/api/tags >/dev/null 2>&1; then
  nohup ollama serve >"$INSTALL_DIR/ollama.log" 2>&1 &
  sleep 5
fi
if ! curl -fsS http://127.0.0.1:11434/api/tags >/dev/null 2>&1; then
  action "Ollama nao respondeu na porta 11434." "Veja $INSTALL_DIR/ollama.log e execute: ollama serve"
  exit 20
fi

stage 56 "Baixando ou validando o modelo $MODEL"
ollama pull "$MODEL"

stage 70 "Criando interface local Linux"
mkdir -p "$INSTALL_DIR" "$HOME/.local/share/applications" "$HOME/.config/systemd/user"
cat >"$CONFIG_FILE" <<JSON
{"version":"2.2.0-linux","model":"$MODEL","port":$PORT,"normal_budget_percent":50,"agent_budget_percent":70,"base_url":"$BASE_URL"}
JSON

cat >"$AGENT_FILE" <<'PY'
#!/usr/bin/env python3
import json
import os
import urllib.request
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer

ROOT = os.path.dirname(os.path.abspath(__file__))
CONFIG = json.load(open(os.path.join(ROOT, "config.json"), encoding="utf-8"))
MODEL = CONFIG["model"]
PORT = int(CONFIG["port"])
HISTORY = os.path.join(ROOT, "history.json")

HTML = r"""<!doctype html><html lang="pt-br"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Mike IA Local Linux</title><style>
:root{color-scheme:dark;--bg:#060b14;--card:#0f172a;--line:#22314a;--text:#e5eef8;--muted:#94a3b8;--cyan:#38bdf8;--gold:#d8b84c}
*{box-sizing:border-box}body{margin:0;background:radial-gradient(circle at top left,#0d2a42,transparent 35%),var(--bg);color:var(--text);font-family:Inter,system-ui,sans-serif}
main{max-width:900px;margin:auto;padding:24px}.head{display:flex;justify-content:space-between;gap:14px;align-items:center;margin-bottom:18px}.brand b{font-size:22px}.brand span{display:block;color:var(--muted);font-size:12px}
.status{border:1px solid #14532d;background:#052e16;color:#86efac;border-radius:999px;padding:8px 12px;font-size:12px}.chat{min-height:58vh;background:rgba(15,23,42,.88);border:1px solid var(--line);border-radius:24px;padding:18px;overflow:auto}
.msg{max-width:82%;padding:12px 14px;border-radius:16px;margin:10px 0;white-space:pre-wrap;line-height:1.5}.user{margin-left:auto;background:#075985}.assistant{background:#182235;border:1px solid #29364d}
form{display:flex;gap:10px;margin-top:14px}textarea{flex:1;resize:vertical;min-height:58px;border-radius:16px;border:1px solid var(--line);background:#0b1220;color:var(--text);padding:14px;font:inherit}button{border:0;border-radius:16px;background:linear-gradient(135deg,var(--cyan),var(--gold));color:#041019;font-weight:900;padding:0 22px;cursor:pointer}
.links{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px}.links a{color:#bae6fd;text-decoration:none;border:1px solid var(--line);padding:8px 10px;border-radius:11px;font-size:12px}
@media(max-width:650px){main{padding:12px}.head{align-items:flex-start}.msg{max-width:94%}form{flex-direction:column}button{min-height:48px}}
</style></head><body><main><div class="head"><div class="brand"><b>Mike IA Local</b><span>Linux · modelo MODEL_NAME · processamento neste computador</span></div><div class="status">IA local ativa</div></div>
<section class="chat" id="chat"><div class="msg assistant">Ola! Estou funcionando localmente neste Linux. Como posso ajudar?</div></section>
<form id="form"><textarea id="prompt" placeholder="Digite sua mensagem..." required></textarea><button>Enviar</button></form>
<div class="links"><a href="https://minike.com.br/local-ai/" target="_blank">Minike IA Local</a><a href="https://ferramentas.minike.com.br" target="_blank">Ferramentas</a><a href="https://minike.com.br/local-ai/skills.php" target="_blank">Skills</a></div>
</main><script>
const form=document.getElementById('form'),prompt=document.getElementById('prompt'),chat=document.getElementById('chat'),messages=[];
function add(role,text){const d=document.createElement('div');d.className='msg '+role;d.textContent=text;chat.appendChild(d);chat.scrollTop=chat.scrollHeight}
form.addEventListener('submit',async e=>{e.preventDefault();const text=prompt.value.trim();if(!text)return;prompt.value='';add('user',text);messages.push({role:'user',content:text});add('assistant','Pensando localmente...');const pending=chat.lastChild;
try{const r=await fetch('/api/chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({messages})});const data=await r.json();pending.textContent=data.message||data.error||'Sem resposta.';if(data.message)messages.push({role:'assistant',content:data.message})}catch(err){pending.textContent='Erro: '+err.message}});
</script></body></html>""".replace("MODEL_NAME", MODEL)

class Handler(BaseHTTPRequestHandler):
    def send_bytes(self, code, body, content_type):
        data = body if isinstance(body, bytes) else body.encode("utf-8")
        self.send_response(code)
        self.send_header("Content-Type", content_type)
        self.send_header("Content-Length", str(len(data)))
        self.send_header("Cache-Control", "no-store")
        self.end_headers()
        self.wfile.write(data)

    def do_GET(self):
        if self.path in ("/", "/ui"):
            return self.send_bytes(200, HTML, "text/html; charset=utf-8")
        if self.path == "/status":
            return self.send_bytes(200, json.dumps({"ok": True, "model": MODEL}), "application/json")
        self.send_bytes(404, "not found", "text/plain")

    def do_POST(self):
        if self.path != "/api/chat":
            return self.send_bytes(404, "not found", "text/plain")
        try:
            size = int(self.headers.get("Content-Length", "0"))
            incoming = json.loads(self.rfile.read(size) or b"{}")
            payload = json.dumps({"model": MODEL, "messages": incoming.get("messages", []), "stream": False}).encode()
            req = urllib.request.Request("http://127.0.0.1:11434/api/chat", data=payload, headers={"Content-Type": "application/json"})
            with urllib.request.urlopen(req, timeout=300) as response:
                result = json.load(response)
            message = result.get("message", {}).get("content", "")
            try:
                history = json.load(open(HISTORY, encoding="utf-8")) if os.path.exists(HISTORY) else []
                history.append({"messages": incoming.get("messages", []), "answer": message})
                json.dump(history[-100:], open(HISTORY, "w", encoding="utf-8"), ensure_ascii=False, indent=2)
            except Exception:
                pass
            self.send_bytes(200, json.dumps({"ok": True, "message": message}, ensure_ascii=False), "application/json; charset=utf-8")
        except Exception as exc:
            self.send_bytes(500, json.dumps({"ok": False, "error": str(exc)}), "application/json")

    def log_message(self, fmt, *args):
        return

ThreadingHTTPServer(("127.0.0.1", PORT), Handler).serve_forever()
PY
chmod +x "$AGENT_FILE"

cat >"$APP_ICON" <<'SVG'
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
  <defs><linearGradient id="g" x2="1" y2="1"><stop stop-color="#22d3ee"/><stop offset=".55" stop-color="#8b5cf6"/><stop offset="1" stop-color="#d8b84c"/></linearGradient></defs>
  <rect width="128" height="128" rx="34" fill="url(#g)"/>
  <path d="M27 91V37h17l20 27 20-27h17v54H84V61L64 87 44 61v30z" fill="#fff"/>
</svg>
SVG

cat >"$APP_LAUNCHER" <<LAUNCHER
#!/usr/bin/env bash
set -e
url="http://127.0.0.1:$PORT/ui"
for browser in microsoft-edge-stable microsoft-edge google-chrome-stable google-chrome chromium chromium-browser brave-browser; do
  if command -v "\$browser" >/dev/null 2>&1; then
    exec "\$browser" --app="\$url" --start-maximized --no-first-run
  fi
done
if command -v xdg-open >/dev/null 2>&1; then
  exec xdg-open "\$url"
fi
printf 'Abra %s no navegador.\\n' "\$url"
LAUNCHER
chmod +x "$APP_LAUNCHER"

cat >"$HOME/.config/systemd/user/mike-local-ai.service" <<UNIT
[Unit]
Description=Mike IA Local Minike
After=network-online.target

[Service]
ExecStart=/usr/bin/env python3 $AGENT_FILE
Restart=always
RestartSec=3

[Install]
WantedBy=default.target
UNIT

cat >"$HOME/.local/share/applications/mike-local-ai.desktop" <<DESKTOP
[Desktop Entry]
Name=Mike IA Local
Comment=IA local conectada ao ecossistema Minike
Exec=$APP_LAUNCHER
Icon=$APP_ICON
Terminal=false
Type=Application
Categories=Utility;Development;
StartupNotify=true
DESKTOP
chmod +x "$HOME/.local/share/applications/mike-local-ai.desktop"
if [[ -d "$HOME/Desktop" ]]; then
  cp "$HOME/.local/share/applications/mike-local-ai.desktop" "$HOME/Desktop/Mike IA Local.desktop"
  chmod +x "$HOME/Desktop/Mike IA Local.desktop"
fi

stage 86 "Ativando a Mike ao iniciar a sessao"
if command -v systemctl >/dev/null 2>&1; then
  systemctl --user daemon-reload
  systemctl --user enable --now mike-local-ai.service
else
  nohup python3 "$AGENT_FILE" >"$INSTALL_DIR/agent.log" 2>&1 &
fi

stage 96 "Verificando a interface local"
for _ in $(seq 1 20); do
  curl -fsS "http://127.0.0.1:$PORT/status" >/dev/null 2>&1 && break
  sleep 1
done
if ! curl -fsS "http://127.0.0.1:$PORT/status" >/dev/null 2>&1; then
  action "A interface local nao respondeu." "Veja $INSTALL_DIR/agent.log ou: journalctl --user -u mike-local-ai"
  exit 30
fi

stage 100 "Mike IA Local instalada no Linux"
printf "${green}  Abrindo http://127.0.0.1:%s/ui${reset}\n" "$PORT"
nohup "$APP_LAUNCHER" >"$INSTALL_DIR/app.log" 2>&1 &
printf "  Log de instalacao: %s\n" "$LOG_FILE"
