<?php

namespace Comitium5\DesignerBundle\Controller\Asset;

use Comitium5\ApiClientBundle\Client\Services\AssetApiService;
use Comitium5\DesignerBundle\Controller\BaseController;
use Comitium5\DesignerBundle\Helper\FileUtils;
use Comitium5\DesignerBundle\UseCase\Asset\UploadAssetUseCase;
use Comitium5\DesignerBundle\UseCase\Asset\UploadExternalAssetUseCase;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
 * Class UploadController
 *
 * @author Carles Gómez <carles@bab-soft.com>
 * @package Comitium5\DesignerBundle\Controller\Asset
 */
class UploadController extends BaseController
{
    const TYPE_PARAMETER = 'type';
    const FILE_PARAMETER = 'file';

    /**
     * @param Request $request
     *
     * @return JsonResponse
     * @throws \Exception
     */
    public function uploadAction(Request $request)
    {
        if (!$request->isMethod(Request::METHOD_POST)) {
            return new JsonResponse(array('status' => Response::HTTP_BAD_REQUEST));
        }

        $file = $request->files->get(self::FILE_PARAMETER);
        $type = $request->get(self::TYPE_PARAMETER);

        if (is_null($file) || is_null($type) || FileUtils::validateFileTyping($file)) {
            return $this->createResponse(Response::HTTP_BAD_REQUEST, [
                'file' => $file,
                'type' => $type,
            ]);
        }

        $file->move(sys_get_temp_dir(), $file->getClientOriginalName());

        $uploadUseCase = new UploadAssetUseCase(
            new AssetApiService(
                $this->get("designer.builder.api_locale")(
                    $request->get("locale", $request->getLocale())
                )
            )
        );

        $tmpFilePath = sys_get_temp_dir().DIRECTORY_SEPARATOR.$file->getClientOriginalName();

        $assetObject = $uploadUseCase(
            $file->getClientOriginalName(),
            $tmpFilePath,
            $type
        );

        unlink($tmpFilePath);

        if ($assetObject === null) {
            return $this->createResponse(Response::HTTP_BAD_REQUEST, [
                'file' => $file,
                'type' => $type,
            ]);
        }

        return $this->createResponse(Response::HTTP_OK, [
            'id' => $assetObject->getId(),
            'relative_dir' => $assetObject->getDirectoryPath(),
            'full_path' => $assetObject->getPath(),
            'title' => $assetObject->getTitle(),
            'width' => $assetObject->getWidth(),
            'height' => $assetObject->getHeight(),
        ]);
    }

    /**
     * @TODO('Make a template for javascript')
     * @param  Request  $request
     * @return Response
     */
    public function alternateUploadAction(Request $request)
    {
        $request->files->set('file', $request->files->get('upload'));

        /**
         * @var JsonResponse
         */
        $response = $this->uploadAction($request);

        if ($response->isOk()) {
            $funcNum = $request->query->get('CKEditorFuncNum');
            $data = json_decode($response->getContent(), $response->getEncodingOptions());
            $dir = $data['metadata']['full_path'];

            return new Response(<<<HTML
"<script type='text/javascript'> window.parent.CKEDITOR.tools.callFunction({$funcNum}, '{$dir}', 'TEST')</script>"
HTML
            );
        }

        return new Response('', 400);
    }

    /**
     * @param Request $request
     *
     * @return JsonResponse
     * @throws \Doctrine\ORM\EntityNotFoundException
     */
    public function createFromExternalAction(Request $request)
    {
        $uploadUseCase = new UploadExternalAssetUseCase(
            new AssetApiService(
                $this->get("designer.builder.api_locale")(
                    $request->get("locale", $request->getLocale())
                )
            )
        );

        $assetUploadObject = $uploadUseCase(
            $request->request->get('source'),
            $request->request->get('type')
        );

        return new JsonResponse(array(
            'status' => 200,
            'metadata' => array(
                'id'    => $assetUploadObject->getId(),
                'title' => $assetUploadObject->getTitle(),
            ),
        ));
    }

    /**
     * @param Request $request
     *
     * @return Response|\ComitiumSuite\Bundle\AdminBundle\Controller\Asset\UploadController
     */
    public function createAssetFromUrlAction(Request $request)
    {
        $url  = $request->get("url");
        $type = $request->get("type", AssetTypes::IMAGE);

        $manager = $this->get("admin.manager.asset");
        $handler = $this->get("admin.handler.upload");

        $data = $manager->createFromSource($url, $type);

        if ($data === false) {
            return JsonResponse::create([
                "error" => "Empty data. Maybe url not found."
            ], JsonResponse::HTTP_NOT_FOUND);
        }

        $asset = $data["asset"];
        $file  = $data["file"];

        if (!$asset instanceof AssetInterface || !$file instanceof UploadedFile) {
            return JsonResponse::create([
                "error" => "Invalid asset or uploaded file"
            ], JsonResponse::HTTP_BAD_REQUEST);
        }

        $handler->storeAsset($asset, $file);

        return JsonResponse::create([
            "id" => $asset->getId(),
        ]);
    }

    /**
     * @param int $status
     * @param array $metadata
     * @return JsonResponse
     */
    protected function createResponse($status = Response::HTTP_OK, array $metadata = [])
    {
        return new JsonResponse([
            'status' => $status,
            'metadata' => $metadata,
        ]);
    }
}
