<?php

namespace App\Console\Commands;

use App\Models\FingerprintMachine;
use App\Services\Fingerprint\FingerprintDeviceManager;
use Illuminate\Console\Command;

class FingerprintTestCommand extends Command
{
    protected $signature = 'fingerprint:test {machine : ID or IP or Cloud ID of the fingerprint machine}';

    protected $description = 'Run layered diagnostic test for a Fingerspot Revo W-231N machine (Network, TCP/Cloud, Protocol, Auth, Attendance API)';

    public function handle(FingerprintDeviceManager $deviceManager): int
    {
        $machineInput = $this->argument('machine');

        $machine = is_numeric($machineInput)
            ? FingerprintMachine::find($machineInput)
            : FingerprintMachine::where('ip_address', $machineInput)
                ->orWhere('cloud_id', $machineInput)
                ->first();

        if (!$machine) {
            $this->error("Mesin fingerprint '{$machineInput}' tidak ditemukan.");
            return Command::FAILURE;
        }

        $this->info("=================================================");
        $this->info(" DIAGNOSTIC TEST: {$machine->name}");
        $this->info(" Connection Type: " . strtoupper($machine->connection_type ?? 'local'));
        $this->info(" Protocol       : " . strtoupper($machine->protocol ?? 'fingerspot_local'));
        if (($machine->connection_type ?? 'local') === 'cloud') {
            $this->info(" Cloud ID       : {$machine->cloud_id}");
        } else {
            $this->info(" IP Address     : {$machine->ip_address}");
            $this->info(" Port           : {$machine->port}");
        }
        $this->info("=================================================");

        $provider = $deviceManager->make($machine);

        // LAYER 1: NETWORK / API REACHABILITY TEST
        $this->comment("\n[Layer 1] Testing Connectivity...");
        $tcpRes = $provider->testTcpConnection($machine);

        if ($tcpRes['tcp_connected']) {
            $this->info("  [PASS] Endpoint/Socket reachable ({$tcpRes['latency_ms']}ms)");
        } else {
            $this->error("  [FAIL] Connection failed: {$tcpRes['message']}");
            $this->warn("  [STOP] Diagnostic halted because endpoint is unreachable.");
            return Command::FAILURE;
        }

        // LAYER 2: PROTOCOL HANDSHAKE / CONFIG TEST
        $this->comment("\n[Layer 2] Testing Protocol Configuration...");
        $protoRes = $provider->testProtocol($machine);

        if ($protoRes['protocol_detected']) {
            $this->info("  [PASS] Protocol configuration verified ({$protoRes['protocol_name']})");
        } else {
            $this->warn("  [FAIL] Protocol verification failed: {$protoRes['message']}");
        }

        // LAYER 3: DEVICE INFORMATION
        $this->comment("\n[Layer 3] Fetching Device Information...");
        $infoRes = $provider->getDeviceInfo($machine);

        if ($infoRes['success']) {
            $this->info("  [PASS] Device info retrieved successfully.");
            foreach ($infoRes['device_info'] as $key => $val) {
                if (is_array($val)) {
                    $val = json_encode($val);
                }
                $this->line("         - {$key}: {$val}");
            }
        } else {
            $this->warn("  [FAIL] Unable to read device info: {$infoRes['message']}");
        }

        // LAYER 4: FUNCTIONAL ATTENDANCE LOG TEST
        $this->comment("\n[Layer 4] Fetching Attendance Logs...");
        $attRes = $provider->getAttendanceLogs($machine);

        if ($attRes['success']) {
            $count = count($attRes['logs']);
            $this->info("  [PASS] Successfully fetched {$count} raw attendance logs.");
            if ($count > 0) {
                $sample = array_slice($attRes['logs'], 0, 3);
                $this->comment("         Sample logs:");
                foreach ($sample as $log) {
                    $arr = method_exists($log, 'toArray') ? $log->toArray() : (array) $log;
                    $this->line("         - User PIN: {$arr['employee_pin']} | Time: {$arr['attendance_time']} | Source: {$arr['source']}");
                }
            }
        } else {
            $this->warn("  [FAIL] Failed to fetch attendance logs: {$attRes['message']}");
        }

        $this->info("\n=================================================");
        $this->info(" DIAGNOSTIC SUMMARY");
        $this->line(" Network/API : " . ($tcpRes['tcp_connected'] ? 'PASS' : 'FAIL'));
        $this->line(" Protocol   : " . ($protoRes['protocol_detected'] ? 'PASS' : 'FAIL'));
        $this->line(" Device Info: " . ($infoRes['success'] ? 'PASS' : 'FAIL'));
        $this->line(" Attendance : " . ($attRes['success'] ? 'PASS' : 'FAIL'));
        $this->warn(" Hardware Status: PENDING PHYSICAL FINGERPRINT SCAN");
        $this->comment(" (Run 'php artisan fingerprint:verify-hardware {$machine->id}' when physical machine is ready)");
        $this->info("=================================================");

        return Command::SUCCESS;
    }
}
