<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\ProvisioningLog;
use App\Services\Provisioning\ProvisioningLogger;
use App\Traits\LogsAdminActivity;
use Illuminate\Http\Request;

class ProvisioningLogController extends Controller
{
    use LogsAdminActivity;

    public function __construct(private ProvisioningLogger $logger) {}

    public function index(Request $request)
    {
        $query = ProvisioningLog::query()->latest();

        if ($status = $request->input('status')) {
            $query->where('status', $status);
        }
        if ($family = $request->input('family')) {
            $query->where('module_family', $family);
        }
        if ($module = $request->input('module')) {
            $query->where('module_name', $module);
        }
        if ($q = $request->input('q')) {
            $query->where(function ($qb) use ($q) {
                $qb->where('error_message', 'like', "%{$q}%")
                    ->orWhere('module_name', 'like', "%{$q}%")
                    ->orWhere('action', 'like', "%{$q}%");
            });
        }

        $logs = $query->paginate(50);

        $stats = [
            'pending' => ProvisioningLog::pending()->count(),
            'failed' => ProvisioningLog::failed()->count(),
            'due_for_retry' => ProvisioningLog::dueForRetry()->count(),
        ];

        return view('admin.provisioning-logs.index', compact('logs', 'stats'));
    }

    public function show(ProvisioningLog $provisioningLog)
    {
        return view('admin.provisioning-logs.show', ['log' => $provisioningLog]);
    }

    public function retry(Request $request, ProvisioningLog $provisioningLog)
    {
        if (! $provisioningLog->canRetry()) {
            return back()->withErrors(['retry' => __('admin/provisioning-logs.cannot_retry')]);
        }

        // Mark as pending — actual retry dispatch is module-specific.
        // For now we surface the row to the cron retry command; provisioning
        // services will pick it up on the next attempt cycle.
        $provisioningLog->update([
            'status' => ProvisioningLog::STATUS_PENDING,
            'next_retry_at' => now(),
            'resolved_by_admin_id' => $request->user('admin')?->id,
        ]);

        $this->logUpdated(
            model: $provisioningLog,
            description: "Manual retry queued for provisioning log #{$provisioningLog->id}"
        );

        return back()->with('success', __('admin/provisioning-logs.retry_queued'));
    }

    public function dismiss(Request $request, ProvisioningLog $provisioningLog)
    {
        $reason = (string) $request->input('reason', '');
        $this->logger->markDismissed($provisioningLog, $request->user('admin')?->id, $reason ?: null);

        $this->logUpdated(
            model: $provisioningLog,
            description: "Provisioning log #{$provisioningLog->id} dismissed by admin"
        );

        return back()->with('success', __('admin/provisioning-logs.dismissed'));
    }

    public function bulkRetry(Request $request)
    {
        $ids = array_filter((array) $request->input('ids', []));

        if (empty($ids)) {
            return back()->withErrors(['ids' => __('admin/provisioning-logs.bulk_retry_none_selected')]);
        }

        $count = 0;
        foreach (ProvisioningLog::whereIn('id', $ids)->get() as $log) {
            if ($log->canRetry()) {
                $log->update([
                    'status' => ProvisioningLog::STATUS_PENDING,
                    'next_retry_at' => now(),
                    'resolved_by_admin_id' => $request->user('admin')?->id,
                ]);
                $count++;
            }
        }

        return back()->with('success', __('admin/provisioning-logs.bulk_retried', ['count' => $count]));
    }
}
