#!/usr/bin/env bash
set -e

APP="${1:-myapp}"

echo "Creating project: $APP"

mkdir -p "$APP"/{manifest,backend/api/routes,backend/lib,worker,cli,admin/tools,admin,public/{css,js/components},db,config,logs,data/{cache,tmp,exports},docs}

########################################
# ENV
########################################
cat > "$APP/config/.env" << 'EOF'
DB_HOST=localhost
DB_NAME=appdb
DB_USER=appuser
DB_PASS=secret
API_KEY=local-api-key
LOG_LEVEL=debug
EOF

########################################
# SQL
########################################
cat > "$APP/db/schema.sql" << 'EOF'
CREATE TABLE users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    username TEXT NOT NULL,
    password_hash TEXT NOT NULL,
    role TEXT NOT NULL
);

CREATE TABLE logs (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    level TEXT,
    message TEXT,
    created_at TEXT
);

CREATE TABLE items (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    title TEXT NOT NULL,
    body TEXT,
    created_at TEXT
);
EOF

sqlite3 "$APP/db/app.db" < "$APP/db/schema.sql"

########################################
# Backend Libs
########################################
cat > "$APP/backend/lib/Env.php" << 'EOF'
<?php
class Env {
    private static array $cache = [];
    public static function get(string $key, $default=null) {
        if (!self::$cache) {
            $path = __DIR__ . '/../../config/.env';
            if (!file_exists($path)) return $default;
            foreach (file($path, FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES) as $line) {
                if (strpos($line,'=')!==false) {
                    [$k,$v]=explode('=',$line,2);
                    self::$cache[$k]=$v;
                }
            }
        }
        return self::$cache[$key] ?? $default;
    }
}
EOF

cat > "$APP/backend/lib/Db.php" << 'EOF'
<?php
class Db {
    private static ?PDO $pdo=null;
    public static function conn():PDO {
        if (!self::$pdo) {
            self::$pdo=new PDO('sqlite:' . __DIR__ . '/../db/app.db');
            self::$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
        }
        return self::$pdo;
    }
}
EOF

cat > "$APP/backend/lib/Logger.php" << 'EOF'
<?php
class Logger {
    public static function log(string $level,string $msg):void {
        $file=__DIR__.'/../../logs/app.log';
        $line="[".date('Y-m-d H:i:s')."] [$level] $msg\n";
        file_put_contents($file,$line,FILE_APPEND);
    }
}
EOF

cat > "$APP/backend/lib/Auth.php" << 'EOF'
<?php
class Auth {
    public static function check():bool {
        return ($_GET['key'] ?? '') === Env::get('API_KEY');
    }
}
EOF

cat > "$APP/backend/lib/Response.php" << 'EOF'
<?php
class Response {
    public static function json($data,int $code=200):void {
        http_response_code($code);
        header('Content-Type: application/json');
        echo json_encode($data);
        exit;
    }
}
EOF

########################################
# Backend API
########################################
cat > "$APP/backend/api/index.php" << 'EOF'
<?php
require __DIR__.'/../lib/Db.php';
require __DIR__.'/../lib/Env.php';
require __DIR__.'/../lib/Logger.php';
require __DIR__.'/../lib/Auth.php';
require __DIR__.'/../lib/Response.php';

$path=$_GET['path'] ?? '';

switch ($path) {
    case 'status':
        require __DIR__.'/routes/status.php';
        break;
    case 'users':
        require __DIR__.'/routes/users.php';
        break;
    case 'items':
        require __DIR__.'/routes/items.php';
        break;
    default:
        Response::json(['error'=>'Not found'],404);
}
EOF

cat > "$APP/backend/api/routes/status.php" << 'EOF'
<?php
if (!Auth::check()) Response::json(['error'=>'Unauthorized'],403);
Response::json([
    'status'=>'ok',
    'time'=>date('Y-m-d H:i:s'),
    'db'=>file_exists(__DIR__.'/../../db/app.db')?'connected':'missing'
]);
EOF

