<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Campaign;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class QueueControlController extends Controller
{
    /**
     * Show queue control panel + list of campaigns with active queues and jobs
     */
    public function index(Request $request)
    {
        $campaigns = Campaign::orderBy('created_at', 'desc')->get();
        
        // Get active queues (distinct queue names from campaigns that are running/pending/dispatched)
        $activeQueues = Campaign::whereIn('status', ['running', 'pending', 'dispatched', 'paused'])
            ->whereNotNull('queue_name')
            ->distinct()
            ->pluck('queue_name')
            ->toArray();

        // Get active jobs from the jobs table
        $activeJobs = DB::table('jobs')
            ->select('queue', 'payload')
            ->get()
            ->map(function ($job) {
                $payload = json_decode($job->payload, true);
                $jobClass = $payload['displayName'] ?? 'Unknown';
                return [
                    'queue' => $job->queue,
                    'job_class' => $jobClass,
                    'payload' => $job->payload
                ];
            });

        // Group jobs by queue
        $jobsByQueue = $activeJobs->groupBy('queue');

        // Get countries with active campaigns
        $activeCountries = Campaign::whereIn('status', ['running', 'pending', 'dispatched', 'paused'])
            ->whereNotNull('country')
            ->distinct()
            ->pluck('country')
            ->toArray();

        return view('dashboard.queue_control.index', compact('campaigns', 'activeQueues', 'jobsByQueue', 'activeCountries'));
    }

    /**
     * Pause all running/dispatched/pending campaigns (set status = paused)
     */
    public function pauseAll(Request $request)
    {
        Campaign::whereIn('status', ['running','dispatched','pending'])->update(['status' => 'paused']);
        return response()->json(['success' => true, 'message' => 'All campaigns paused']);
    }

    /**
     * Resume all paused campaigns (set status = running)
     */
    public function resumeAll(Request $request)
    {
        Campaign::where('status', 'paused')->update(['status' => 'running']);
        return response()->json(['success' => true, 'message' => 'All campaigns resumed']);
    }

    /**
     * Cancel all campaigns: set status cancelled and delete pending jobs from jobs table that belong to our jobs.
     * WARNING: this deletes entries from jobs table that match our job class names.
     */
    public function cancelAll(Request $request)
    {
        // mark campaigns cancelled
        Campaign::whereIn('status', ['pending','running','paused','dispatched'])->update(['status' => 'cancelled']);

        // delete jobs entries that reference our job classes in payload
        try {
            DB::table('jobs')->where('payload', 'like', '%SendSingleEmailJob%')->delete();
            DB::table('jobs')->where('payload', 'like', '%CampaignJob%')->delete();
            DB::table('jobs')->where('payload', 'like', '%SendMultiMailsJob%')->delete();
        } catch (\Exception $e) {
            Log::error("QueueControlController::cancelAll error deleting jobs: ".$e->getMessage());
            return response()->json(['success' => false, 'message' => 'Error deleting jobs: '.$e->getMessage()], 500);
        }

        return response()->json(['success' => true, 'message' => 'All campaigns cancelled and pending jobs removed']);
    }

    /**
     * Pause campaigns by queue names
     */
    public function pauseByQueues(Request $request)
    {
        $queueNames = $request->input('queue_names', []);
        if (empty($queueNames)) {
            return response()->json(['success' => false, 'message' => 'No queues selected'], 400);
        }

        Campaign::whereIn('queue_name', $queueNames)
            ->whereIn('status', ['running','dispatched','pending'])
            ->update(['status' => 'paused']);

        return response()->json(['success' => true, 'message' => 'Selected queues paused']);
    }

    /**
     * Resume campaigns by queue names
     */
    public function resumeByQueues(Request $request)
    {
        $queueNames = $request->input('queue_names', []);
        if (empty($queueNames)) {
            return response()->json(['success' => false, 'message' => 'No queues selected'], 400);
        }

        Campaign::whereIn('queue_name', $queueNames)
            ->where('status', 'paused')
            ->update(['status' => 'running']);

        return response()->json(['success' => true, 'message' => 'Selected queues resumed']);
    }

    /**
     * Cancel campaigns by queue names and delete their jobs
     */
    public function cancelByQueues(Request $request)
    {
        $queueNames = $request->input('queue_names', []);
        if (empty($queueNames)) {
            return response()->json(['success' => false, 'message' => 'No queues selected'], 400);
        }

        // mark campaigns cancelled
        Campaign::whereIn('queue_name', $queueNames)
            ->whereIn('status', ['pending','running','paused','dispatched'])
            ->update(['status' => 'cancelled']);

        // delete jobs for these queues
        try {
            DB::table('jobs')->whereIn('queue', $queueNames)->delete();
        } catch (\Exception $e) {
            Log::error("QueueControlController::cancelByQueues error deleting jobs: ".$e->getMessage());
            return response()->json(['success' => false, 'message' => 'Error deleting jobs: '.$e->getMessage()], 500);
        }

        return response()->json(['success' => true, 'message' => 'Selected queues cancelled and jobs removed']);
    }

    /**
     * Pause campaigns by countries
     */
    public function pauseByCountries(Request $request)
    {
        $countries = $request->input('countries', []);
        if (empty($countries)) {
            return response()->json(['success' => false, 'message' => 'No countries selected'], 400);
        }

        Campaign::whereIn('country', $countries)
            ->whereIn('status', ['running','dispatched','pending'])
            ->update(['status' => 'paused']);

        return response()->json(['success' => true, 'message' => 'Campaigns for selected countries paused']);
    }

    /**
     * Resume campaigns by countries
     */
    public function resumeByCountries(Request $request)
    {
        $countries = $request->input('countries', []);
        if (empty($countries)) {
            return response()->json(['success' => false, 'message' => 'No countries selected'], 400);
        }

        Campaign::whereIn('country', $countries)
            ->where('status', 'paused')
            ->update(['status' => 'running']);

        return response()->json(['success' => true, 'message' => 'Campaigns for selected countries resumed']);
    }

    /**
     * Cancel campaigns by countries and delete their jobs
     */
    public function cancelByCountries(Request $request)
    {
        $countries = $request->input('countries', []);
        if (empty($countries)) {
            return response()->json(['success' => false, 'message' => 'No countries selected'], 400);
        }

        // Get queue names for these countries
        $queueNames = Campaign::whereIn('country', $countries)
            ->whereIn('status', ['pending','running','paused','dispatched'])
            ->pluck('queue_name')
            ->unique()
            ->toArray();

        // mark campaigns cancelled
        Campaign::whereIn('country', $countries)
            ->whereIn('status', ['pending','running','paused','dispatched'])
            ->update(['status' => 'cancelled']);

        // delete jobs for these queues
        try {
            if (!empty($queueNames)) {
                DB::table('jobs')->whereIn('queue', $queueNames)->delete();
            }
        } catch (\Exception $e) {
            Log::error("QueueControlController::cancelByCountries error deleting jobs: ".$e->getMessage());
            return response()->json(['success' => false, 'message' => 'Error deleting jobs: '.$e->getMessage()], 500);
        }

        return response()->json(['success' => true, 'message' => 'Campaigns for selected countries cancelled and jobs removed']);
    }

    /**
     * Pause single campaign
     */
    public function pauseCampaign($id)
    {
        $c = Campaign::find($id);
        if (!$c) return response()->json(['success'=>false,'message'=>'Not found'],404);
        $c->update(['status'=>'paused']);
        return response()->json(['success'=>true,'message'=>'Campaign paused']);
    }

    /**
     * Resume single campaign
     */
    public function resumeCampaign($id)
    {
        $c = Campaign::find($id);
        if (!$c) return response()->json(['success'=>false,'message'=>'Not found'],404);
        $c->update(['status'=>'running']);
        return response()->json(['success'=>true,'message'=>'Campaign resumed']);
    }

    /**
     * Cancel single campaign and delete its pending jobs
     */
    public function cancelCampaign($id)
    {
        $c = Campaign::find($id);
        if (!$c) return response()->json(['success'=>false,'message'=>'Not found'],404);
        $c->update(['status'=>'cancelled']);

        // delete jobs for this campaign from jobs table (database queue driver)
        try {
            DB::table('jobs')->where('payload','like','%"campaignId":'.$c->id.'%')->delete();
            // also remove jobs with payload referencing campaign id in any form
            DB::table('jobs')->where('payload','like','%\"'.$c->id.'\"%')->delete();
        } catch (\Exception $e) {
            Log::error("QueueControlController::cancelCampaign error deleting jobs: ".$e->getMessage());
        }

        return response()->json(['success'=>true,'message'=>'Campaign cancelled and jobs removed']);
    }

    /**
     * Get real-time queue statistics
     */
    public function getQueueStats()
    {
        // Get queue statistics
        $stats = [];
        
        // Count jobs per queue
        $jobCounts = DB::table('jobs')
            ->select('queue', DB::raw('count(*) as job_count'))
            ->groupBy('queue')
            ->get();

        foreach ($jobCounts as $count) {
            $stats[$count->queue] = [
                'pending_jobs' => $count->job_count,
                'campaigns' => Campaign::where('queue_name', $count->queue)
                    ->whereIn('status', ['running', 'pending', 'dispatched', 'paused'])
                    ->count()
            ];
        }

        return response()->json(['success' => true, 'stats' => $stats]);
    }
}