<?php

namespace App\Controller;

use App\Entity\Campaign;
use App\Form\CampaignType;
use App\Service\CampaignService;
use App\Service\DataGrid\DataGrid;
use App\Service\DataGrid\DataGridFilterMultiselect;
use App\Service\DataGrid\DataGridFilterNotNull;
use App\Service\DataGrid\DataGridFilterQuery;
use App\Service\DataGrid\DataGridFilterSingleselect;
use App\Service\DataGrid\DataGridHeader;
use App\Service\DataGrid\DataGridNavigation;
use App\Service\DataGrid\DataGridSort;
use Doctrine\ORM\EntityNotFoundException;
use DomainException;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\View\View;
use Limenius\Liform\Liform;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class CampaignController extends FOSRestController
{
    private $campaignService;

    public function __construct(CampaignService $campaignService)
    {
        $this->campaignService = $campaignService;
    }

    /**
     * Retrieves a collection of Campaign resource.
     *
     * @Rest\Get("/campaign/grid")
     * @Rest\View(serializerGroups={"grid"})
     *
     * @param Request $request
     *
     * @return View
     */
    public function getGridCampaign(Request $request): View
    {
        $dataGrid = new DataGrid();

        $dataGrid
            ->setName('campaign')
            ->addHeader(new DataGridHeader(['label' => 'Title', 'id' => 'title', 'isSortable' => true, 'type' => 'campaign']))
            ->addHeader(new DataGridHeader(['label' => 'Client', 'id' => 'client', 'isSortable' => true, 'type' => 'client']))
            ->addHeader(new DataGridHeader(['label' => 'Domain', 'id' => 'domain', 'isSortable' => true, 'type' => 'domain']))
            ->addHeader(new DataGridHeader(['label' => 'Level', 'id' => 'level', 'type' => 'campaign_level']))
            ->addHeader(new DataGridHeader(['label' => 'Boltons', 'id' => 'boltons', 'type' => 'campaign_boltons']))
            ->addHeader(new DataGridHeader(['label' => 'Description', 'id' => 'description', 'isSortable' => true]));

        $dataGrid->setNavigation(new DataGridNavigation(['page' => $request->get('page'), 'rpp' => $request->get('rpp')]));

        $dataGrid->addSorter(new DataGridSort(['sort' => $request->get('sort'), 'order' => $request->get('order')]));

        $dataGrid->addFilter(new DataGridFilterQuery($request->get('q')));

        $dataGrid->addFilter(new DataGridFilterMultiselect(
            'id',
            [],
            $request->get('id') ?? []));

        $dataGrid->addFilter(new DataGridFilterMultiselect(
            'domain',
            [],
            $request->get('domain') ?? []));

        $dataGrid->addFilter(new DataGridFilterMultiselect(
            'level',
            [],
            $request->get('level') ?? []));

        $dataGrid->addFilter(new DataGridFilterMultiselect(
            'client',
            [],
            $request->get('client') ?? []));

        $dataGrid->addFilter(new DataGridFilterSingleselect(
            'ppc',
            [],
            null !== $request->get('ppc') ? filter_var($request->get('ppc'), FILTER_VALIDATE_BOOLEAN) : null));

        $dataGrid->addFilter(new DataGridFilterSingleselect(
            'assignedContentWriter',
            [],
            null !== $request->get('assignedContentWriter') ? filter_var($request->get('assignedContentWriter'), FILTER_VALIDATE_BOOLEAN) : null));

        if ($request->get('googleAnalyticsProfileId') && 'NOT NULL' === $request->get('googleAnalyticsProfileId')) {
            $dataGrid->addFilter(new DataGridFilterNotNull('googleAnalyticsProfileId'));
        }

        $dataGrid->setData($this->campaignService->getCampaignsByGrid($dataGrid))
            ->setTotal($this->campaignService->countCampaignsByGrid($dataGrid));

        // In case our GET was a success we need to return a 200 HTTP OK response with the collection of article object
        return View::create($dataGrid, Response::HTTP_OK);
    }

    /**
     * Retrieves a collection of Campaign resource.
     *
     * @Rest\Get("/campaign")
     *
     * @return View
     */
    public function getAllCampaigns(): View
    {
        $campaigns = $this->campaignService->getAllCampaigns();

        // In case our GET was a success we need to return a 200 HTTP OK response with the collection of article object
        return View::create($campaigns, Response::HTTP_OK);
    }

    /**
     * Retrieves an campaign resource.
     *
     * @Rest\Get("/campaign/{campaignId}", requirements={"campaignId"="\d+"}))
     *
     * @param int $campaignId
     *
     * @return View
     */
    public function getCampaign(int $campaignId): View
    {
        try {
            $campaign = $this->campaignService->getCampaign($campaignId);

            return View::create($campaign, Response::HTTP_OK);
        } catch (EntityNotFoundException $e) {
            return View::create(['code' => Response::HTTP_NOT_FOUND, 'message' => $e->getMessage()], Response::HTTP_NOT_FOUND);
        }
    }

    /**
     * Creates an campaign resource.
     *
     * @Rest\Post("/campaign")
     *
     * @param Request $request
     *
     * @return View
     */
    public function postCampaign(Request $request): View
    {
        $form = $this->createForm(CampaignType::class, null, ['csrf_protection' => false]);

        $form->submit($request->request->all());

        if ($form->isSubmitted() && $form->isValid()) {
            $campaign = $this->campaignService->saveCampaign($form->getData());
            // In case our POST was a success we need to return a 201 HTTP CREATED response
            return View::create($campaign, Response::HTTP_CREATED);
        }

        return View::create($form, Response::HTTP_BAD_REQUEST);
    }

    /**
     * Replaces Campaign resource.
     *
     * @Rest\Put("/campaign/{campaignId}")
     *
     * @param Request $request
     * @param int     $campaignId
     *
     * @return View
     */
    public function putCampaign(Request $request, int $campaignId): View
    {
        try {
            $campaign = $this->campaignService->getCampaign($campaignId);
        } catch (EntityNotFoundException $e) {
            return View::create(['code' => Response::HTTP_NOT_FOUND, 'message' => $e->getMessage()], Response::HTTP_NOT_FOUND);
        }

        $form = $this->createForm(CampaignType::class, $campaign, ['csrf_protection' => false]);
        $form->submit($request->request->all());

        if ($form->isSubmitted() && $form->isValid()) {
            $campaign = $this->campaignService->saveCampaign($campaign);

            // In case our POST was a success we need to return a 201 HTTP CREATED response
            return View::create($campaign, Response::HTTP_OK);
        }

        // In case our PUT was a success we need to return a 200 HTTP OK response with the object as a result of PUT
        return View::create($form, Response::HTTP_BAD_REQUEST);
    }

    /**
     * Updates Campaign resource.
     *
     * @Rest\Patch("/campaign/{campaignId}")
     *
     * @param Request $request
     * @param int     $campaignId
     *
     * @return View
     */
    public function patchCampaignAction(Request $request, int $campaignId): View
    {
        try {
            $campaign = $this->campaignService->getCampaign($campaignId);
        } catch (EntityNotFoundException $e) {
            return View::create(['code' => Response::HTTP_NOT_FOUND, 'message' => $e->getMessage()], Response::HTTP_NOT_FOUND);
        }
        $form = $this->createForm(CampaignType::class, $campaign, ['csrf_protection' => false]);
	$form->submit($request->request->all(), false);
//return View::create(['code' => Response::HTTP_BAD_REQUEST, 'message' => "hello world"], Response::HTTP_BAD_REQUEST);
        if ($form->isSubmitted() && $form->isValid()) {
		
		try{
			                $campaign = $this->campaignService->saveCampaign($form->getData());

					return View::create($campaign, Response::HTTP_OK);
					                            }
					                                        catch (Exception $e)
					                                                    {
					return View::create(['code' => Response::HTTP_BAD_REQUEST, 'message' => $e->getMessage()], Response::HTTP_BAD_REQUEST);
					                                             }
		
		//    $campaign = $this->campaignService->saveCampaign($form->getData());

            // In case our PUT was a success we need to return a 200 HTTP OK response with the object as a result of PATCH
        //    return View::create($campaign, Response::HTTP_OK);
        }

        // In case our PATCH wasn't a success we need to return a 400 HTTP BAD REQUEST response with the form object as a result
        return View::create($form, Response::HTTP_BAD_REQUEST);
    }

    /**
     * Removes the Campaign resource.
     *
     * @Rest\Delete("/campaign/{campaignId}")
     *
     * @param int $campaignId
     *
     * @return View
     */
    public function deleteCampaign(int $campaignId): View
    {
        try {
            $campaign = $this->campaignService->getCampaign($campaignId);
        } catch (EntityNotFoundException $e) {
            return View::create(['code' => Response::HTTP_BAD_REQUEST, 'message' => $e->getMessage()], Response::HTTP_BAD_REQUEST);
        }

        try {
            $this->campaignService->delete($campaign);
        } catch (DomainException $e) {
            return View::create(['code' => Response::HTTP_CONFLICT, 'message' => $e->getMessage()], Response::HTTP_CONFLICT);
        }
        // In case our DELETE was a success we need to return a 204 HTTP NO CONTENT response. The object is deleted.
        return View::create([], Response::HTTP_NO_CONTENT);
    }

    /**
     * Return serialized form to create resource.
     *
     * @Rest\Get("/campaign/schema")
     *
     * @param Liform $liform
     *
     * @return View
     */
    public function getSchema(Liform $liform): View
    {
        $campaign = new Campaign();

        $form = $this->createForm(CampaignType::class, $campaign, ['csrf_protection' => false]);

        $form->remove('startDate');
        $form->remove('endDate');
        $form->remove('level');
        $form->remove('boltons');
        $form->remove('approvement');
        $form->remove('ppc');
        $form->remove('retainer');
        $form->remove('retainerTime');
        $form->remove('randomContentAssignment');
        $form->remove('assignedContentWriter');
        $form->remove('contentWriter');
        $form->remove('paused');
        $form->remove('googleAnalyticsDropThreshold');
        $form->remove('googleAnalyticsMonitorTimeframe');

        $form = $liform->transform($form);

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