cat > "$APP/backend/api/routes/users.php" << 'EOF'
<?php
if (!Auth::check()) Response::json(['error'=>'Unauthorized'],403);
$db=Db::conn();
$rows=$db->query("SELECT id,username,role FROM users")->fetchAll(PDO::FETCH_ASSOC);
Response::json($rows);
EOF

cat > "$APP/backend/api/routes/items.php" << 'EOF'
<?php
if (!Auth::check()) Response::json(['error'=>'Unauthorized'],403);
$db=Db::conn();
$rows=$db->query("SELECT id,title,body,created_at FROM items ORDER BY id DESC")->fetchAll(PDO::FETCH_ASSOC);
Response::json($rows);
EOF

########################################
# Worker System
########################################
cat > "$APP/worker/fetch.py" << 'EOF'
import sqlite3
import time

DB = "../db/app.db"

def add_item(title, body):
    conn = sqlite3.connect(DB)
    cur = conn.cursor()
    cur.execute("INSERT INTO items (title, body, created_at) VALUES (?, ?, ?)",
                (title, body, time.strftime("%Y-%m-%d %H:%M:%S")))
    conn.commit()
    conn.close()

if __name__ == "__main__":
    add_item("Worker Event", "Worker executed successfully.")
EOF

########################################
# Frontend
########################################
cat > "$APP/public/index.html" << 'EOF'
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>MyApp Dashboard</title>
  <link rel="stylesheet" href="css/app.css">
</head>
<body>
  <h1>MyApp Dashboard</h1>
  <div id="status"></div>
  <div id="items"></div>
  <script src="js/app.js"></script>
</body>
</html>
EOF

cat > "$APP/public/css/app.css" << 'EOF'
body { font-family: sans-serif; padding: 2rem; }
#items { margin-top: 2rem; }
EOF

cat > "$APP/public/js/app.js" << 'EOF'
fetch('../backend/api/index.php?path=status&key=local-api-key')
  .then(r => r.json())
  .then(data => {
    document.getElementById('status').innerText = JSON.stringify(data, null, 2);
  });

fetch('../backend/api/index.php?path=items&key=local-api-key')
  .then(r => r.json())
  .then(data => {
    document.getElementById('items').innerText = JSON.stringify(data, null, 2);
  });
EOF

########################################
# CLI Tools
########################################
cat > "$APP/cli/app.sh" << 'EOF'
#!/usr/bin/env bash
php backend/api/index.php "$@"
EOF
chmod +x "$APP/cli/app.sh"

cat > "$APP/cli/admin.sh" << 'EOF'
#!/usr/bin/env bash
case "$1" in
  db) php admin/tools/db-inspect.php ;;
  logs) php admin/tools/log-viewer.php "${2:-}" ;;
  config) php admin/tools/config-check.php ;;
  users) shift; php admin/tools/user-admin.php "$@" ;;
  dashboard) php -S localhost:9000 -t admin ;;
  *) echo "Commands: db, logs, config, users, dashboard" ;;
esac
EOF
chmod +x "$APP/cli/admin.sh"

cat > "$APP/cli/test.sh" << 'EOF'
#!/usr/bin/env bash
set -e
php -l backend/api/index.php
sqlite3 db/app.db < db/tests.sql
bash -n cli/admin.sh
bash -n cli/app.sh
echo "All tests passed."
EOF
chmod +x "$APP/cli/test.sh"

########################################
# Tests
########################################
cat > "$APP/db/tests.sql" << 'EOF'
SELECT name FROM sqlite_master WHERE type='table';
SELECT COUNT(*) FROM users;
EOF

########################################
# Admin Toolkit
########################################
cat > "$APP/admin/tools/db-inspect.php" << 'EOF'
<?php
$db=new PDO('sqlite:' . __DIR__.'/../../db/app.db');
$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
$tables=$db->query("SELECT name FROM sqlite_master WHERE type='table'")->fetchAll(PDO::FETCH_COLUMN);
foreach ($tables as $t) {
    $count=$db->query("SELECT COUNT(*) FROM \"$t\"")->fetchColumn();
    echo "$t : $count\n";
}
EOF

