<?php

namespace App\Sms\Controller;

use App\Shared\Constant\ErrorCodes;
use App\Shared\Controller\BaseController;
use App\Sms\Entity\SmsMessageTemplate;
use App\Sms\Repository\SmsMessageTemplateRepository;
use OpenApi\Attributes as OA;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

/**
 * مدیریت متن ویرایش‌پذیر پیامک‌های سیستمی (بر اساس تگ).
 */
#[OA\Tag(name: 'SMS')]
#[IsGranted('ROLE_ADMIN')]
class SmsMessageController extends BaseController
{
    public function __construct(
        private readonly SmsMessageTemplateRepository $repo,
    ) {}

    #[OA\Get(
        path: '/api/v1/admin/sms/messages',
        summary: 'لیست متن‌های سیستمی پیامک (بر اساس تگ)',
        security: [['bearerAuth' => []]],
        responses: [new OA\Response(response: 200, description: 'لیست متن‌ها')]
    )]
    #[Route('/api/v1/admin/sms/messages', methods: ['GET'])]
    public function list(): JsonResponse
    {
        $existing = [];
        foreach ($this->repo->findAll() as $tpl) {
            $existing[$tpl->getTag()] = $tpl->toArray();
        }

        // تگ‌های پیش‌فرضی که هنوز در DB رکورد ندارند را هم با مقدار پیش‌فرض نشان بده.
        $items = [];
        foreach (SmsMessageTemplate::DEFAULTS as $tag => $def) {
            $items[] = $existing[$tag] ?? [
                'tag'                => $tag,
                'title'              => $def['title'],
                'body'               => $def['body'],
                'variables'          => $def['variables'],
                'kavenegar_template' => $def['kavenegar_template'],
                'token_map'          => $def['token_map'],
                'updated_at'         => null,
            ];
        }

        return $this->success(['data' => $items]);
    }

    #[OA\Patch(
        path: '/api/v1/admin/sms/messages/{tag}',
        summary: 'ویرایش متن یک پیامک سیستمی',
        security: [['bearerAuth' => []]],
        requestBody: new OA\RequestBody(
            required: true,
            content: new OA\JsonContent(
                required: ['body'],
                properties: [new OA\Property(property: 'body', type: 'string')]
            )
        ),
        responses: [
            new OA\Response(response: 200, description: 'متن به‌روزرسانی شد'),
            new OA\Response(response: 404, description: 'تگ ناشناخته'),
            new OA\Response(response: 422, description: 'placeholder نامعتبر'),
        ]
    )]
    #[Route('/api/v1/admin/sms/messages/{tag}', methods: ['PATCH'])]
    public function update(string $tag, Request $request): JsonResponse
    {
        if (!isset(SmsMessageTemplate::DEFAULTS[$tag])) {
            return $this->error(ErrorCodes::ERR_NOT_FOUND_001, 'تگ پیامک ناشناخته است', 404);
        }

        $data = json_decode($request->getContent(), true) ?? [];
        $body = trim((string) ($data['body'] ?? ''));
        if ($body === '') {
            return $this->error(ErrorCodes::ERR_VALIDATION_002, 'متن پیامک الزامی است', 422);
        }

        $allowed = SmsMessageTemplate::DEFAULTS[$tag]['variables'];
        preg_match_all('/\{([a-zA-Z0-9_]+)\}/', $body, $m);
        $used = array_unique($m[1]);
        $unknown = array_diff($used, $allowed);
        if (!empty($unknown)) {
            return $this->error(
                ErrorCodes::ERR_VALIDATION_001,
                'placeholder نامعتبر: ' . implode(', ', $unknown) . ' — مجاز: ' . implode(', ', $allowed),
                422,
                'body',
            );
        }

        $def = SmsMessageTemplate::DEFAULTS[$tag];
        $tpl = $this->repo->findByTag($tag);
        if ($tpl === null) {
            $tpl = new SmsMessageTemplate(
                $tag,
                $def['title'],
                $body,
                $def['variables'],
                $def['kavenegar_template'],
                $def['token_map'],
            );
        } else {
            $tpl->setBody($body);
        }

        if (array_key_exists('kavenegar_template', $data)) {
            $name = trim((string) $data['kavenegar_template']);
            $tpl->setKavenegarTemplate($name !== '' ? $name : null);
        }
        $this->repo->save($tpl);

        return $this->success(['data' => $tpl->toArray()]);
    }
}
