<?php

namespace App\ClinicInvitation\Controller;

use App\ClinicInvitation\Entity\ClinicDoctorInvitation;
use App\ClinicInvitation\Repository\ClinicDoctorInvitationRepository;
use App\ClinicInvitation\Service\ClinicInvitationService;
use App\Shared\Controller\BaseController;
use App\Shared\Exception\AppException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

/**
 * صفحات HTML عمومی دعوت پزشک — لینک پیامک اینجا باز می‌شود (بدون JWT).
 * جدا از ClinicInvitationController که نسخهٔ JSON (/api/v1/...) را برای کلاینت React/اپ سِرو می‌کند.
 */
class ClinicInvitationWebController extends BaseController
{
    public function __construct(
        private readonly ClinicDoctorInvitationRepository $invRepo,
        private readonly ClinicInvitationService          $invitationService,
        private readonly string                           $appUrl,
    ) {}

    #[Route('/clinic-invitation/{token}', methods: ['GET'], name: 'invitation_web_view')]
    #[Route('/i/{token}', methods: ['GET'], name: 'invitation_web_view_short')]
    public function view(string $token): Response
    {
        $inv = $this->invRepo->findByToken($token);
        if ($inv === null) {
            return $this->render('invitation/result.html.twig', ['state' => 'notfound'])->setStatusCode(404);
        }

        if (!$inv->isUsable()) {
            return $this->render('invitation/result.html.twig', [
                'state'     => $this->stateFromStatus($inv),
                'admin_url' => $this->adminUrl(),
            ]);
        }

        return $this->render('invitation/view.html.twig', [
            'token'      => $token,
            'clinic'     => $inv->getClinic()->getName() ?: 'کلینیک',
            'doctor'     => $inv->getInvitedName(),
            'expires_at' => $inv->getExpiresAt(),
        ]);
    }

    #[Route('/clinic-invitation/{token}/respond', methods: ['POST'], name: 'invitation_web_respond')]
    public function respond(string $token, Request $request): Response
    {
        $inv = $this->invRepo->findByToken($token);
        if ($inv === null) {
            return $this->render('invitation/result.html.twig', ['state' => 'notfound'])->setStatusCode(404);
        }

        if (!$this->isCsrfTokenValid('invitation_' . $token, (string) $request->request->get('_token'))) {
            return $this->render('invitation/result.html.twig', ['state' => 'expired'])->setStatusCode(403);
        }

        $action = (string) $request->request->get('action', '');

        try {
            if ($action === 'accept') {
                $this->invitationService->accept($inv);
                return $this->render('invitation/result.html.twig', [
                    'state'     => 'accepted',
                    'admin_url' => $this->adminUrl(),
                ]);
            }
            if ($action === 'reject') {
                $this->invitationService->reject($inv);
                return $this->render('invitation/result.html.twig', ['state' => 'rejected']);
            }
        } catch (AppException) {
            return $this->render('invitation/result.html.twig', ['state' => 'expired']);
        }

        return $this->render('invitation/result.html.twig', ['state' => 'expired'])->setStatusCode(422);
    }

    private function stateFromStatus(ClinicDoctorInvitation $inv): string
    {
        return match ($inv->getStatus()) {
            ClinicDoctorInvitation::STATUS_ACCEPTED => 'accepted',
            ClinicDoctorInvitation::STATUS_REJECTED => 'rejected',
            default                                 => 'expired',
        };
    }

    private function adminUrl(): string
    {
        return rtrim($this->appUrl, '/') . '/admin';
    }
}
