<?php
namespace Modules\Utilisateur\Controller;

use GuzzleHttp\Psr7\Response;
use Helpers\Ariane\Ariane;
use Helpers\Securite\Securite;
use Helpers\Trad\Trad;
use Helpers\Validator\Validator;
use Modules\GlobalApplication\Repository\Utilisateur;
use Skeleton\Controller\Controller;
use GuzzleHttp\Psr7\Stream;
use Helpers\Log\LogSysteme;

class ManageAvatarController extends Controller
{

    const FLASHBAG_ERROR = 'Utilisateur.ManageAvatar.uploadError';
    const FLASHBAG_SUCCESS = 'Utilisateur.ManageAvatar.uploadSuccess';

    public function indexAction() :string
    {
        // Get user
        $utilisateur = new Utilisateur($this->pdo);
        $user_info = $utilisateur->rqInfoUserByLogin($_SESSION['Session_Login']);

        // Get file path
        $file_path = $this->getAvatarFileService()
            ->getAvatarPath($user_info['id_user'], 'medium');

        Ariane::generate(0, 'user');

        return $this->renderer->render('@Utilisateur/ManageAvatar/avatarmanage_index', [
            'has_custom_avatar' => $file_path !== null,
            'avatar' => [
                'user_code' => $_SESSION['Session_Login'],
                'user_name' => $user_info['NomUser'],
            ],
        ]);
    }

    public function getAvatarAction() :Response
    {
        $user_code = $this->request->getAttribute('user_code');
        $format = $this->request->getAttribute('format') ?? 'medium';

        if (!in_array($format, ['small','medium','large'])) {
            LogSysteme::prefixErrorLog('Invalid parameter "format"');
            return new Response(400, [], 'Invalid paramter "format"');
        }

        // Get user
        $utilisateur = new Utilisateur($this->pdo);
        $user_info = $utilisateur->rqInfoUserByLogin($user_code);

        // Get file path
        $avatar_service = $this->getAvatarFileService();
        $file_path = $avatar_service
            ->getAvatarPath($user_info['id_user'], $format);

        // TODO : find where Cache-Control is declared prematurely
        header_remove('Cache-Control');

        // Case : no custom file uploaded -> serve default avatar
        if ($file_path === null) {
            return new Response(200, [
                'Cache-Control' => 'must-revalidate, public',
                'Content-Type' => 'image/svg+xml',
                // TODO : add a cache strategy
            ], $this->renderer->render(
                '@Utilisateur/ManageAvatar/avatar_default',
                [
                    'size' => $avatar_service->getSize($format),
                    'bg_color' => $avatar_service->getBgColor($user_info['NomUser']), // TODO
                    'text' => strtoupper(substr($user_info['NomUser'], 0, 2)),
                ]
            ));
        }

        $last_modified = filemtime($file_path);

        if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) &&
            strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $last_modified
        ) {
            return new Response(304);
        }

        
        $fopen = fopen($file_path, 'r');
        if (!$fopen) {
            $fopen = null;
        }
        return (new Response(200, [
            'Cache-Control' => 'must-revalidate, private',
            'Content-Type' => 'image/jpeg',
            'Last-Modified' => gmdate('D, d M Y H:i:s T', (int)$last_modified)
        ], new Stream($fopen, [])));
    }

    public function uploadFileAction() :Response
    {
        $trad = $this->getTranslationService();
        $crop_info = $this->request->getParsedBody()['importavatar_file_crop'] ?? null;
        $file = $this->request->getUploadedFiles()['importavatar_file'];

        //_____________________________
        // Validation

        // Silent fail : crop info should exist for a normal
        // use case but is optional
        if ($crop_info === null) {
            LogSysteme::prefixErrorLog('missing parameter "importavatar_file_crop"');
        }
        // TODO : handle $file null
        // TODO : handle $file->getError()

        $validator = $this->createValidator();

        $validator->fileCheck(
            $trad->t('avatar'),
            $file->getClientFilename(),
            ['png', 'jpg'],
            false,
            $file->getSize()
        );

        if (! $validator->isValid()) {
            return new Response(400, [], $this->renderer->render(
                '@popup-erreur/ErreurCreation',
                [
                    'ErreurValid' => $validator->getError(),
                    'desactiveRow' => true,
                ]
            ));
        }

        //_____________________________

        $utilisateur = new Utilisateur($this->pdo);
        $user_info = $utilisateur->rqInfoUserByLogin(
            $_SESSION['Session_Login']
        );

        try {
            $this->getAvatarFileService()
                ->addAvatar($user_info['id_user'], $file->getStream(), $crop_info);
        } catch (\Exception $e) {
            LogSysteme::prefixErrorLog($e->getMessage());

            return new Response(400, [], $this->renderer->render(
                '@popup-erreur/ErreurCreation',
                [
                    'ErreurValid' => 'Server error',
                    'desactiveRow' => true,
                ]
            ));
        }
        
        return new Response(200, []);
    }

    public function deleteFileAction() :Response
    {
        $post = $this->request->getParsedBody();

        // Protection CSRF
        if (Securite::ifCSRFValid($post)) {
            // header('Location : '.$this->router->generateUri('Index.Index.redirectionCSRF'));
            // @exit();
            LogSysteme::prefixErrorLog('CSRF failed');
            return new Response(400);
        }

        // Get user
        $utilisateur = new Utilisateur($this->pdo);
        $user_info = $utilisateur->rqInfoUserByLogin($_SESSION['Session_Login']);

        // Get file path
        $this->getAvatarFileService()
            ->delete($user_info['id_user']);
        
        return new Response(200);
    }

//_____________________________________________________________________________
// Sub-routine

    private function getAvatarFileService() :\Helpers\Fichier\AvatarFileService
    {
        return $this->contenaire->get('AvatarFileRepo');
    }
}
