<?php
require_once __DIR__ . '/../Core.php';
require_once __DIR__ . '/Setting.php';

class MailFolder extends Model
{
    private const SETTINGS_KEY = 'email_custom_folders_json';

    public function system(): array
    {
        return [
            ['key' => 'inbox', 'name' => 'Inbox', 'system' => true],
            ['key' => 'outbox', 'name' => 'Outbox', 'system' => true],
            ['key' => 'sent', 'name' => 'Sent', 'system' => true],
            ['key' => 'junk', 'name' => 'Junk', 'system' => true],
            ['key' => 'trash', 'name' => 'Trash', 'system' => true],
        ];
    }

    public function custom(): array
    {
        $json = (new Setting())->get(self::SETTINGS_KEY, '[]');
        $rows = json_decode((string)$json, true);
        if (!is_array($rows)) {
            return [];
        }
        $folders = [];
        foreach ($rows as $row) {
            if (!is_array($row)) {
                continue;
            }
            $key = $this->normalizeKey($row['key'] ?? '');
            $name = trim((string)($row['name'] ?? ''));
            if ($key === '' || $name === '') {
                continue;
            }
            $folders[] = [
                'key' => $key,
                'name' => $name,
                'system' => false,
                'created_at' => $row['created_at'] ?? null,
            ];
        }
        return $folders;
    }

    public function all(): array
    {
        return array_merge($this->system(), $this->custom());
    }

    public function byKey(string $key): ?array
    {
        $key = $this->normalizeKey($key);
        foreach ($this->all() as $folder) {
            if (($folder['key'] ?? '') === $key) {
                return $folder;
            }
        }
        return null;
    }

    public function exists(string $key): bool
    {
        return $this->byKey($key) !== null;
    }

    public function create(string $name): array
    {
        $name = trim($name);
        if ($name === '') {
            throw new RuntimeException('Folder name is required.');
        }

        $key = $this->normalizeKey($name);
        if ($key === '') {
            $key = 'folder-' . substr(md5($name . microtime(true)), 0, 8);
        }

        $reserved = array_column($this->system(), 'key');
        if (in_array($key, $reserved, true)) {
            throw new RuntimeException('That folder name is reserved.');
        }

        $folders = $this->custom();
        foreach ($folders as $folder) {
            if (($folder['key'] ?? '') === $key || strcasecmp((string)($folder['name'] ?? ''), $name) === 0) {
                throw new RuntimeException('That folder already exists.');
            }
        }

        $folder = [
            'key' => $key,
            'name' => $name,
            'system' => false,
            'created_at' => date('Y-m-d H:i:s'),
        ];
        $folders[] = $folder;
        (new Setting())->set(self::SETTINGS_KEY, json_encode($folders));
        return $folder;
    }

    public function normalizeKey(string $key): string
    {
        $key = strtolower(trim($key));
        $key = preg_replace('/[^a-z0-9_-]+/', '-', $key) ?? '';
        return trim($key, '-_');
    }
}
