#!/usr/bin/env bash
#
# reset-framework.sh — restaura o framework ao estado atual do GitHub
#
# Uso:
#   ./reset-framework.sh            # volta a main (estado limpo do GitHub)
#   ./reset-framework.sh --prs      # volta a main e reaplica os PRs em teste
#
# A pasta web/mad-framework e descartavel: este script joga fora QUALQUER
# alteracao local e recoloca o repositorio no estado de origin/main.
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_DIR="$SCRIPT_DIR/mad-framework"
INTEGRATION_BRANCH="testes/pr3-pr4-pr5-pr7-aplicados"
PR_BRANCHES=(
  "origin/feature/theme-notch-sidebar-toggle"
  "origin/fix/toggle-menu-builder-template"
  "origin/fix/nullable-param-system-message-form"
  "origin/fix/fgetcsv-enclosure-escape"
)

apply_slim_context() {
  echo "==> Enxugando contexto Claude (.claude/rules -> docs/mad-rules)..."

  mkdir -p docs/mad-rules

  if [[ -d .claude/rules ]]; then
    find .claude/rules -maxdepth 1 -type f -name '*.md' -exec mv -f {} docs/mad-rules/ \;

    if [[ -d .claude/rules/_backup ]]; then
      rm -rf docs/mad-rules/_backup
      mv .claude/rules/_backup docs/mad-rules/_backup
    fi

    rm -rf .claude/rules
  fi

  (
    cd docs/mad-rules
    {
      echo "# Índice — Regras (carregar sob demanda)"
      echo
      echo "NÃO auto-carregados. Leia via Read quando relevante."
      echo

      for f in *.md; do
        [[ "$f" == "INDEX.md" || ! -f "$f" ]] && continue
        d=$(grep -m1 '^#' "$f" | sed 's/^#* *//')
        echo "- \`$f\` — $d"
      done

      if [[ -d _backup ]]; then
        echo
        echo "## _backup/ — por componente"
        find _backup -maxdepth 1 -type f -name '*.md' -printf '%f\n' | sort | sed 's/^/- `/' | sed 's/$/`/'
      fi
    } > INDEX.md
  )

  python3 - <<'PY'
from pathlib import Path

p = Path('CLAUDE.md')
s = p.read_text() if p.exists() else '# CLAUDE.md\n\n'
section = '''
## Regras MAD sob demanda

As regras volumosas foram removidas do auto-load de `.claude/rules/` e ficam em `docs/mad-rules/`. Não cole o conteúdo dessas regras aqui; leia apenas quando o trabalho exigir. O índice completo está em `docs/mad-rules/INDEX.md`.

| Vou trabalhar com | Leia sob demanda |
|---|---|
| Formulários, layout de formulário, detalhes ou listas | `docs/mad-rules/form-rules.md`, `docs/mad-rules/form-layout-rules.md`, `docs/mad-rules/detail-form-rules.md`, `docs/mad-rules/list-rules.md` |
| Blade, atributos, variáveis de view ou componentes MAD | `docs/mad-rules/blade-rules.md`, `docs/mad-rules/blade-attribute-quotes-rules.md`, `docs/mad-rules/madcomponent-view-vars-rules.md`, `docs/mad-rules/mad-componentes-admin-map.md` |
| Banco, consultas, filtros ou requisições | `docs/mad-rules/database-query-rules.md`, `docs/mad-rules/tcriteria-tfilter-rules.md`, `docs/mad-rules/madrequest-rules.md` |
| Rotas públicas ou páginas públicas/site | `docs/mad-rules/public-routes-rules.md`, `docs/mad-rules/mad-componentes-site-map.md`, `docs/mad-rules/mad-site-overview-rules.md` |
| Componentes específicos de UI | `docs/mad-rules/_backup/<componente>-rules.md` e `docs/mad-rules/INDEX.md` |

'''
if '## Regras MAD sob demanda' not in s:
    marker = '## Project Overview\n'
    s = s.replace(marker, section + marker) if marker in s else s.rstrip() + '\n\n' + section
p.write_text(s)
PY
}

