<?php
declare(strict_types=1);

namespace App\Modules\Carnets\Services;

/**
 * Simple QR Code generator — produces SVG output.
 * Uses a basic QR encoding algorithm without external libraries.
 * For production, this generates a simple encoded string representation.
 * The SVG renders a visual grid that encodes the membership number.
 */
final class QRCodeGenerator
{
    /**
     * Encode data into a string suitable for QR storage.
     */
    public static function encode(string $data): string
    {
        return 'THECLUB:' . $data . ':' . substr(md5($data . 'theclub_salt'), 0, 8);
    }

    /**
     * Render an SVG QR code from data.
     * This generates a simple matrix pattern that visually represents the data.
     * For a real production system, you'd integrate a proper QR library.
     * This implementation creates a deterministic visual pattern from the data hash.
     */
    public static function renderSvg(string $data, int $size = 200): string
    {
        $hash = md5($data . 'qr_render_key');
        $gridSize = 21; // Standard QR minimum
        $cellSize = $size / $gridSize;
        $matrix = self::generateMatrix($hash, $gridSize);

        $svg = '<svg xmlns="http://www.w3.org/2000/svg" width="' . $size . '" height="' . $size . '" viewBox="0 0 ' . $size . ' ' . $size . '">';
        $svg .= '<rect width="' . $size . '" height="' . $size . '" fill="white"/>';

        // Draw finder patterns (3 corners)
        $svg .= self::drawFinderPattern(0, 0, $cellSize);
        $svg .= self::drawFinderPattern(($gridSize - 7) * $cellSize, 0, $cellSize);
        $svg .= self::drawFinderPattern(0, ($gridSize - 7) * $cellSize, $cellSize);

        // Draw data cells
        for ($row = 0; $row < $gridSize; $row++) {
            for ($col = 0; $col < $gridSize; $col++) {
                if ($matrix[$row][$col]) {
                    // Skip finder pattern areas
                    if (self::isFinderArea($row, $col, $gridSize)) {
                        continue;
                    }
                    $x = $col * $cellSize;
                    $y = $row * $cellSize;
                    $svg .= '<rect x="' . round($x, 2) . '" y="' . round($y, 2) . '" width="' . round($cellSize, 2) . '" height="' . round($cellSize, 2) . '" fill="black"/>';
                }
            }
        }

        $svg .= '</svg>';
        return $svg;
    }

    private static function generateMatrix(string $hash, int $gridSize): array
    {
        $matrix = [];
        $extended = str_repeat($hash, (int) ceil(($gridSize * $gridSize) / strlen($hash)));
        $bits = '';
        for ($i = 0; $i < strlen($extended); $i++) {
            $bits .= str_pad(decbin(ord($extended[$i])), 8, '0', STR_PAD_LEFT);
        }

        $idx = 0;
        for ($row = 0; $row < $gridSize; $row++) {
            $matrix[$row] = [];
            for ($col = 0; $col < $gridSize; $col++) {
                if (self::isFinderArea($row, $col, $gridSize)) {
                    $matrix[$row][$col] = false;
                } else {
                    $matrix[$row][$col] = isset($bits[$idx]) && $bits[$idx] === '1';
                    $idx++;
                }
            }
        }

        return $matrix;
    }

    private static function isFinderArea(int $row, int $col, int $gridSize): bool
    {
        // Top-left finder pattern
        if ($row < 8 && $col < 8) return true;
        // Top-right finder pattern
        if ($row < 8 && $col >= $gridSize - 8) return true;
        // Bottom-left finder pattern
        if ($row >= $gridSize - 8 && $col < 8) return true;
        return false;
    }

    private static function drawFinderPattern(float $x, float $y, float $cellSize): string
    {
        $svg = '';
        $s = $cellSize;

        // Outer black 7x7
        $svg .= '<rect x="' . round($x, 2) . '" y="' . round($y, 2) . '" width="' . round(7 * $s, 2) . '" height="' . round(7 * $s, 2) . '" fill="black"/>';
        // Inner white 5x5
        $svg .= '<rect x="' . round($x + $s, 2) . '" y="' . round($y + $s, 2) . '" width="' . round(5 * $s, 2) . '" height="' . round(5 * $s, 2) . '" fill="white"/>';
        // Center black 3x3
        $svg .= '<rect x="' . round($x + 2 * $s, 2) . '" y="' . round($y + 2 * $s, 2) . '" width="' . round(3 * $s, 2) . '" height="' . round(3 * $s, 2) . '" fill="black"/>';

        return $svg;
    }
}