cat > "$APP/admin/tools/log-viewer.php" << 'EOF'
<?php
$log=__DIR__.'/../../logs/app.log';
$filter=$argv[1] ?? null;
foreach (file($log,FILE_IGNORE_NEW_LINES) as $line) {
    if ($filter && stripos($line,"[$filter]")===false) continue;
    echo $line."\n";
}
EOF

cat > "$APP/admin/tools/config-check.php" << 'EOF'
<?php
$envFile=__DIR__.'/../../config/.env';
$required=['DB_HOST','DB_NAME','DB_USER','DB_PASS','API_KEY','LOG_LEVEL'];
$env=[];
foreach (file($envFile,FILE_IGNORE_NEW_LINES) as $line) {
    [$k,$v]=explode('=',$line,2);
    $env[$k]=$v;
}
foreach ($required as $key) {
    echo "$key : ".(isset($env[$key])?'OK':'MISSING')."\n";
}
EOF

cat > "$APP/admin/tools/user-admin.php" << 'EOF'
<?php
$db=new PDO('sqlite:' . __DIR__.'/../../db/app.db');
$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
$cmd=$argv[1] ?? 'list';
switch ($cmd) {
    case 'list':
        print_r($db->query("SELECT id,username,role FROM users")->fetchAll(PDO::FETCH_ASSOC));
        break;
    case 'add':
        $u=$argv[2]; $p=$argv[3]; $r=$argv[4] ?? 'user';
        $hash=password_hash($p,PASSWORD_DEFAULT);
        $db->prepare("INSERT INTO users (username,password_hash,role) VALUES (?,?,?)")->execute([$u,$hash,$r]);
        echo "User added\n";
        break;
    case 'del':
        $u=$argv[2];
        $db->prepare("DELETE FROM users WHERE username=?")->execute([$u]);
        echo "User deleted\n";
        break;
}
EOF

########################################
# Admin Dashboard
########################################
cat > "$APP/admin/dashboard.php" << 'EOF'
<?php
$db=new PDO('sqlite:' . __DIR__.'/../db/app.db');
$tables=$db->query("SELECT name FROM sqlite_master WHERE type='table'")->fetchAll(PDO::FETCH_COLUMN);
?>
<!DOCTYPE html>
<html>
<head><title>Admin Dashboard</title></head>
<body>
<h1>Admin Dashboard</h1>
<ul>
<?php foreach ($tables as $t): ?>
<li><?= $t ?> (<?= $db->query("SELECT COUNT(*) FROM \"$t\"")->fetchColumn() ?> rows)</li>
<?php endforeach; ?>
</ul>
</body>
</html>
EOF

########################################
# Docs
########################################
cat > "$APP/docs/README.md" << 'EOF'
# $APP
Version 1 unified package.
EOF

cat > "$APP/docs/ARCHITECTURE.md" << 'EOF'
# Architecture
Backend, Frontend, Worker, CLI, Admin, Tests, Docs, Config, Logs, Data.
EOF

cat > "$APP/docs/INSTALL.md" << 'EOF'
# Install
chmod +x install.sh
./install.sh myapp
php -S localhost:8000 -t public
EOF

cat > "$APP/docs/DESIGN.md" << 'EOF'
# Design
Modular, layered, documented, single installer.
EOF

cat > "$APP/docs/TESTING.md" << 'EOF'
# Testing
cli/test.sh
EOF

########################################
# Manifest
########################################
cat > "$APP/manifest/manifest.json" << 'EOF'
{
  "name": "$APP",
  "version": "1.0.0",
  "paths": {
    "backend": "backend/",
    "cli": "cli/",
    "admin": "admin/",
    "db": "db/",
    "config": "config/",
    "logs": "logs/",
    "data": "data/",
    "docs": "docs/",
    "public": "public/",
    "worker": "worker/"
  }
}
EOF

echo "Project $APP created successfully."

