<?php

declare(strict_types=1);

namespace app\admin\controller;

use ba\Exception as BaException;
use app\admin\model\AdminLog;
use app\admin\library\module\Server;
use app\admin\library\module\Manage;
use app\common\controller\Backend;
use Webman\Http\Request;
use support\Response;

class Module extends Backend
{
    protected array $noNeedPermission = ['state', 'dependentInstallComplete'];

    public function index(Request $request): Response
    {
        $response = $this->initializeBackend($request);
        if ($response !== null) return $response;

        return $this->success('', [
            'installed' => Server::installedList(root_path() . 'modules' . DIRECTORY_SEPARATOR),
            'sysVersion' => config('buildadmin.version'),
            'nuxtVersion' => Server::getNuxtVersion(),
        ]);
    }

    public function state(Request $request): Response
    {
        $response = $this->initializeBackend($request);
        if ($response !== null) return $response;

        $uid = $request->get('uid', '');
        if (!$uid) {
            return $this->error(__('Parameter error'));
        }
        return $this->success('', [
            'state' => Manage::instance($uid)->getInstallState()
        ]);
    }

    public function install(Request $request): Response
    {
        $response = $this->initializeBackend($request);
        if ($response !== null) return $response;

        AdminLog::instance($request)->setTitle(__('Install module'));
        $uid = $request->get('uid', $request->post('uid', ''));
        $update = filter_var($request->get('update', $request->post('update', false)), FILTER_VALIDATE_BOOLEAN);
        if (!$uid) {
            return $this->error(__('Parameter error'));
        }
        $res = [];
        try {
            $res = Manage::instance($uid)->install($update);
        } catch (BaException $e) {
            return $this->error(__($e->getMessage()), $e->getData(), $e->getCode());
        } catch (\Throwable $e) {
            return $this->error(__($e->getMessage()));
        }
        return $this->success('', ['data' => $res]);
    }

    public function dependentInstallComplete(Request $request): Response
    {
        $response = $this->initializeBackend($request);
        if ($response !== null) return $response;

        $uid = $request->get('uid', '');
        if (!$uid) {
            return $this->error(__('Parameter error'));
        }
        try {
            Manage::instance($uid)->dependentInstallComplete('all');
        } catch (BaException $e) {
            return $this->error(__($e->getMessage()), $e->getData(), $e->getCode());
        } catch (\Throwable $e) {
            return $this->error(__($e->getMessage()));
        }
        return $this->success();
    }

    public function changeState(Request $request): Response
    {
        $response = $this->initializeBackend($request);
        if ($response !== null) return $response;

        AdminLog::instance($request)->setTitle(__('Change module state'));
        $uid = $request->post('uid', '');
        $state = filter_var($request->post('state', false), FILTER_VALIDATE_BOOLEAN);
        if (!$uid) {
            return $this->error(__('Parameter error'));
        }
        $info = [];
        try {
            $info = Manage::instance($uid)->changeState($state);
        } catch (BaException $e) {
            return $this->error(__($e->getMessage()), $e->getData(), $e->getCode());
        } catch (\Throwable $e) {
            return $this->error(__($e->getMessage()));
        }
        return $this->success('', ['info' => $info]);
    }

    public function uninstall(Request $request): Response
    {
        $response = $this->initializeBackend($request);
        if ($response !== null) return $response;

        AdminLog::instance($request)->setTitle(__('Uninstall module'));
        $uid = $request->post('uid', '');
        if (!$uid) {
            return $this->error(__('Parameter error'));
        }
        try {
            Manage::instance($uid)->uninstall();
        } catch (BaException $e) {
            return $this->error(__($e->getMessage()), $e->getData(), $e->getCode());
        } catch (\Throwable $e) {
            return $this->error(__($e->getMessage()));
        }
        return $this->success();
    }

    public function upload(Request $request): Response
    {
        $response = $this->initializeBackend($request);
        if ($response !== null) return $response;

        AdminLog::instance($request)->setTitle(__('Upload module'));
        $file = $request->file('file');
        if (!$file) {
            return $this->error(__('Parameter error'));
        }
        try {
            $res = Manage::uploadFromRequest($request);
        } catch (BaException $e) {
            return $this->error(__($e->getMessage()), $e->getData(), $e->getCode());
        } catch (\Throwable $e) {
            return $this->error(__($e->getMessage()));
        }
        return $this->success('', $res);
    }
}
