<?php
declare(strict_types=1);

if (!function_exists('q_e')) {
    function q_e(?string $value): string
    {
        return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
    }
}

if (!function_exists('q_parse_money')) {
    function q_parse_money(string $value): float
    {
        $value = trim($value);
        if ($value === '') {
            return 0.0;
        }
        $value = preg_replace('/[^\d,.\-]/', '', $value);
        if (str_contains($value, ',') && str_contains($value, '.')) {
            $value = str_replace('.', '', $value);
            $value = str_replace(',', '.', $value);
        } elseif (str_contains($value, ',')) {
            $value = str_replace(',', '.', $value);
        }
        return round((float) $value, 2);
    }
}

if (!function_exists('q_money')) {
    function q_money(float $value): string
    {
        return 'R$ ' . number_format($value, 2, ',', '.');
    }
}

if (!function_exists('q_format_date')) {
    function q_format_date(?string $date): string
    {
        $date = trim((string) $date);
        if ($date === '') {
            return '';
        }
        if (preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $date, $m)) {
            return $m[3] . '/' . $m[2] . '/' . $m[1];
        }
        return $date;
    }
}

if (!function_exists('q_hex_to_rgb')) {
    function q_hex_to_rgb(string $hex): array
    {
        $hex = ltrim(trim($hex), '#');
        if (!preg_match('/^[0-9a-fA-F]{6}$/', $hex)) {
            $hex = '1e3a5f';
        }
        return [
            hexdec(substr($hex, 0, 2)),
            hexdec(substr($hex, 2, 2)),
            hexdec(substr($hex, 4, 2)),
        ];
    }
}

if (!function_exists('q_mix_color_with_white')) {
    function q_mix_color_with_white(string $hexColor, int $intensity): string
    {
        $intensity = max(30, min(100, $intensity));
        [$r, $g, $b] = q_hex_to_rgb($hexColor);
        $f = $intensity / 100;
        $mix = static function (int $channel) use ($f): int {
            return (int) round($channel * $f + 255 * (1 - $f));
        };
        return sprintf('#%02x%02x%02x', $mix($r), $mix($g), $mix($b));
    }
}

if (!function_exists('q_rgba')) {
    function q_rgba(string $hexColor, float $alpha): string
    {
        [$r, $g, $b] = q_hex_to_rgb($hexColor);
        $alpha = max(0, min(1, $alpha));
        return sprintf('rgba(%d, %d, %d, %.3f)', $r, $g, $b, $alpha);
    }
}

if (!function_exists('q_normalize_quantity')) {
    function q_normalize_quantity(string $value): float
    {
        $value = trim($value);
        if ($value === '') {
            return 0.0;
        }
        return (float) str_replace(',', '.', $value);
    }
}


if (!function_exists('q_parse_installment_count')) {
    function q_parse_installment_count(string $value): int
    {
        if (preg_match('/(\d+)/', $value, $m)) {
            return max(1, (int) $m[1]);
        }
        return 1;
    }
}

if (!function_exists('q_calc_services')) {
    function q_calc_services(array $services): array
    {
        $total = 0.0;
        $normalized = [];
        foreach ($services as $service) {
            $quantity = q_normalize_quantity((string) ($service['quantity'] ?? 0));
            $unitPrice = q_parse_money((string) ($service['unit_price'] ?? '0'));
            $subtotal = $quantity * $unitPrice;
            $total += $subtotal;
            $normalized[] = [
                'name' => (string) ($service['name'] ?? ''),
                'description' => (string) ($service['description'] ?? ''),
                'quantity' => $quantity,
                'unit_price' => $unitPrice,
                'subtotal' => $subtotal,
            ];
        }
        return [$normalized, $total];
    }
}
