<?php

declare(strict_types=1);

/**
 * Fonctions utilitaires pour BAO
 */

/**
 * Affiche un message coloré dans le terminal
 */
function color(string $text, string $color = 'default'): string {
    static $colors = [
        'default' => "\033[0m",
        'black' => "\033[0;30m",
        'red' => "\033[0;31m",
        'green' => "\033[0;32m",
        'yellow' => "\033[0;33m",
        'blue' => "\033[0;34m",
        'magenta' => "\033[0;35m",
        'cyan' => "\033[0;36m",
        'white' => "\033[0;37m",
        'bold' => "\033[1m",
        'underline' => "\033[4m",
    ];

    $config = DatabaseConfig::getInstance();
    $colorsEnabled = $config->get('COLORS_ENABLED', 'true') === 'true';

    if (!$colorsEnabled || !isset($colors[$color])) {
        return $text;
    }

    return $colors[$color] . $text . $colors['default'];
}

/**
 * Affiche un titre encadré
 */
function title(string $text): void {
    $length = strlen($text);
    $border = str_repeat('═', $length + 4);

    echo color("\n╔{$border}╗\n", 'cyan');
    echo color("║  {$text}  ║\n", 'cyan');
    echo color("╚{$border}╝\n\n", 'cyan');
}

/**
 * Affiche un message de succès
 */
function success(string $message): void {
    echo color("✓ ", 'green') . color($message, 'white') . "\n";
}

/**
 * Affiche un message d'erreur
 */
function error(string $message): void {
    echo color("✗ ", 'red') . color($message, 'white') . "\n";
}

/**
 * Affiche un message d'avertissement
 */
function warning(string $message): void {
    echo color("⚠ ", 'yellow') . color($message, 'white') . "\n";
}

/**
 * Affiche un message d'information
 */
function info(string $message): void {
    echo color("ℹ ", 'blue') . color($message, 'white') . "\n";
}

/**
 * Affiche un label et sa valeur
 */
function display(string $label, ?string $value, bool $encrypted = false): void {
    $labelColored = color($label . ':', 'yellow');

    if ($value === null) {
        $valueColored = color('(null)', 'magenta');
    } elseif ($encrypted && strpos($value, 'base64:') === 0) {
        $valueColored = color('[ENCRYPTED]', 'red');
    } else {
        $valueColored = color($value, 'white');
    }

    echo "  {$labelColored} {$valueColored}\n";
}

/**
 * Affiche une ligne de séparation
 */
function separator(int $length = 80): void {
    echo color(str_repeat('─', $length), 'cyan') . "\n";
}

/**
 * Demande une confirmation à l'utilisateur
 */
function confirm(string $question, bool $default = false): bool {
    $suffix = $default ? '[O/n]' : '[o/N]';
    echo color("{$question} {$suffix}: ", 'yellow');

    $handle = fopen('php://stdin', 'r');
    $line = trim(fgets($handle));
    fclose($handle);

    if (empty($line)) {
        return $default;
    }

    return in_array(strtolower($line), ['o', 'oui', 'y', 'yes']);
}

/**
 * Demande un choix parmi plusieurs options
 */
function choice(string $question, array $options, $default = null): string {
    echo color("\n{$question}\n", 'yellow');

    foreach ($options as $key => $label) {
        $prefix = ($key === $default) ? color('*', 'green') : ' ';
        echo "  {$prefix} " . color((string)$key, 'cyan') . ") {$label}\n";
    }

    echo color("\nVotre choix: ", 'yellow');

    $handle = fopen('php://stdin', 'r');
    $line = trim(fgets($handle));
    fclose($handle);

    if (empty($line) && $default !== null) {
        return (string)$default;
    }

    if (!isset($options[$line])) {
        error("Choix invalide");
        return choice($question, $options, $default);
    }

    return $line;
}

/**
 * Affiche un tableau formaté
 */
function table(array $headers, array $rows, bool $showIndex = true): void {
    if (empty($rows)) {
        warning("Aucune donnée à afficher");
        return;
    }

    // Calculer les largeurs de colonnes
    $widths = [];

    if ($showIndex) {
        $widths['#'] = max(strlen((string)count($rows)), 1) + 1;
    }

    foreach ($headers as $key => $label) {
        $widths[$key] = max(
            strlen($label),
            max(array_map(fn($row) => strlen((string)($row[$key] ?? '')), $rows))
        ) + 2;
    }

    // En-tête
    separator();

    if ($showIndex) {
        echo color(str_pad('#', $widths['#']), 'bold');
    }

    foreach ($headers as $key => $label) {
        echo color(str_pad($label, $widths[$key]), 'bold');
    }
    echo "\n";

    separator();

    // Lignes
    foreach ($rows as $index => $row) {
        if ($showIndex) {
            echo color(str_pad((string)($index + 1), $widths['#']), 'cyan');
        }

        foreach ($headers as $key => $label) {
            $value = $row[$key] ?? '';
            echo str_pad((string)$value, $widths[$key]);
        }
        echo "\n";
    }

    separator();
}

/**
 * Formate une date MySQL en français
 */
function formatDate(?string $date): string {
    if (empty($date) || $date === '0000-00-00' || $date === '0000-00-00 00:00:00') {
        return '-';
    }

    try {
        $dt = new DateTime($date);
        return $dt->format('d/m/Y H:i');
    } catch (Exception $e) {
        return $date;
    }
}

/**
 * Tronque une chaîne si elle est trop longue
 */
function truncate(string $text, int $length = 50): string {
    if (strlen($text) <= $length) {
        return $text;
    }

    return substr($text, 0, $length - 3) . '...';
}