cd "$REPO_DIR"

echo "==> Buscando atualizacoes do GitHub..."
git fetch origin --prune

echo "==> Descartando alteracoes locais e voltando para main..."
git checkout -f main
git reset --hard origin/main
# preserva vendor/ (composer caro) e tmp/ (cache) — limpa o resto
# preserva lib/madtrace (nao versionado, mantido a pedido) alem de vendor/tmp
git clean -fd -e vendor -e tmp -e lib/madtrace

if [[ "${1:-}" == "--prs" ]]; then
  echo "==> Recriando branch de integracao com os 4 PRs..."
  git branch -D "$INTEGRATION_BRANCH" 2>/dev/null || true
  git checkout -b "$INTEGRATION_BRANCH"
  for b in "${PR_BRANCHES[@]}"; do
    echo "    -> aplicando $b"
    git merge --no-ff -X theirs "$b" -m "Aplica PR: ${b#origin/}"
  done
  echo "==> Pronto. Branch '$INTEGRATION_BRANCH' com os 4 PRs aplicados."
else
  echo "==> Pronto. Repositorio no estado limpo de origin/main."
fi

apply_slim_context

echo "==> Injetando MadTrace no init.php..."
MADTRACE_MARKER="// MadTrace — captura automática"
if ! grep -q "$MADTRACE_MARKER" init.php; then
  python3 - <<'PY'
from pathlib import Path

p = Path('init.php')
s = p.read_text()
block = """
// MadTrace — captura automática de erros, exceptions e fatais
if (file_exists('lib/madtrace/MadTrace.php')) {
    require_once 'lib/madtrace/MadTrace.php';
    MadTrace::install([
        'dsn'     => 'https://d6c9c59722f66b6546e893b3bc3239ad@api.staging.madbuilder.dev/api/trace/ingest',
        'app'     => 'Teste MadTrace',
        'env'     => 'production',
        'release' => trim(@shell_exec('git rev-parse --short HEAD 2>/dev/null')) ?: null,
    ]);
}

"""
anchor = "// define the autoloader"
s = s.replace(anchor, block + anchor, 1)
p.write_text(s)
PY
  echo "    -> MadTrace injetado"
else
  echo "    -> MadTrace já presente"
fi

echo "==> Corrigindo configs de banco SQLite..."
# Os configs no git têm nomes errados/legados — corrigir após cada reset
sed -i "s/'name' => \".*\",/'name' => \"app\/database\/permission.db\",/" app/config/permission.php
sed -i "s/'name' => \".*\",/'name' => \"app\/database\/log.db\",/"        app/config/log.php
sed -i "s/'name' => \".*\",/'name' => \"app\/database\/communication.db\",/" app/config/communication.php
sed -i "s/'name' => \".*\",/'name' => \"app\/database\/minierp.db\",/"    app/config/minierp.php
sed -i "s|'name' => .*,|'name' => dirname(__DIR__) . '/database/sqlite/minierp.db',|" app/config/mini_erp.php

echo "==> Garantindo dependencias e permissoes..."
[ -d vendor ] || composer install --no-interaction --no-progress
mkdir -p tmp/blade-cache app/output uploads/import_templates

echo "==> Restaurando bancos SQLite da branch de referencia..."

DB_DIR="app/database/sqlite"
DB_SCHEMA_DIR="app/database"
DB_BRANCH="origin/fix/toggle-menu-builder-template"
DB_BRANCH_PATH="app/database/sqlite"

