<?php

namespace DZ\ImageShield\XF\Service\Attachment;

use DZ\ImageShield\Shield;
use DZ\ImageShield\Option\OverlayScope;
use DZ\ImageShield\Service\ShieldApplier;
use XF;
use XF\Attachment\AbstractHandler;
use XF\Entity\AttachmentData;
use XF\Entity\User;
use XF\FileWrapper;
use XF\PrintableException;

class PreparerService extends XFCP_PreparerService
{
    protected bool $shieldEnabled = true;

    public function insertAttachment(
        AbstractHandler $handler,
        FileWrapper $file,
        User $user,
        $hash
    ) {
        $contentType = $handler->getContentType();
        $allowedContentTypes = XF::app()->options()->dzImageShield_contentTypes;
        if (($allowedContentTypes['type'] ?? OverlayScope::ENABLE_FOR_ALL) !== OverlayScope::ENABLE_FOR_ALL) {
            $configuredTypes = isset($allowedContentTypes['content_types'])
                ? (array) $allowedContentTypes['content_types']
                : [];
            if (!in_array($contentType, $configuredTypes, true)) {
                $this->shieldEnabled = false;
            }
        }

        return parent::insertAttachment($handler, $file, $user, $hash);
    }

    /**
     * @throws PrintableException
     */
    public function insertDataFromFile(FileWrapper $file, $userId, array $extra = []): AttachmentData
    {
        if (isset($extra[Shield::KEY_EXTRA_SKIP_SHIELD])) {
            unset($extra[Shield::KEY_EXTRA_SKIP_SHIELD]);

            return parent::insertDataFromFile($file, $userId, $extra);
        }

        if (!$this->shieldEnabled) {
            return parent::insertDataFromFile($file, $userId, $extra);
        }

        if ($userId == XF::visitor()->user_id) {
            $user = XF::visitor();
        } else {
            /** @var User|null $user */
            $user = $this->em()->find('XF:User', $userId, ['Option']);
        }

        $protectedTimestamp = 0;

        if ($user === null || Shield::shouldProtectUploads($user)) {
            $shieldApplier = $this->service(ShieldApplier::class, $file);
            if ($user !== null && $user->hasPermission('general', 'dzImageShield_customText')) {
                $text = Shield::getUserOverlayText($user->user_id ?? 0);
                if (strlen($text) > 0) {
                    $shieldApplier
                        ->setOverlayText($text)
                        ->setOverlayMode(ShieldApplier::MODE_TEXT);
                }
            }
            $file = $shieldApplier->render();
            $protectedTimestamp = XF::$time;
        }

        $data = parent::insertDataFromFile($file, $userId, $extra);
        if ($protectedTimestamp > 0) {
            $db = $this->db();
            $db->query('
                INSERT IGNORE INTO `xf_dz_imageshield_data`
                    (`data_id`, `watermark_date`)
                VALUES
                    (?, ?)
            ', [
                $data->data_id,
                $protectedTimestamp,
            ]);
        }

        return $data;
    }
}
