<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Services\CPanelService;
use App\Models\UserDatabase;
use App\Models\UserDbUser;

class DatabaseController extends Controller
{
    protected CPanelService $cpanel;

    public function __construct()
    {
        $user = Auth::user();
        $this->cpanel = new CPanelService(
            env('CPANEL_DOMAIN'),
            $user->cpanel_username ?? env('CPANEL_USERNAME'),
            env('CPANEL_API_TOKEN')
        );
    }

    // ── helpers ────────────────────────────────────────────────

    private function userId(): int
    {
        return Auth::id();
    }

    /** Only databases owned by current user */
    private function myDatabases(): array
    {
        return UserDatabase::where('user_id', $this->userId())
            ->pluck('database_name')
            ->toArray();
    }

    /** Only DB users owned by current user */
    private function myDbUsers(): array
    {
        return UserDbUser::where('user_id', $this->userId())
            ->pluck('db_username')
            ->toArray();
    }

    private function ownsDb(string $db): bool
    {
        return UserDatabase::where('user_id', $this->userId())
            ->where('database_name', $db)
            ->exists();
    }

    private function ownsDbUser(string $username): bool
    {
        return UserDbUser::where('user_id', $this->userId())
            ->where('db_username', $username)
            ->exists();
    }

    private function apiError(array $res): ?string
    {
        if (isset($res['status']) && (int)$res['status'] === 0) {
            $errs = $res['errors'] ?? [];
            return is_array($errs) ? ($errs[0] ?? 'API error') : (string)$errs;
        }
        $cp = $res['cpanelresult'] ?? [];
        if (!empty($cp['error'])) return $cp['error'];
        $d = $cp['data'][0] ?? null;
        if ($d && isset($d['result']) && (int)$d['result'] === 0)
            return $d['reason'] ?? $d['output'] ?? 'API error';
        return null;
    }

    // ── page ───────────────────────────────────────────────────

    public function index()
    {
        $prefix = $this->cpanel->getDbPrefix();

        // Only show THIS user's databases and DB users
        $databases = $this->myDatabases();
        $dbUsers   = $this->myDbUsers();

        // Build db→users map for user's own databases only
        $privMap = [];
        try {
            foreach ($databases as $db) {
                $privRes  = $this->cpanel->callApi('Mysql', 'get_privileges_on_database', ['database' => $db]);
                $privData = $privRes['data'] ?? $privRes['result']['data'] ?? [];
                foreach ((array)$privData as $row) {
                    $user = $row['user'] ?? '';
                    // Only show users that belong to this account
                    if ($user && in_array($user, $dbUsers)) {
                        $privMap[$db][] = $user;
                    }
                }
            }
        } catch (\Throwable) {}

        $cpanelDomain  = preg_replace('#^https?://#', '', rtrim(env('CPANEL_DOMAIN', ''), '/'));
        $phpMyAdminUrl = "https://{$cpanelDomain}:2083/3rdparty/phpMyAdmin/";

        return view('dashboard.databases', compact('databases', 'dbUsers', 'prefix', 'privMap', 'phpMyAdminUrl'));
    }

    // ── phpMyAdmin auto-login ──────────────────────────────────

    public function phpMyAdmin()
    {
        $cpanelHost = preg_replace('#^https?://#', '', rtrim(env('CPANEL_DOMAIN', ''), '/'));
        $user       = Auth::user();
        $cpanelUser = $user->cpanel_username ?? env('CPANEL_USERNAME');
        $apiToken   = env('CPANEL_API_TOKEN');
        $loginUrl   = "https://{$cpanelHost}:2083/login/";

        try {
            $response = \Illuminate\Support\Facades\Http::withoutVerifying()
                ->withOptions(['allow_redirects' => false])
                ->asForm()
                ->post($loginUrl, [
                    'user'      => $cpanelUser,
                    'api_token' => $apiToken,
                    'goto_uri'  => '/3rdparty/phpMyAdmin/',
                ]);
            $location = $response->header('Location');
            if ($location) return redirect()->away($location);
            return view('dashboard.phpmyadmin_redirect', [
                'loginUrl' => $loginUrl, 'cpanelUser' => $cpanelUser,
                'apiToken' => $apiToken, 'error' => 'No redirect from cPanel.',
            ]);
        } catch (\Throwable $e) {
            return view('dashboard.phpmyadmin_redirect', [
                'loginUrl' => $loginUrl, 'cpanelUser' => $cpanelUser,
                'apiToken' => $apiToken, 'error' => $e->getMessage(),
            ]);
        }
    }