restore_db() {
  local name="$1"
  local db="$DB_DIR/${name}.db"
  rm -f "$db"
  if git show "${DB_BRANCH}:${DB_BRANCH_PATH}/${name}.db" > "$db" 2>/dev/null && [ -s "$db" ]; then
    echo "    -> $db restaurado da branch"
  else
    echo "    -> $db nao encontrado na branch, recriando do SQL..."
    local schema="$DB_SCHEMA_DIR/$2"
    local inserts="${3:-}"
    rm -f "$db"
    sqlite3 "$db" < "$schema"
    [[ -n "$inserts" && -f "$DB_SCHEMA_DIR/$inserts" ]] && sqlite3 "$db" < "$DB_SCHEMA_DIR/$inserts"
    echo "    -> $db OK (via SQL)"
  fi
}

restore_db "permission"    "permission-sqlite.sql"    "inserts-permission.sql"
restore_db "communication" "communication-sqlite.sql"
restore_db "minierp"       "minierp-sqlite.sql"       "minierp-inserts.sql"

# log.db da branch tem 45MB de dados antigos — sempre recriar limpo do SQL
rm -f "$DB_DIR/log.db"
sqlite3 "$DB_DIR/log.db" < "$DB_SCHEMA_DIR/log-sqlite.sql"
echo "    -> $DB_DIR/log.db recriado limpo (log nao e restaurado)"

# Migracoes: garantir tabelas/colunas que o codigo espera e podem faltar nos DBs da branch
sqlite3 "$DB_DIR/permission.db" "
CREATE TABLE IF NOT EXISTS system_import_template (
    id INTEGER PRIMARY KEY NOT NULL, title TEXT, code TEXT, description TEXT,
    database_name TEXT, mapping_json TEXT, csv_model_path TEXT, import_mode TEXT,
    active char(1) DEFAULT 'Y', created_by INT, created_at TEXT, updated_at TEXT
);
CREATE TABLE IF NOT EXISTS system_import_template_group (
    id INTEGER PRIMARY KEY NOT NULL, template_id INT, system_group_id INT
);
CREATE TABLE IF NOT EXISTS system_import_template_user (
    id INTEGER PRIMARY KEY NOT NULL, template_id INT, system_user_id INT
);
CREATE TABLE IF NOT EXISTS system_import_log (
    id INTEGER PRIMARY KEY NOT NULL, template_id INT, database_name TEXT,
    mapping_json TEXT, file_name TEXT, import_mode TEXT, total_rows INT,
    success_rows INT, error_rows INT, errors_json TEXT, system_user_id INT, created_at TEXT
);
" && echo "    -> migracao permission.db OK"
sqlite3 "$DB_DIR/permission.db" "ALTER TABLE system_group ADD COLUMN code varchar(100);" 2>/dev/null || true
echo "    -> coluna system_group.code garantida"

# Tabelas de "papéis" (roles) — os DBs da branch sao anteriores a essa feature
sqlite3 "$DB_DIR/permission.db" "
CREATE TABLE IF NOT EXISTS system_role (
    id INTEGER PRIMARY KEY NOT NULL,
    code varchar(100),
    name varchar(100),
    description text,
    uuid varchar(36));
CREATE UNIQUE INDEX IF NOT EXISTS sys_role_code_uidx ON system_role(code);

CREATE TABLE IF NOT EXISTS system_role_group (
    id INTEGER PRIMARY KEY NOT NULL,
    system_role_id int,
    system_group_id int,
    FOREIGN KEY(system_role_id) REFERENCES system_role(id),
    FOREIGN KEY(system_group_id) REFERENCES system_group(id));
CREATE INDEX IF NOT EXISTS sys_role_group_role_idx ON system_role_group(system_role_id);
CREATE INDEX IF NOT EXISTS sys_role_group_group_idx ON system_role_group(system_group_id);

CREATE TABLE IF NOT EXISTS system_role_program (
    id INTEGER PRIMARY KEY NOT NULL,
    system_role_id int,
    system_program_id int,
    actions text,
    FOREIGN KEY(system_role_id) REFERENCES system_role(id),
    FOREIGN KEY(system_program_id) REFERENCES system_program(id));
CREATE INDEX IF NOT EXISTS sys_role_program_role_idx ON system_role_program(system_role_id);
CREATE INDEX IF NOT EXISTS sys_role_program_program_idx ON system_role_program(system_program_id);

