<?php

namespace App\Http\Controllers;

use App\Models\BioTimeDevice;
use App\Models\BioTimeAttendanceLog;
use App\Models\Area;
use App\Models\DeviceCommand;
use App\Models\Employee;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class BioTimeDeviceController extends Controller
{
    private function ensureDevicePermission(): void
    {
        $user = Auth::user();
        if (! $user->canAccess('can_manage_devices')) {
            abort(403);
        }
    }

    private function queueDeviceCommand(BioTimeDevice $device, string $commandText): void
    {
        DeviceCommand::create([
            'device_sn' => $device->sn,
            'command_text' => $commandText,
        ]);
    }

    public function index()
    {
        $devices = BioTimeDevice::query()
            ->withCount([
                'commands as pending_commands_count' => function ($q) {
                    $q->where('status', 'pending');
                },
            ])
            ->addSelect([
                'last_log_sync_at' => BioTimeAttendanceLog::query()
                    ->select('synced_at')
                    ->whereColumn('terminal_sn', 'bio_time_devices.sn')
                    ->latest('synced_at')
                    ->limit(1),
            ])
            ->latest()
            ->paginate(10);
        return view('attendance.devices.index', compact('devices'));
    }

    public function create()
    {
        $areas = Area::where('active', true)->get();
        return view('attendance.devices.create', compact('areas'));
    }

    public function store(Request $request)
    {
        $request->validate([
            'sn' => 'required|unique:bio_time_devices,sn',
            'alias' => 'nullable|string|max:255',
            'area_id' => 'nullable|exists:areas,id',
            'ip_address' => 'nullable|ip',
            'device_model' => 'nullable|string',
            'is_active' => 'boolean',
        ]);

        BioTimeDevice::create($request->all());

        return redirect()->route('biotime-devices.index')
            ->with('success', 'BioTime Device added successfully.');
    }

    public function edit(BioTimeDevice $biotimeDevice)
    {
        $areas = Area::where('active', true)->get();
        $commands = DeviceCommand::where('device_sn', $biotimeDevice->sn)->latest()->take(10)->get();
        return view('attendance.devices.edit', compact('biotimeDevice', 'areas', 'commands'));
    }

    public function update(Request $request, BioTimeDevice $biotimeDevice)
    {
        $request->validate([
            'sn' => 'required|unique:bio_time_devices,sn,' . $biotimeDevice->id,
            'alias' => 'nullable|string|max:255',
            'area_id' => 'nullable|exists:areas,id',
            'ip_address' => 'nullable|ip',
            'device_model' => 'nullable|string',
            'is_active' => 'boolean',
        ]);

        $biotimeDevice->update($request->all());

        return redirect()->route('biotime-devices.index')
            ->with('success', 'BioTime Device updated successfully.');
    }

    public function destroy(BioTimeDevice $biotimeDevice)
    {
        $biotimeDevice->delete();

        return redirect()->route('biotime-devices.index')
            ->with('success', 'BioTime Device deleted successfully.');
    }

    public function toggleLock(BioTimeDevice $biotimeDevice)
    {
        $this->ensureDevicePermission();

        $biotimeDevice->update(['is_active' => ! $biotimeDevice->is_active]);

        return redirect()->route('biotime-devices.index')
            ->with('success', $biotimeDevice->is_active ? 'Device unlocked.' : 'Device locked.');
    }

    public function readInfo(BioTimeDevice $biotimeDevice)
    {
        $this->ensureDevicePermission();
        $this->queueDeviceCommand($biotimeDevice, 'C:INFO');
        return redirect()->route('biotime-devices.index')->with('success', 'Device info command queued.');
    }

    public function removeAdminAccess(BioTimeDevice $biotimeDevice)
    {
        $this->ensureDevicePermission();

        $employees = Employee::all();
        foreach ($employees as $e) {
            $cmd = "C:DATA USER PIN={$e->employee_code}\tPri=0";
            $this->queueDeviceCommand($biotimeDevice, $cmd);
        }

        return redirect()->route('biotime-devices.index')->with('success', 'Remove admin access commands queued.');
    }

    public function syncUsersFromDevice(BioTimeDevice $biotimeDevice)
    {
        $this->ensureDevicePermission();
        $this->queueDeviceCommand($biotimeDevice, 'C:DATA QUERY USER');
        return redirect()->route('biotime-devices.index')->with('success', 'Sync users from device command queued.');
    }

    public function reboot(BioTimeDevice $biotimeDevice)
    {
        $this->ensureDevicePermission();
        $this->queueDeviceCommand($biotimeDevice, 'C:REBOOT');
        return redirect()->route('biotime-devices.index')->with('success', 'Reboot command queued.');
    }

    public function clearPendingCommands(BioTimeDevice $biotimeDevice)
    {
        $this->ensureDevicePermission();

        $deleted = DeviceCommand::query()
            ->where('device_sn', $biotimeDevice->sn)
            ->where(function ($q) {
                $q->where('status', 'pending')->orWhereNull('status');
            })
            ->delete();

        return redirect()->route('biotime-devices.index')->with('success', "Cleared {$deleted} pending commands.");
    }

    public function liveTransactions(Request $request)
    {
        $this->ensureDevicePermission();

        $query = BioTimeAttendanceLog::query()->with(['employee', 'area'])->latest('punch_time');

        if ($request->filled('sn')) {
            $query->where('terminal_sn', $request->sn);
        }

        if ($request->filled('area_id')) {
            $query->where('area_id', $request->area_id);
        }

        $logs = $query->paginate(50)->withQueryString();
        $areas = Area::where('active', true)->get();
        $devices = BioTimeDevice::query()->orderBy('sn')->get(['sn', 'alias']);

        return view('attendance.devices.live_transactions', compact('logs', 'areas', 'devices'));
    }
}
