<?php
declare(strict_types=1);

namespace Celena\Module\Account;

use Celena\Core\Http\Flash;
use Celena\Core\Http\Request;
use Celena\Core\Http\Response;
use Celena\Core\Security\Csrf;
use Celena\Core\Security\Filter;
use Celena\Core\Security\Password;

/**
 * Личный кабинет посетителя (/account). Доступ — только залогиненным
 * (CustomerAuthMiddleware на группе роутов). Базовый набор вкладок
 * (Обзор / Профиль / Безопасность) самодостаточен без плагинов; магазин
 * добавляет свои вкладки через фильтр `account.tabs`.
 */
final class AccountController extends AccountBaseController
{
    public function overview(Request $request): Response
    {
        $user = $this->auth->user() ?? [];
        return $this->renderAccount('account/overview', [
            'profile' => $this->profileVars($user),
        ], 'Личный кабинет', 'overview');
    }

    public function profile(Request $request): Response
    {
        $user = $this->auth->user() ?? [];
        return $this->renderAccount('account/profile', [
            'profile' => $this->profileVars($user),
        ], 'Профиль', 'profile');
    }

    public function updateProfile(Request $request): Response
    {
        if (!Csrf::validate((string) $request->input('_csrf'))) {
            Flash::error('Сессия устарела, попробуйте ещё раз.');
            return Response::redirect('/account/profile');
        }
        $id = (int) $this->auth->id();
        $name = Filter::string($request->input('name'), 191);
        $email = Filter::email($request->input('email'));
        if ($name === '' || $email === null) {
            Flash::error('Проверьте имя и email.');
            return Response::redirect('/account/profile');
        }
        $taken = $this->conn->builder('celena_users')
            ->where('email', '=', strtolower($email))
            ->where('id', '!=', $id)
            ->first();
        if ($taken !== null) {
            Flash::error('Этот email уже занят.');
            return Response::redirect('/account/profile');
        }
        $this->conn->builder('celena_users')->where('id', '=', $id)->update([
            'name'       => $name,
            'email'      => strtolower($email),
            'updated_at' => date('Y-m-d H:i:s'),
        ]);
        Flash::success('Профиль сохранён.');
        return Response::redirect('/account/profile');
    }

    public function password(Request $request): Response
    {
        return $this->renderAccount('account/password', [], 'Безопасность', 'security');
    }

    public function updatePassword(Request $request): Response
    {
        if (!Csrf::validate((string) $request->input('_csrf'))) {
            Flash::error('Сессия устарела, попробуйте ещё раз.');
            return Response::redirect('/account/password');
        }
        $user = $this->auth->user();
        if ($user === null) {
            return Response::redirect('/account/login');
        }
        $current = (string) $request->input('current_password', '');
        $new = (string) $request->input('new_password', '');
        $confirm = (string) $request->input('new_password_confirm', '');

        if (!Password::verify($current, (string) $user['password_hash'])) {
            Flash::error('Текущий пароль неверный.');
            return Response::redirect('/account/password');
        }
        if (strlen($new) < 8) {
            Flash::error('Новый пароль должен быть не короче 8 символов.');
            return Response::redirect('/account/password');
        }
        if ($new !== $confirm) {
            Flash::error('Новые пароли не совпадают.');
            return Response::redirect('/account/password');
        }
        $this->conn->builder('celena_users')->where('id', '=', (int) $user['id'])->update([
            'password_hash' => Password::hash($new),
            'updated_at'    => date('Y-m-d H:i:s'),
        ]);
        Flash::success('Пароль изменён.');
        return Response::redirect('/account/password');
    }

    /**
     * Рендер страницы кабинета: добавляет навигацию (вкладки из account.tabs)
     * и активный пункт.
     *
     * @param array<string, mixed> $vars
     */
    private function renderAccount(string $template, array $vars, string $title, string $active): Response
    {
        $vars['account_tabs'] = AccountTabs::build($this->auth->user(), $active);
        $vars['account_active'] = $active;
        return $this->render($template, $vars, $title);
    }

    /**
     * @param array<string, mixed> $user
     * @return array<string, mixed>
     */
    private function profileVars(array $user): array
    {
        return [
            'id'    => (int) ($user['id'] ?? 0),
            'name'  => (string) ($user['name'] ?? ''),
            'email' => (string) ($user['email'] ?? ''),
        ];
    }
}
