<?php

declare(strict_types=1);

namespace App\Console\Commands;

use App\Services\Compliance\IsmsControls;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

/**
 * `php artisan compliance:pia-report`
 *
 * Runs all 28 ISMS-P controls, persists each result to isms_check_runs,
 * and writes a human-readable markdown report to storage/app/compliance/pia/.
 *
 * Exit code:
 *   0 — all controls pass or skip
 *   1 — at least one fail
 *   2 — error during execution
 */
class CompliancePiaReport extends Command
{
    protected $signature = 'compliance:pia-report
        {--tenant= : Tenant UUID (omit for system-wide check)}
        {--format=md : md | json}';

    protected $description = 'Run ISMS-P 28 controls and write a PIA report.';

    public function handle(IsmsControls $controls): int
    {
        $tenantId = $this->option('tenant');
        $this->info('Running ISMS-P 28 controls'.($tenantId ? " for tenant {$tenantId}" : ''));

        $results = $controls->runAll();
        $failed = 0;
        $passed = 0;
        $skipped = 0;

        foreach ($results as $code => $result) {
            DB::table('isms_check_runs')->insert([
                'id' => Str::uuid()->toString(),
                'tenant_id' => $tenantId,
                'control_code' => $code,
                'status' => $result['status'],
                'evidence' => json_encode($result['evidence'] ?? [], JSON_UNESCAPED_UNICODE),
                'notes' => $result['notes'] ?? null,
                'ran_at' => now(),
            ]);

            match ($result['status']) {
                'pass' => $passed++,
                'fail' => $failed++,
                default => $skipped++,
            };
        }

        $report = $this->option('format') === 'json'
            ? $this->formatJson($results, $passed, $failed, $skipped)
            : $this->formatMarkdown($results, $passed, $failed, $skipped);

        $ext = $this->option('format') === 'json' ? 'json' : 'md';
        $path = sprintf('compliance/pia/pia-%s.%s', now()->format('Ymd-His'), $ext);
        Storage::disk('local')->put($path, $report);

        $this->line('');
        $this->info("Pass: {$passed}  Fail: {$failed}  Skip: {$skipped}");
        $this->info('Report: '.storage_path('app/'.$path));

        return $failed > 0 ? 1 : 0;
    }

    private function formatMarkdown(array $results, int $pass, int $fail, int $skip): string
    {
        $lines = [
            '# PIA Report ('.now()->toDateTimeString().')',
            '',
            "- pass: {$pass}",
            "- fail: {$fail}",
            "- skip: {$skip}",
            '',
            '| Code | Status | Notes |',
            '|------|--------|-------|',
        ];

        foreach ($results as $code => $r) {
            $notes = str_replace('|', '\\|', (string) ($r['notes'] ?? ''));
            $lines[] = "| {$code} | {$r['status']} | {$notes} |";
        }

        return implode("\n", $lines)."\n";
    }

    private function formatJson(array $results, int $pass, int $fail, int $skip): string
    {
        return (string) json_encode([
            'generated_at' => now()->toIso8601String(),
            'summary' => compact('pass', 'fail', 'skip'),
            'results' => $results,
        ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
    }
}
