<?php

namespace App\Controller;

use App\Bundle\Infoclinica\Region;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use App\Repository\RecordRepository;
use OpenApi\Annotations as OA;
use App\Repository\CityRepository;
use App\Bundle\Utils\Logger;
use App\Bundle\Sms\Manager as SmsManager;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Component\HttpClient\CachingHttpClient;
use Symfony\Component\HttpKernel\HttpCache\Store;
use App\Repository\DepartmentRepository;
use App\Entity\Filial;
use App\Repository\SpecialistViewRepository;

/**
 * @Route("/api")
 */
class InternalAPIController extends AbstractController
{
    private $client;
    private $rootPath = '';

    public function __construct(HttpClientInterface $client, string $rootPath)
    {
        $this->rootPath = $rootPath; 
        $store = new Store($rootPath . '/var/HttpClient');
        $this->client = new CachingHttpClient($client, $store);
    }

    /**
     * @Route("/swagger.json", name="public_api_swagger_js")
     */
    public function swaggerJson(): Response
    {
        $openapi = \OpenApi\Generator::scan([$this->rootPath . '/src/']);
        $response = new Response(
            $openapi->toJson(),
            Response::HTTP_OK,
            ['content-type' => 'application/json']
        );

        return $response;
    }

    /**
     * @Route("/swagger", name="public_api_swagger")
     */
    public function swaggerUI():response
    {
        return $this->render('internal_api/swagger.html.twig', [
            'title' => 'Open API sovamed'
        ]);
    }

    /**
     * @Route("/smart-captcha", name="public_smart_captcha", methods={"POST"})
     */
    public function smartCaptcha(Request $request):response
    {
        $res = $this->client->request('POST', '/validate', [
            'verify_peer' => false,
            'verify_host' => false,
            'base_uri' => 'https://smartcaptcha.yandexcloud.net',
            'headers' => [
                'Accept' => 'application/json',
                'Content-Type' => 'application/json',
                'User-Agent' => 'sovamed_bot',
            ], 
            'query' => [
                "secret" => $_ENV['SMARTCAPTCHA_SERVER_KEY'],
                "token" => $request->request->get('smart-token'),
                "ip" => $_SERVER['REMOTE_ADDR'], 
            ]
        ]);
        
        return $this->json($res->toArray());
    }
    

    /**
     * @Route("/banner/{regionId}", name="banner_show", methods={"GET"})
     */
    public function show($regionId, CityRepository $cityRepository): Response
    {
        $banner = $cityRepository->findOneBy(['regionId' => $regionId])->getBanner();
        $data = [
            'active' => false,
        ];

        if ($banner) {
            $data = [
                'src' => $banner->getSrc(),
                'href' => $banner->getHref(),
                'active' => $banner->getActive(),
            ];
        }

        return $this->json($data);
    }

    /**
     * @Route("/log", name="api_log", methods={"POST"})
     */
    public function log(Request $request): Response
    {
        Logger::send($request->toArray());

        return $this->json(['success' => true]);
    }

     /**
     * @Route("/count-record", methods={"POST"})
     */
    public function countRecord(RecordRepository $recordRepository, Request $request): Response 
    {
        $stDate = date('Y-m-d H:00', \time());
        $enDate = date('Y-m-d H:00', strtotime('+1 hours', time()));

        $count = $recordRepository
            ->createQueryBuilder('r')
            ->select('count(r.id)')
            ->where('r.hash in (:hash)')
            ->andWhere('r.createAt BETWEEN :currentDate AND :nextDate')
            ->setParameter('currentDate', new \DateTime($stDate))
            ->setParameter('nextDate', new \DateTime($enDate))
            ->setParameter('hash', md5($request->request->get('phone')))
            ->getQuery()
            ->getSingleScalarResult();

        return $this->json(['data' => [
            'stDate' => $stDate,
            'enDate' => $enDate,
            'count' => $count,
            'hash' => md5($request->request->get('phone')),
            'phone' => $request->request->get('phone'),
        ]]);
    }

    /**
     * @Route("/add-record", methods={"POST"})
     */
    public function addRecord(Request $request): Response 
    {
        $entityManager = $this->getDoctrine()->getManager();

        $record = new Record();
        $record
            ->setSpecialistId((int) $request->request->get('dcode'))
            ->setPhone($request->request->get('phone'))
            ->setHash($request->request->get('phone'))
            ->setCreateAt(new \DateTime('NOW'));
        
        try {
            $entityManager->persist($record);
            $entityManager->flush();

            return $this->json(['data' => true]);
        } catch (Exception $e) {
            return $this->json(['data' => $e->getMessage()]);
        }
    }


