<?php

namespace App\Http\Controllers;

use App\Services\AuditLogger;
use App\Services\Updater;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Artisan;

/**
 * Bare browser-reachable recovery endpoints : /update-database, /clear-cache, /refresh-cache.
 *
 * All three are plain `web` routes NOT behind auth/admin, so they're reachable
 * even after a buyer FTP-uploads new code whose pending migration would 500
 * every authenticated page (the in-app Settings buttons are unreachable then).
 * They only call Artisan — never query app models — so they work while the
 * schema is mid-upgrade.
 */
class SystemMigrateController extends Controller
{
    /** GET /update-database — run pending migrations (+ relocate uploads + clear). */
    public function migrate(): Response
    {
        try {
            Artisan::call('migrate', ['--force' => true]);
            $output = trim(Artisan::output());

            Updater::relocateLegacyUploads();
            Artisan::call('optimize:clear');

            AuditLogger::record('app.migrated', null, 'Database migrated via /update-database', []);

            // These routes are UNAUTHENTICATED (they must work when login is
            // broken), so never leak raw migration output (schema/table names)
            // to anonymous visitors in production — only in debug.
            $detail = config('app.debug') && $output !== ''
                ? '<pre>' . e($output) . '</pre>'
                : '<p>Your database is up to date.</p>';

            return $this->page('<h1>Database updated successfully.</h1>' . $detail . $this->continueLink());
        } catch (\Throwable $e) {
            return $this->page($this->failure($e, '/update-database'), 500);
        }
    }

    /** GET /clear-cache — drop config/route/view/app caches. */
    public function clearCache(): Response
    {
        try {
            Artisan::call('config:clear');
            Artisan::call('route:clear');
            Artisan::call('view:clear');
            Artisan::call('cache:clear');

            AuditLogger::record('app.cache_cleared', null, 'Caches cleared via /clear-cache', []);

            return $this->page('<h1>Cache cleared successfully.</h1>' . $this->continueLink());
        } catch (\Throwable $e) {
            return $this->page($this->failure($e, '/clear-cache'), 500);
        }
    }

    /**
     * GET /refresh-cache — rebuild the cacheable optimizations. We deliberately
     * do NOT run `optimize` / `route:cache`: AppShot has closure-based routes
     * (the /storage, /user-uploads and /{slug} fallbacks), and route:cache
     * throws "Unable to serialize closure" on those. Config + events + views
     * are the safe, worthwhile caches on shared hosting.
     */
    public function refreshCache(): Response
    {
        try {
            Artisan::call('config:cache');
            Artisan::call('event:cache');
            Artisan::call('view:cache');

            AuditLogger::record('app.cache_refreshed', null, 'Caches refreshed via /refresh-cache', []);

            return $this->page('<h1>Cache refreshed successfully.</h1>' . $this->continueLink());
        } catch (\Throwable $e) {
            return $this->page($this->failure($e, '/refresh-cache'), 500);
        }
    }

    private function continueLink(): string
    {
        return '<p><a class="btn" href="' . url('/') . '">Click here to continue</a></p>';
    }

    private function failure(\Throwable $e, string $retry): string
    {
        // Log the full error for the operator; only surface details to the
        // (unauthenticated) browser in debug — in production a DB error message
        // can leak connection/schema info to anyone hitting the URL.
        report($e);

        $detail = config('app.debug')
            ? '<pre>' . e($e->getMessage()) . '</pre>'
            : '<p>The operation could not complete. Check <code>storage/logs/laravel.log</code> for details, fix the cause, and retry.</p>';

        return '<h1>Action failed</h1>' . $detail
            . '<p><a class="btn" href="' . e($retry) . '">Retry</a></p>';
    }

    private function page(string $body, int $status = 200): Response
    {
        $html = '<!doctype html><html lang="en"><head><meta charset="utf-8">'
            . '<meta name="viewport" content="width=device-width, initial-scale=1">'
            . '<meta name="robots" content="noindex"><title>System — AppShot AI</title><style>'
            . 'body{font-family:system-ui,sans-serif;max-width:560px;margin:80px auto;padding:0 24px;color:#1c1917;line-height:1.5}'
            . 'h1{font-size:1.4rem;margin:0 0 .75rem}'
            . 'pre{background:#f5f5f4;border:1px solid #e7e5e4;border-radius:8px;padding:12px;white-space:pre-wrap;word-break:break-word;font-size:.8rem;max-height:320px;overflow:auto}'
            . '.btn{display:inline-block;margin-top:.5rem;padding:10px 18px;background:#1c1917;color:#fff;border-radius:8px;text-decoration:none;font-weight:600}'
            . "</style></head><body>{$body}</body></html>";

        return response($html, $status)->header('Content-Type', 'text/html; charset=UTF-8');
    }
}
