<?php

namespace App\Repository;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use App\Model\Notes;

class Utils {
    private const COOKIE_NAME = 'notes_data';

    public static function decryptPostNoteData(Request $request): array
    {
        $encoded_key = $request->cookies->get('client_key');
        if(!$encoded_key) {
            return ["title" => "", "content" => ""];
        }

        $key = base64_decode($encoded_key, true);
        if ($key === false || strlen($key) !== 16) {
            return ["title" => "", "content" => ""];
        }

        $data = json_decode($request->getContent(), true);
        if (!is_array($data)) {
            $data = [];
        }

        if(!isset($data["title"]) || !isset($data["content"])) {
            return ["title" => "", "content" => ""];
        }

        $enc_title = base64_decode($data["title"], true);
        $enc_content = base64_decode($data["content"], true);

        if($enc_title === false || $enc_content === false) {
            return ["title" => "", "content" => ""];
        }

        $title = self::decryptParam($enc_title, $key);
        $content =  self::decryptParam($enc_content, $key);

        return ["title" => $title, "content" => $content];
    }

    private static function decryptParam(string $data, string $key): string
    {
        $out = '';
        $key_size = strlen($key);
        $data_size = strlen($data);

        for ($i = 0; $i < $data_size; $i++) {
            $out .= $data[$i] ^ $key[$i % $key_size];
        }

        return $out;
    }

    public static function getNotesFromCookie(Request $request): array
    {
        $cookieValue = $request->cookies->get(self::COOKIE_NAME);

        if (!$cookieValue) {
            return ['notes' => new Notes([]), 'invalid' => false];
        }

        try {
            $data = base64_decode($cookieValue);

            if ($data === false) {
                return ['notes' => new Notes([]), 'invalid' => true];
            }
            
            $unserialized = unserialize($data);
           
            if (!$unserialized instanceof Notes) {
                return ['notes' => new Notes([]), 'invalid' => true];
            }

            return ['notes' => $unserialized, 'invalid' => false];
        } catch (\Exception $e) {
            return ['notes' => new Notes([]), 'invalid' => true];
        }
    }

    public static function setNotesCookie(JsonResponse $response, Notes $notes): void
    {
        $serialized = serialize($notes);

        $dataCookie = Cookie::create(self::COOKIE_NAME)
            ->withValue(base64_encode($serialized))
            ->withExpires(strtotime('+30 days'))
            ->withPath('/')
            ->withSecure(false)
            ->withHttpOnly(false);

        $response->headers->setCookie($dataCookie);
    }

    public static function clearNotesCookies(Response $response): void
    {
        $response->headers->clearCookie(self::COOKIE_NAME, '/');
    }
}