<?php

namespace App\Console\Commands;

use App\Helpers\Legacy5130Calculator;
use App\Services\Quote\FormulaEvaluatorService;
use Illuminate\Console\Command;

/**
 * 5130 견적 계산 결과 검증 커맨드
 *
 * 5130 레거시 시스템의 계산 결과와 SAM의 계산 결과가 동일한지 검증합니다.
 *
 * Usage:
 *   php artisan migration:verify-5130-calculation
 *   php artisan migration:verify-5130-calculation --W0=3000 --H0=2500 --type=screen
 */
class Verify5130Calculation extends Command
{
    protected $signature = 'migration:verify-5130-calculation
                            {--W0=2500 : 개구부 폭 (mm)}
                            {--H0=2000 : 개구부 높이 (mm)}
                            {--qty=1 : 수량}
                            {--type=screen : 제품 유형 (screen, steel)}
                            {--tenant-id=1 : 테넌트 ID}
                            {--finished-goods= : 완제품 코드 (BOM 계산 시)}
                            {--verbose-mode : 상세 출력 모드}';

    protected $description = '5130 레거시 계산 결과와 SAM 계산 결과 비교 검증';

    public function handle(FormulaEvaluatorService $formulaEvaluator): int
    {
        $this->info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
        $this->info('  5130 → SAM 견적 계산 검증');
        $this->info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
        $this->newLine();

        // 입력 파라미터
        $W0 = (float) $this->option('W0');
        $H0 = (float) $this->option('H0');
        $qty = (int) $this->option('qty');
        $productType = $this->option('type');
        $tenantId = (int) $this->option('tenant-id');
        $finishedGoodsCode = $this->option('finished-goods');
        $verboseMode = $this->option('verbose-mode');

        $this->info('📥 입력 파라미터:');
        $this->table(
            ['항목', '값'],
            [
                ['개구부 폭 (W0)', "{$W0} mm"],
                ['개구부 높이 (H0)', "{$H0} mm"],
                ['수량 (QTY)', $qty],
                ['제품 유형', $productType],
                ['테넌트 ID', $tenantId],
            ]
        );
        $this->newLine();

        // 1. Legacy5130Calculator로 계산 (5130 호환 모드)
        $this->info('🔄 Step 1: Legacy5130Calculator 계산 (5130 호환)');
        $legacyResult = Legacy5130Calculator::calculateEstimate($W0, $H0, $qty, $productType);

        $this->table(
            ['항목', '값'],
            [
                ['제작 폭 (W1)', "{$legacyResult['calculated']['W1']} mm"],
                ['제작 높이 (H1)', "{$legacyResult['calculated']['H1']} mm"],
                ['면적 (M)', "{$legacyResult['calculated']['area_m2']} m²"],
                ['중량 (K)', "{$legacyResult['calculated']['weight_kg']} kg"],
                ['브라켓 인치', "{$legacyResult['calculated']['bracket_inch']} inch"],
                ['모터 용량', $legacyResult['motor']['capacity']],
                ['브라켓 사이즈', $legacyResult['motor']['bracket_dimensions']],
            ]
        );
        $this->newLine();

        // 2. SAM FormulaEvaluatorService로 계산
        $this->info('🔄 Step 2: SAM FormulaEvaluatorService 계산');

        if ($finishedGoodsCode) {
            // BOM 기반 계산
            $samResult = $formulaEvaluator->calculateBomWithDebug(
                $finishedGoodsCode,
                ['W0' => $W0, 'H0' => $H0, 'QTY' => $qty],
                $tenantId
            );

            if (! $samResult['success']) {
                $this->error('SAM 계산 실패: '.($samResult['error'] ?? '알 수 없는 오류'));

                return Command::FAILURE;
            }

            $samVariables = $samResult['variables'];
        } else {
            // 직접 계산 (변수만)
            $samVariables = $this->calculateSamVariables($W0, $H0, $productType);
            $samResult = ['success' => true, 'variables' => $samVariables];
        }

        $this->table(
            ['항목', '값'],
            [
                ['제작 폭 (W1)', ($samVariables['W1'] ?? 'N/A').' mm'],
                ['제작 높이 (H1)', ($samVariables['H1'] ?? 'N/A').' mm'],
                ['면적 (M)', round($samVariables['M'] ?? 0, 4).' m²'],
                ['중량 (K)', round($samVariables['K'] ?? 0, 2).' kg'],
            ]
        );
        $this->newLine();

        // 3. 결과 비교
        $this->info('🔍 Step 3: 결과 비교');

        $comparison = [
            ['W1 (제작 폭)', $legacyResult['calculated']['W1'], $samVariables['W1'] ?? 0],
            ['H1 (제작 높이)', $legacyResult['calculated']['H1'], $samVariables['H1'] ?? 0],
            ['M (면적)', $legacyResult['calculated']['area_m2'], round($samVariables['M'] ?? 0, 4)],
            ['K (중량)', $legacyResult['calculated']['weight_kg'], round($samVariables['K'] ?? 0, 2)],
        ];

        $allMatch = true;
        $comparisonTable = [];

        foreach ($comparison as [$name, $legacy, $sam]) {
            $diff = abs($legacy - $sam);
            $percentDiff = $legacy != 0 ? ($diff / abs($legacy)) * 100 : 0;
            $match = $percentDiff < 1; // 1% 이내 허용

            if (! $match) {
                $allMatch = false;
            }

            $comparisonTable[] = [
                $name,
                $legacy,
                $sam,
                round($diff, 4),
                round($percentDiff, 2).'%',
                $match ? '✅ 일치' : '❌ 불일치',
            ];
        }

        $this->table(
            ['항목', '5130 (Legacy)', 'SAM', '차이', '차이율', '결과'],
            $comparisonTable
        );
        $this->newLine();

        // 4. 최종 결과
        if ($allMatch) {
            $this->info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
            $this->info('  ✅ 검증 성공: 5130과 SAM 계산 결과가 일치합니다.');
            $this->info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
        } else {
            $this->error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
            $this->error('  ❌ 검증 실패: 5130과 SAM 계산 결과가 불일치합니다.');
            $this->error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
        }

        // 상세 출력 모드
        if ($verboseMode) {
            $this->newLine();
            $this->info('📊 상세 정보 (Legacy5130Calculator):');
            $this->line(json_encode($legacyResult, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));

            if ($finishedGoodsCode && isset($samResult['debug_steps'])) {
                $this->newLine();
                $this->info('📊 상세 정보 (SAM Debug Steps):');
                foreach ($samResult['debug_steps'] as $step) {
                    $this->line("Step {$step['step']}: {$step['name']}");
                    $this->line(json_encode($step['data'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
                }
            }
        }

        return $allMatch ? Command::SUCCESS : Command::FAILURE;
    }

    /**
     * SAM 방식으로 변수 계산 (BOM 없이)
     */
    private function calculateSamVariables(float $W0, float $H0, string $productType): array
    {
        // 마진값 결정
        if (strtolower($productType) === 'steel') {
            $marginW = 110;
            $marginH = 350;
        } else {
            $marginW = 140;
            $marginH = 350;
        }

        $W1 = $W0 + $marginW;
        $H1 = $H0 + $marginH;
        $M = ($W1 * $H1) / 1000000;

        // 중량 계산
        if (strtolower($productType) === 'steel') {
            $K = $M * 25;
        } else {
            $K = $M * 2 + ($W0 / 1000) * 14.17;
        }

        return [
            'W0' => $W0,
            'H0' => $H0,
            'W1' => $W1,
            'H1' => $H1,
            'W' => $W1,
            'H' => $H1,
            'M' => $M,
            'K' => $K,
        ];
    }
}