CREATE TABLE IF NOT EXISTS system_user_role (
    id INTEGER PRIMARY KEY NOT NULL,
    system_user_id int,
    system_role_id int,
    FOREIGN KEY(system_user_id) REFERENCES system_users(id),
    FOREIGN KEY(system_role_id) REFERENCES system_role(id));
CREATE INDEX IF NOT EXISTS sys_user_role_user_idx ON system_user_role(system_user_id);
CREATE INDEX IF NOT EXISTS sys_user_role_role_idx ON system_user_role(system_role_id);
" && echo "    -> tabelas de role garantidas (permission.db)"

sqlite3 "$DB_DIR/communication.db" "
ALTER TABLE system_message ADD COLUMN thread_id INT;
ALTER TABLE system_message ADD COLUMN reply_to_id INT;
ALTER TABLE system_message ADD COLUMN deleted_by_from char(1) DEFAULT 'N';
ALTER TABLE system_message ADD COLUMN deleted_by_to char(1) DEFAULT 'N';
CREATE TABLE IF NOT EXISTS system_message_attachment (
    id INTEGER PRIMARY KEY NOT NULL, system_message_id INT,
    file_path TEXT, file_name TEXT, file_size INT
);
" 2>/dev/null || true
echo "    -> migracao communication.db OK"

# Senha FIXA e forte definida pelo operador via variavel de ambiente (mesma p/ admin e user).
# Nada de senha gravada no script. Sem a variavel, aborta para nao cair em senha fraca.
if [[ -z "${MAD_RESET_PASS:-}" ]]; then
    echo "ERRO: defina a senha antes de rodar o reset:" >&2
    echo "      MAD_RESET_PASS='suaSenhaForte' $0" >&2
    exit 1
fi
BCRYPT_PASS=$(php -r 'echo password_hash($argv[1], PASSWORD_BCRYPT);' "$MAD_RESET_PASS")
sqlite3 "$DB_DIR/permission.db" "UPDATE system_users SET password = '$BCRYPT_PASS' WHERE login IN ('admin','user');"
echo "    -> senhas admin/user definidas a partir de MAD_RESET_PASS (bcrypt)"

# Criar unidade padrão e vincular ao admin (inserts-permission.sql não inclui system_unit)
sqlite3 "$DB_DIR/permission.db" "
INSERT OR IGNORE INTO system_unit (id, name, connection_name) VALUES (1, 'Matriz', 'minierp');
INSERT OR IGNORE INTO system_user_unit (id, system_user_id, system_unit_id) VALUES (1, 1, 1);
"
echo "    -> unidade 'Matriz' criada e vinculada ao admin"

# Os configs do app leem app/database/*.db, mas os bancos sao montados em $DB_DIR (app/database/sqlite).
# Sincroniza permission/communication/log para o caminho lido pelo app.
# (minierp ja e lido de sqlite/ via mini_erp.php, entao nao precisa sincronizar.)
echo "==> Sincronizando bancos para o caminho lido pelo app (app/database)..."
for _db in permission communication log; do
    cp -f "$DB_DIR/${_db}.db" "$DB_SCHEMA_DIR/${_db}.db"
done
echo "    -> permission/communication/log sincronizados"

# Deslogar todos: invalida as sessoes PHP ativas (apos o reset ninguem continua logado)
rm -f /var/lib/php/sessions/sess_* 2>/dev/null || true
echo "    -> sessoes PHP limpas (todos os usuarios deslogados)"

# Apache (www-data) precisa escrever em cache, output e nos bancos SQLite
chown -R www-data:www-data tmp app/output app/database uploads 2>/dev/null || true
chmod -R 775 tmp app/output app/database uploads 2>/dev/null || true

git log --oneline -1

echo ""
echo "============================================================"
echo "  Logins admin e user usam a senha definida em MAD_RESET_PASS"
echo "============================================================"
