<?php

namespace App\Controller;

use App\Entity\CopyscapeReport;
use App\Integrations\Copyscape\CSearchRequest;
use App\Integrations\Copyscape\GuzzleHandler;
use App\Service\ContentService;
use App\Service\CopyscapeReportService;
use Doctrine\ORM\EntityNotFoundException;
use Exception;
use FOS\RestBundle\Controller\AbstractFOSRestController;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\View\View;
use GuzzleHttp\Exception\GuzzleException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class CopyscapeController extends AbstractFOSRestController
{
    /**
     * @var ContentService
     */
    private $service;
    /**
     * @var GuzzleHandler
     */
    private $handler;
    /**
     * @var CopyscapeReportService
     */
    private $copyscapeReportService;

    public function __construct(ContentService $service, GuzzleHandler $handler, CopyscapeReportService $copyscapeReportService)
    {
        $this->service = $service;
        $this->handler = $handler;
        $this->copyscapeReportService = $copyscapeReportService;
    }

    /**
     * Retrieves an File resource.
     *
     * @Rest\Post("/content/{id}/copyscape", requirements={"id"="\d+"}))
     *
     * @param int     $id
     * @param Request $request
     *
     * @return View
     *
     * @throws Exception
     */
    public function getAction(int $id, Request $request): View
    {
        try {
            $content = $this->service->getContent($id);
        } catch (EntityNotFoundException $e) {
            return View::create(['code' => Response::HTTP_NOT_FOUND, 'message' => $e->getMessage()], Response::HTTP_NOT_FOUND);
        }

        $text = $request->get('text');
        $text = strtolower(strip_tags($text));
        $text = preg_replace('/[^\w\s]/', '', $text);

        if ($content->getCopyscapeReport()) {
            if (count(array_diff(explode(' ', $content->getCopyscapeReport()->getText()), explode(' ', $text))) >
                count(explode(' ', $text)) / 2) {
                $request = CSearchRequest::fromText($text);

                try {
                    $response = $this->handler->makeRequest($request);
                } catch (GuzzleException $e) {
                    return View::create(['code' => Response::HTTP_BAD_REQUEST, 'message' => $e->getMessage()],
                        Response::HTTP_BAD_REQUEST);
                }

                $matched = (int) $response->count > 0;
                $copyscapeReport = $content->getCopyscapeReport();
                $copyscapeReport->setDescription(json_encode($response));
                $copyscapeReport->setMatched($matched);
                $copyscapeReport->setText($text);

                $report = $this->copyscapeReportService->save($copyscapeReport);

                return View::create($report, Response::HTTP_OK);
            }

            return View::create($content->getCopyscapeReport(), Response::HTTP_OK);
        } else {
            $request = CSearchRequest::fromText($text);

            try {
                $response = $this->handler->makeRequest($request);
            } catch (GuzzleException $e) {
                return View::create(['code' => Response::HTTP_BAD_REQUEST, 'message' => $e->getMessage()],
                    Response::HTTP_BAD_REQUEST);
            }

            $matched = (int) $response->count > 0;
            $copyscapeReport = new CopyscapeReport();
            $copyscapeReport->setContent($content);
            $copyscapeReport->setDescription(json_encode($response));
            $copyscapeReport->setMatched($matched);
            $copyscapeReport->setText($text);

            $report = $this->copyscapeReportService->save($copyscapeReport);

            return View::create($report, Response::HTTP_OK);
        }
    }
}
