<?php
declare(strict_types=1);

namespace Celena\Plugin\Leads\Admin;

use Celena\Core\Database\Connection;
use Celena\Core\Http\Pagination;
use Celena\Core\Http\Request;
use Celena\Core\Http\Response;
use Celena\Core\Security\Auth;
use Celena\Core\Security\Csrf;
use Celena\Core\Security\Filter;
use Celena\Core\Template\Engine;
use Celena\Module\AdminBase\AdminController;
use Celena\Module\Settings\Options;
use Celena\Plugin\Leads\Repositories\FormRepository;

/**
 * Админ-страница «Все заявки» (/admin/leads) — объединённый инбокс: новые заявки
 * конструктора форм (cl_form_submissions) + историческая таблица cl_leads. Список,
 * смена статуса (new/done), удаление. Действия каждой строки роутятся в «свой»
 * источник (status_action/delete_action вычисляются здесь, не в шаблоне).
 * Маршруты регистрируются в plugin.php вне группы AuthMiddleware, поэтому
 * авторизацию проверяем здесь явно.
 */
final class LeadsAdminController extends AdminController
{
    private const STATUSES = ['new', 'done'];

    public function __construct(
        Engine $engine,
        Auth $auth,
        Options $options,
        private readonly Connection $conn,
    ) {
        parent::__construct($engine, $auth, $options);
    }

    public function index(Request $request): Response
    {
        if ($this->auth->user() === null) {
            return Response::redirect('/admin/login');
        }

        $filter = Filter::in($request->query('status'), self::STATUSES, '');
        $page   = Filter::int($request->query('page', 1), 1);

        // Источник 1 — новые заявки конструктора форм (всех форм).
        $repo  = new FormRepository($this->conn);
        $items = [];
        foreach ($repo->allSubmissions($filter) as $s) {
            $items[] = $this->normalizeSubmission($s);
        }

        // Источник 2 — историческая таблица cl_leads.
        $legacyQ = $this->conn->builder('leads');
        if ($filter !== '') {
            $legacyQ->where('status', '=', $filter);
        }
        foreach ($legacyQ->orderBy('id', 'desc')->get() as $l) {
            $items[] = $this->normalizeLegacy($l);
        }

        // Хронологическая сортировка (формат Y-m-d H:i:s сравнивается лексикографически).
        usort($items, function (array $a, array $b): int {
            $c = strcmp((string) $b['created_at'], (string) $a['created_at']);
            return $c !== 0 ? $c : strcmp($b['source'] . $b['id'], $a['source'] . $a['id']);
        });

        $total = count($items);
        $p = new Pagination($page, 30, $total);
        $rows = array_slice($items, $p->offset, $p->perPage);

        // «Новые» — счётчик по обоим источникам, без учёта текущего фильтра.
        $newCount = $repo->newCountAll()
            + $this->conn->builder('leads')->where('status', '=', 'new')->count();

        return $this->view('plugins/leads/admin/index', [
            'leads'          => $rows,
            'pagination'     => $p->toArray('/admin/leads?page=:page' . ($filter !== '' ? '&status=' . $filter : '')),
            'current_filter' => $filter,
            'new_count'      => $newCount,
        ], 'leads', 'Заявки с сайта');
    }

    /**
     * Заявка конструктора форм → общий вид строки. Стандартные поля (name/email/
     * phone/message) раскладываем по колонкам, прочие поля дописываем в «Сообщение».
     * @param array<string,mixed> $s
     * @return array<string,mixed>
     */
    private function normalizeSubmission(array $s): array
    {
        $data = is_array($s['data'] ?? null) ? $s['data'] : [];
        $flat = [];
        foreach ($data as $k => $v) {
            $flat[(string) $k] = is_array($v) ? implode(', ', array_map('strval', $v)) : (string) $v;
        }
        $message = $flat['message'] ?? ($flat['details'] ?? '');
        $known   = ['name', 'email', 'phone', 'tel', 'service', 'message', 'details'];
        $extra   = [];
        foreach ($flat as $k => $v) {
            if (!in_array($k, $known, true) && trim($v) !== '') {
                $extra[] = $k . ': ' . $v;
            }
        }
        if ($extra !== []) {
            $message = trim($message . "\n" . implode("\n", $extra));
        }

        $id = (int) $s['id'];
        return [
            'source'        => 'form',
            'source_label'  => '',
            'id'            => $id,
            'created_at'    => (string) ($s['created_at'] ?? ''),
            'name'          => $flat['name'] ?? '',
            'phone'         => $flat['phone'] ?? ($flat['tel'] ?? ''),
            'email'         => $flat['email'] ?? '',
            'service'       => $flat['service'] ?? '',
            'message'       => $message,
            'status'        => (string) ($s['status'] ?? 'new'),
            'status_action' => '/admin/forms/sub/' . $id . '/status',
            'delete_action' => '/admin/forms/sub/' . $id . '/delete',
        ];
    }

    /**
     * Историческая запись cl_leads → общий вид строки.
     * @param array<string,mixed> $l
     * @return array<string,mixed>
     */
    private function normalizeLegacy(array $l): array
    {
        $id = (int) $l['id'];
        return [
            'source'        => 'legacy',
            'source_label'  => 'архив',
            'id'            => $id,
            'created_at'    => (string) ($l['created_at'] ?? ''),
            'name'          => (string) ($l['name'] ?? ''),
            'phone'         => (string) ($l['phone'] ?? ''),
            'email'         => (string) ($l['email'] ?? ''),
            'service'       => (string) ($l['service'] ?? ''),
            'message'       => (string) ($l['message'] ?? ''),
            'status'        => (string) ($l['status'] ?? 'new'),
            'status_action' => '/admin/leads/' . $id . '/status',
            'delete_action' => '/admin/leads/' . $id . '/delete',
        ];
    }

    public function setStatus(Request $request, array $params): Response
    {
        if ($this->auth->user() === null) {
            return Response::redirect('/admin/login');
        }
        if (!Csrf::validate((string) $request->input('_csrf'))) {
            return $this->redirect('/admin/leads', 'CSRF.', 'error');
        }
        $id = Filter::int($params['id'] ?? 0);
        $status = Filter::in($request->input('status'), self::STATUSES, 'new');
        $this->conn->builder('leads')->where('id', '=', $id)->update(['status' => $status]);
        return $this->redirect('/admin/leads', 'Статус обновлён.');
    }

    public function delete(Request $request, array $params): Response
    {
        if ($this->auth->user() === null) {
            return Response::redirect('/admin/login');
        }
        if (!Csrf::validate((string) $request->input('_csrf'))) {
            return $this->redirect('/admin/leads', 'CSRF.', 'error');
        }
        $id = Filter::int($params['id'] ?? 0);
        $this->conn->builder('leads')->where('id', '=', $id)->delete();
        return $this->redirect('/admin/leads', 'Заявка удалена.');
    }
}
