<?php
/**
 * Tax Snapshot - Audit Trail
 * 
 * Preserves exact calculation details for audit purposes
 * Even if algorithm changes, old calculations remain verifiable
 * 
 * @package Odjoo
 * @category Finance
 * @version 3.0.0
 */
class TaxSnapshot
{
    /**
     * Create snapshot from calculation result
     * 
     * @param array $calculationResult TaxEngine result
     * @param array $metadata Additional metadata
     * @return array Snapshot data
     */
    public static function create(array $calculationResult, array $metadata = []): array
    {
        return [
            'version' => '3.0.0',
            'timestamp' => time(),
            'calculation' => [
                'total_net' => $calculationResult['total_net'],
                'total_vat' => $calculationResult['total_vat'],
                'total_gross' => $calculationResult['total_gross'],
                'global_discount' => $calculationResult['global_discount'],
                'currency' => $calculationResult['currency']
            ],
            'lines' => array_map(function($line) {
                return [
                    'unit_price_net' => $line['unit_price_net'],
                    'quantity' => $line['quantity'],
                    'vat_rate_basis' => $line['vat_rate_basis'],
                    'line_net_before_discount' => $line['line_net_before_discount'],
                    'line_discount' => $line['line_discount'],
                    'distributed_discount' => $line['distributed_discount'],
                    'line_net_final' => $line['line_net_final'],
                    'line_vat' => $line['line_vat'],
                    'line_gross' => $line['line_gross'],
                    'compensation' => $line['compensation']
                ];
            }, $calculationResult['lines']),
            'metadata' => array_merge([
                'input_type' => $metadata['input_type'] ?? 'net',
                'kdv_hesaplama_tipi' => $metadata['kdv_hesaplama_tipi'] ?? 'kdv_haric',
                'rounding_strategy' => $metadata['rounding_strategy'] ?? 'HALF_UP',
                'engine_version' => 'TaxEngine 3.0.0'
            ], $metadata)
        ];
    }
    
    /**
     * Serialize snapshot to JSON
     * 
     * @param array $snapshot
     * @return string
     */
    public static function toJson(array $snapshot): string
    {
        return json_encode($snapshot, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
    }
    
    /**
     * Deserialize snapshot from JSON
     * 
     * @param string $json
     * @return array|null
     */
    public static function fromJson(string $json): ?array
    {
        $snapshot = json_decode($json, true);
        
        if (json_last_error() !== JSON_ERROR_NONE) {
            return null;
        }
        
        return $snapshot;
    }
    
    /**
     * Verify snapshot integrity
     * 
     * @param array $snapshot
     * @return bool
     */
    public static function verify(array $snapshot): bool
    {
        // Check required fields
        if (!isset($snapshot['version']) || 
            !isset($snapshot['calculation']) || 
            !isset($snapshot['lines'])) {
            return false;
        }
        
        // Verify totals match line sums
        $lineNetSum = array_sum(array_column($snapshot['lines'], 'line_net_final'));
        $lineVatSum = array_sum(array_column($snapshot['lines'], 'line_vat'));
        
        if ($lineNetSum !== $snapshot['calculation']['total_net']) {
            return false;
        }
        
        if ($lineVatSum !== $snapshot['calculation']['total_vat']) {
            return false;
        }
        
        return true;
    }
    
    /**
     * Get human-readable trace
     * 
     * @param array $snapshot
     * @return string
     */
    public static function getTrace(array $snapshot): string
    {
        require_once __DIR__ . '/MoneyHelper.php';
        
        $trace = "=== TAX CALCULATION TRACE ===\n";
        $trace .= "Version: {$snapshot['version']}\n";
        $trace .= "Date: " . date('Y-m-d H:i:s', $snapshot['timestamp']) . "\n";
        $trace .= "Mode: " . ($snapshot['metadata']['kdv_hesaplama_tipi'] ?? 'unknown') . "\n\n";
        
        $trace .= "LINES:\n";
        foreach ($snapshot['lines'] as $index => $line) {
            $lineNum = $index + 1;
            $trace .= "Line {$lineNum}:\n";
            $trace .= "  Unit Price (Net): " . MoneyHelper::format($line['unit_price_net']) . "\n";
            $trace .= "  Quantity: {$line['quantity']}\n";
            $trace .= "  VAT Rate: " . ($line['vat_rate_basis'] / 100) . "%\n";
            $trace .= "  Net Before Discount: " . MoneyHelper::format($line['line_net_before_discount']) . "\n";
            
            if ($line['line_discount'] > 0) {
                $trace .= "  Line Discount: " . MoneyHelper::format($line['line_discount']) . "\n";
            }
            
            if ($line['distributed_discount'] > 0) {
                $trace .= "  Distributed Discount: " . MoneyHelper::format($line['distributed_discount']) . "\n";
            }
            
            $trace .= "  Net Final: " . MoneyHelper::format($line['line_net_final']) . "\n";
            $trace .= "  VAT: " . MoneyHelper::format($line['line_vat']) . "\n";
            
            if ($line['compensation'] != 0) {
                $trace .= "  Compensation: " . MoneyHelper::format($line['compensation']) . " ⚠️\n";
            }
            
            $trace .= "  Gross: " . MoneyHelper::format($line['line_gross']) . "\n\n";
        }
        
        $trace .= "TOTALS:\n";
        $trace .= "  Total Net: " . MoneyHelper::format($snapshot['calculation']['total_net']) . "\n";
        $trace .= "  Total VAT: " . MoneyHelper::format($snapshot['calculation']['total_vat']) . "\n";
        
        if ($snapshot['calculation']['global_discount'] > 0) {
            $trace .= "  Global Discount: " . MoneyHelper::format($snapshot['calculation']['global_discount']) . "\n";
        }
        
        $trace .= "  Total Gross: " . MoneyHelper::format($snapshot['calculation']['total_gross']) . "\n";
        
        return $trace;
    }
}
