<?php

declare(strict_types=1);

namespace apexl\Io\modules\mirror\Helper;

use apexl\Io\modules\file\entities\fileEntity;
use apexl\Io\modules\mirror\Interface\Uploadable;
use apexl\Vault\Vault;
use Mimey\MimeTypes;

final readonly class UploadableFileEntity implements Uploadable
{
    private const string TABLE__LOCK = 'file_locks';
    private const string TYPE__LOCKED = 'locked';
    private const string TYPE__UPLOADED = 'uploaded';

    public function __construct(private Vault $db, private fileEntity $fileEntity) {}

    public function getKey(): string
    {
        return sprintf('%s/%s', dirname($this->fileEntity->path), $this->fileEntity->name);
    }

    public function getPath(): string
    {
        return $this->fileEntity->getLocalPath();
    }

    public function unlockUpload(): void
    {
        $this->removeLock(self::TYPE__UPLOADED);
    }

    public function removeLock(string $type): void
    {
        $this->db->delete(self::TABLE__LOCK)
            ->where('file', $this->fileEntity->id)
            ->where('type', $type)
            ->execute();
    }

    public function lockUpload(): void
    {
        $this->addLock(self::TYPE__LOCKED);
    }

    private function addLock(string $type): void
    {
        $this->db->insert(self::TABLE__LOCK)
            ->fields([
                'file' => $this->fileEntity->id,
                'type' => $type,
                'datetime' => date('Y-m-d H:i:s'),
            ])
            ->execute();
    }

    public function markUploaded(): void
    {
        $this->addLock(self::TYPE__UPLOADED);
    }

    public function isUploaded(): bool
    {
        return $this->hasLock(self::TYPE__UPLOADED);
    }

    private function hasLock(string $type): bool
    {
        $result = $this->db->select(self::TABLE__LOCK)
            ->fields('id')
            ->where('file', $this->fileEntity->id)
            ->where('type', $type)
            ->limit(1)
            ->execute()
            ->fetchAll();

        return count($result) > 0;
    }

    public function isLocked(): bool
    {
        return $this->hasLock(self::TYPE__LOCKED);
    }

    public function getMimeType(): string
    {
        $mimey = new MimeTypes();
        preg_match('/\.(\w+)$/', $this->fileEntity->name, $match);
        [, $ext] = $match;

        return $mimey->getMimeType($ext);
    }
}