    // ── databases ──────────────────────────────────────────────

    public function createDatabase(Request $request)
    {
        $request->validate(['name' => 'required|string|max:48|regex:/^[a-zA-Z0-9_]+$/']);
        $prefix   = $this->cpanel->getDbPrefix();
        $fullName = $prefix . $request->name;

        $res = $this->cpanel->createDatabase($fullName);
        if ($err = $this->apiError($res))
            return response()->json(['success' => false, 'message' => $err]);

        // Record ownership
        UserDatabase::firstOrCreate([
            'user_id'       => $this->userId(),
            'database_name' => $fullName,
        ]);

        return response()->json(['success' => true, 'db' => $fullName]);
    }

    public function deleteDatabase(Request $request)
    {
        $request->validate(['db' => 'required|string']);

        if (!$this->ownsDb($request->db))
            return response()->json(['success' => false, 'message' => 'Unauthorized.'], 403);

        $res = $this->cpanel->deleteDatabase($request->db);
        if ($err = $this->apiError($res))
            return response()->json(['success' => false, 'message' => $err]);

        UserDatabase::where('user_id', $this->userId())
            ->where('database_name', $request->db)
            ->delete();

        return response()->json(['success' => true]);
    }

    // ── users ──────────────────────────────────────────────────

    public function createUser(Request $request)
    {
        $request->validate([
            'username' => 'required|string|max:10|regex:/^[a-zA-Z0-9_]+$/',
            'password' => 'required|string|min:8',
        ]);
        $prefix   = $this->cpanel->getDbPrefix();
        $fullUser = $prefix . $request->username;

        $res = $this->cpanel->createDbUser($fullUser, $request->password);
        if ($err = $this->apiError($res))
            return response()->json(['success' => false, 'message' => $err]);

        // Record ownership
        UserDbUser::firstOrCreate([
            'user_id'     => $this->userId(),
            'db_username' => $fullUser,
        ]);

        return response()->json(['success' => true, 'user' => $fullUser]);
    }

    public function deleteUser(Request $request)
    {
        $request->validate(['username' => 'required|string']);

        if (!$this->ownsDbUser($request->username))
            return response()->json(['success' => false, 'message' => 'Unauthorized.'], 403);

        $res = $this->cpanel->deleteDbUser($request->username);
        if ($err = $this->apiError($res))
            return response()->json(['success' => false, 'message' => $err]);

        UserDbUser::where('user_id', $this->userId())
            ->where('db_username', $request->username)
            ->delete();

        return response()->json(['success' => true]);
    }

    public function changePassword(Request $request)
    {
        $request->validate([
            'username' => 'required|string',
            'password' => 'required|string|min:8',
        ]);

        if (!$this->ownsDbUser($request->username))
            return response()->json(['success' => false, 'message' => 'Unauthorized.'], 403);

        $res = $this->cpanel->changeDbUserPassword($request->username, $request->password);
        if ($err = $this->apiError($res))
            return response()->json(['success' => false, 'message' => $err]);

        return response()->json(['success' => true]);
    }

    // ── privileges ─────────────────────────────────────────────

    public function assignUser(Request $request)
    {
        $request->validate([
            'username'   => 'required|string',
            'db'         => 'required|string',
            'privileges' => 'sometimes|string|in:all,ro,rw',
        ]);

        if (!$this->ownsDb($request->db) || !$this->ownsDbUser($request->username))
            return response()->json(['success' => false, 'message' => 'Unauthorized.'], 403);

        $res = $this->cpanel->assignUserToDb($request->username, $request->db, $request->privileges ?? 'all');
        if ($err = $this->apiError($res))
            return response()->json(['success' => false, 'message' => $err]);

        return response()->json(['success' => true]);
    }

    public function revokeUser(Request $request)
    {
        $request->validate(['username' => 'required|string', 'db' => 'required|string']);

        if (!$this->ownsDb($request->db) || !$this->ownsDbUser($request->username))
            return response()->json(['success' => false, 'message' => 'Unauthorized.'], 403);

        $res = $this->cpanel->revokeUserFromDb($request->username, $request->db);
        if ($err = $this->apiError($res))
            return response()->json(['success' => false, 'message' => $err]);

        return response()->json(['success' => true]);
    }
}