    /**
     * https://sms.ru/code/call?phone=79626293193&ip=33.22.11.55&api_id=B58070E1-E89B-95B0-D9BA-37A108868CAF
     * @Route("/msg", methods={"POST"})
     */
    public function msg(Request $request): Response
    {
        return $this->json(['status' => 'OK']);
    }

    /**
     * https://sms.ru/code/call?phone=79626293193&ip=33.22.11.55&api_id=B58070E1-E89B-95B0-D9BA-37A108868CAF
     * @Route("/veretify", methods={"POST"})
     */
    public function veretify(Request $request): Response
    {
        $phone = preg_replace( '/[^0-9]/', '', $request->request->get('phone'));
        $sms = new SmsManager($this->client);    
        $code = rand(1000, 9999);
        $msg = 'Код: ' . $code . ' для подтверждения. Никому не сообщайте пароль.'; 
        
        if (Region::getTemplite() == 'base') {
            $response = $sms->sendSmsSova($phone, $msg);
        } else {
            if ($response = $sms->sendSmsWmt($phone, $msg)) {
                $response['status'] = "OK";
            }
        }
  
        if ($response['status'] == 'OK' ) {
            if (! empty($code)) {
                return $this->json([
                    'status' => 'OK',
                    'code' => base64_encode($code)
                ]);
            } else {
                return $this->json(['status' => 'OK']);
            }
            
        }

        return $this->json($response);
    }

    /**
     * @Route("/search", methods={"POST"})
     */
    public function search(
        Request $request, 
        SpecialistViewRepository $specialistViewRepository, 
        DepartmentRepository $departmentRepository
    ): Response {
        $searchType = $request->request->get('type');
        $searchQuery = $request->request->get('q');

        if ($searchType === 'name') {

            $specialistQuery = $specialistViewRepository->createFilteredQueryBuilder([
                'name' => $searchQuery,
                'onlineMode' => $request->request->getInt('onlineMode', 0) === 1,
                'regionId' => $request->cookies->getInt('region', 0)
            ]);

            $query = $specialistQuery->getQuery();
        } else {
            $departmentQuery = $departmentRepository
                ->createQueryBuilder('d')
                ->where('d.name LIKE :name')
                ->setParameter('name', '%' . mb_convert_case($searchQuery, MB_CASE_TITLE, "UTF-8") . '%');

            $query = $departmentQuery->getQuery();
        }

        return $this->json(['data' => $query->getResult()]);
    }

    /**
     * @Route("/departments", methods={"GET"})
     */
    public function departments(
        Request $request,
        DepartmentRepository $departmentRepository
    ): Response {
        try {
            $regionId = $request->cookies->getInt('region');
            $regionId = ($regionId > 0) ? $regionId : null;
            $kinder = $request->query->getInt('kinder', 0);
            $kinder = ($kinder == 1) ? 1 : null;

            // Используем ту же логику, что и в форме SpecialistSearchType
            $qb = $departmentRepository->createQueryBuilder('d')
                ->select('d.did, d.name')
                ->distinct()
                ->innerJoin('App\Entity\LocationView', 'l', 'WITH', 'l.department = d.did AND l.active = true')
                ->innerJoin('App\Entity\SpecialistView', 's', 'WITH', 's.id = l.specialistId AND s.active = true')
                ->leftJoin('App\Entity\Filial', 'f', 'WITH', 'f.fid = l.filial')
                ->where('f.address LIKE :address')
                ->andWhere('d.did <> :did')
                ->setParameter('did', 0)
                ->setParameter('address', '%' . \App\Bundle\Infoclinica\Region::getCurrentName() . '%');

            // Добавляем фильтр по региону, если он указан
            if ($regionId !== null && $regionId > 0) {
                $qb->andWhere('s.regionId = :regionId')
                   ->setParameter('regionId', $regionId);
            }

            // Добавляем фильтр по детским специализациям, если выбран "Детский врач"
            if ($kinder !== null && $kinder == 1) {
                $qb->andWhere('s.sType = :sType')
                   ->setParameter('sType', 1);
            }
            // Если "Взрослый врач" или не выбран, показываем все специализации (без фильтра по sType)

            $departments = $qb->orderBy('d.name', 'ASC')
                ->getQuery()
                ->getArrayResult();

            $result = [];
            foreach ($departments as $department) {
                $result[] = [
                    'did' => $department['did'],
                    'name' => $department['name']
                ];
            }

            return $this->json(['data' => $result]);
        } catch (\Exception $e) {
            return $this->json([
                'error' => $e->getMessage(),
                'data' => []
            ], 500);
        }
    }
}
