<?php

declare(strict_types=1);

namespace app\admin\controller\routine;

use ba\Filesystem;
use app\common\library\Email;
use PHPMailer\PHPMailer\PHPMailer;
use app\common\controller\Backend;
use app\admin\model\Config as ConfigModel;
use PHPMailer\PHPMailer\Exception as PHPMailerException;
use Webman\Http\Request;
use support\Response;

class Config extends Backend
{
    protected ?object $model = null;

    protected array $filePath = [
        'appConfig' => 'config/app.php',
        'webAdminBase' => 'web/src/router/static/adminBase.ts',
        'backendEntranceStub' => 'app/admin/library/stubs/backendEntrance.stub',
    ];

    protected function initController(Request $request): ?Response
    {
        $this->model = new ConfigModel();
        return null;
    }

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

        $configGroup = get_sys_config('config_group');
        $config = $this->model->order('weigh desc')->select()->toArray();

        $list = [];
        $newConfigGroup = [];
        if (is_array($configGroup)) {
            foreach ($configGroup as $item) {
                $key = $item['key'] ?? $item;
                $val = $item['value'] ?? $item;
                $list[$key] = ['name' => $key, 'title' => __($val)];
                $newConfigGroup[$key] = $list[$key]['title'];
            }
        }
        foreach ($config as $item) {
            $group = $item['group'] ?? '';
            if (isset($newConfigGroup[$group])) {
                $item['title'] = __($item['title'] ?? '');
                $list[$group]['list'][] = $item;
            }
        }

        return $this->success('', [
            'list' => $list,
            'remark' => get_route_remark(),
            'configGroup' => $newConfigGroup,
            'quickEntrance' => get_sys_config('config_quick_entrance'),
        ]);
    }

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

        $all = $this->model->select();
        if ($request->method() === 'POST') {
            $this->modelValidate = false;
            $data = $request->post();
            if (!$data) {
                return $this->error(__('Parameter %s can not be empty', ['']));
            }

            $data = $this->excludeFields($data);
            $configValue = [];
            foreach ($all as $item) {
                if (array_key_exists($item->name, $data)) {
                    $configValue[] = [
                        'id' => $item->id,
                        'type' => $item->getData('type'),
                        'value' => $data[$item->name]
                    ];
                }
            }

            $result = false;
            $this->model->startTrans();
            try {
                foreach ($configValue as $cv) {
                    $this->model->where('id', $cv['id'])->update(['value' => $cv['value']]);
                }
                $this->model->commit();
                $result = true;
            } catch (\Throwable $e) {
                $this->model->rollback();
                return $this->error($e->getMessage());
            }
            return $result ? $this->success(__('The current page configuration item was updated successfully')) : $this->error(__('No rows updated'));
        }

        return $this->error(__('Parameter error'));
    }

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

        if ($request->method() !== 'POST') {
            return $this->error(__('Parameter error'));
        }

        $data = $request->post();
        if (!$data) {
            return $this->error(__('Parameter %s can not be empty', ['']));
        }

        $data = $this->excludeFields($data);
        $result = false;
        $this->model->startTrans();
        try {
            if ($this->modelValidate) {
                $validateClass = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                if (class_exists($validateClass)) {
                    $validate = new $validateClass();
                    $validate->scene('add')->check($data);
                }
            }
            $result = $this->model->save($data);
            $this->model->commit();
        } catch (\Throwable $e) {
            $this->model->rollback();
            return $this->error($e->getMessage());
        }
        return $result !== false ? $this->success(__('Added successfully')) : $this->error(__('No rows were added'));
    }

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

        $data = $request->post();
        $mail = new Email();
        try {
            $mail->Host = $data['smtp_server'] ?? '';
            $mail->SMTPAuth = true;
            $mail->Username = $data['smtp_user'] ?? '';
            $mail->Password = $data['smtp_pass'] ?? '';
            $mail->SMTPSecure = ($data['smtp_verification'] ?? '') == 'SSL' ? PHPMailer::ENCRYPTION_SMTPS : PHPMailer::ENCRYPTION_STARTTLS;
            $mail->Port = $data['smtp_port'] ?? 465;
            $mail->setFrom($data['smtp_sender_mail'] ?? '', $data['smtp_user'] ?? '');
            $mail->isSMTP();
            $mail->addAddress($data['testMail'] ?? '');
            $mail->isHTML();
            $mail->setSubject(__('This is a test email') . '-' . get_sys_config('site_name'));
            $mail->Body = __('Congratulations, receiving this email means that your email service has been configured correctly');
            $mail->send();
        } catch (PHPMailerException) {
            return $this->error($mail->ErrorInfo ?? '');
        }
        return $this->success(__('Test mail sent successfully~'));
    }
}
