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

class MailLabel extends Model
{
    private const COLORS = ['slate', 'blue', 'green', 'amber', 'red', 'violet'];

    public function all(): array
    {
        return $this->db->query('SELECT * FROM mail_labels ORDER BY name ASC')->fetchAll();
    }

    public function byKey(string $key): ?array
    {
        $stmt = $this->db->prepare('SELECT * FROM mail_labels WHERE label_key = ? LIMIT 1');
        $stmt->execute([$this->normalizeKey($key)]);
        return $stmt->fetch() ?: null;
    }

    public function create(string $name, string $color = 'blue'): array
    {
        $name = trim($name);
        if ($name === '') {
            throw new RuntimeException('Label name is required.');
        }
        $key = $this->normalizeKey($name);
        if ($key === '') {
            $key = 'label-' . substr(md5($name . microtime(true)), 0, 8);
        }
        $existing = $this->byKey($key);
        if ($existing) {
            throw new RuntimeException('That label already exists.');
        }
        $color = $this->normalizeColor($color);
        $stmt = $this->db->prepare('INSERT INTO mail_labels (label_key, name, color_token, created_by) VALUES (?, ?, ?, ?)');
        $stmt->execute([$key, $name, $color, (int)(current_user()['id'] ?? 0) ?: null]);
        return $this->byKey($key) ?: ['label_key' => $key, 'name' => $name, 'color_token' => $color];
    }

    public function assignmentsByConversation(array $conversationKeys): array
    {
        $conversationKeys = array_values(array_unique(array_filter(array_map('strval', $conversationKeys))));
        if (!$conversationKeys) {
            return [];
        }
        $placeholders = implode(',', array_fill(0, count($conversationKeys), '?'));
        $stmt = $this->db->prepare("SELECT cl.conversation_key, l.*
            FROM mail_conversation_labels cl
            INNER JOIN mail_labels l ON l.id = cl.label_id
            WHERE cl.conversation_key IN ($placeholders)
            ORDER BY l.name ASC");
        $stmt->execute($conversationKeys);
        $result = [];
        foreach ($stmt->fetchAll() as $row) {
            $result[(string)$row['conversation_key']][] = $row;
        }
        return $result;
    }

    public function replaceConversationLabels(string $conversationKey, array $labelKeys): void
    {
        $labelKeys = array_values(array_unique(array_filter(array_map([$this, 'normalizeKey'], $labelKeys))));
        $this->db->prepare('DELETE FROM mail_conversation_labels WHERE conversation_key = ?')->execute([$conversationKey]);
        if (!$labelKeys) {
            return;
        }
        $labels = [];
        foreach ($labelKeys as $key) {
            $label = $this->byKey($key);
            if ($label) {
                $labels[] = $label;
            }
        }
        $stmt = $this->db->prepare('INSERT IGNORE INTO mail_conversation_labels (conversation_key, label_id, created_by) VALUES (?, ?, ?)');
        foreach ($labels as $label) {
            $stmt->execute([$conversationKey, (int)$label['id'], (int)(current_user()['id'] ?? 0) ?: null]);
        }
    }

    public function addConversationLabel(string $conversationKey, string $labelKey): void
    {
        $label = $this->byKey($labelKey);
        if (!$label) {
            return;
        }
        $stmt = $this->db->prepare('INSERT IGNORE INTO mail_conversation_labels (conversation_key, label_id, created_by) VALUES (?, ?, ?)');
        $stmt->execute([$conversationKey, (int)$label['id'], (int)(current_user()['id'] ?? 0) ?: null]);
    }

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

    public function normalizeColor(string $color): string
    {
        $color = strtolower(trim($color));
        return in_array($color, self::COLORS, true) ? $color : 'blue';
    }
}
