<?php

namespace App\Http\Controllers\BulkSms;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\BulkSmsRequest;
use Illuminate\Support\Facades\Auth;
use App\Models\SendMessage;
use App\Models\ScheduleSendMessage;
use Illuminate\Http\JsonResponse;
use App\Jobs\ProcessBulkSmsJob;
use App\Jobs\ProcessScheduleSmsJob;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;

class BulkSmsController extends Controller
{
    public function fetchRoutes()
    {
        $user = Auth::user();

        $routes = SendMessage::getRoutesForUser($user);

        return response()->json([
            'status' => true,
            'data' => $routes
        ], 200);
    }

    public function fetchSenderId()
    {
        $user = Auth::user();

        $sender_id = SendMessage::getSenderIdsForUser($user);

        return response()->json([
            'status' => true,
            'data' => $sender_id
        ], 200);
    }

    public function fetchTemplateDetails(BulkSmsRequest $request)
    {
        $user = Auth::user();
        $senderId = $request->validated()['sender_ID'];

        $requestedUserId = null;
        
        if($user->role_ID == 2 || $user->role_ID == 3 || $user->role_ID == 4) 
        {
            $requestedUserId = $request->validated()['user_ID'] ?? null;
        }

        $template_details = SendMessage::getTemplateDetails($user, $senderId, $requestedUserId);

        return response()->json([
            'status' => true,
            'data' => $template_details
        ], 200);
    }

    public function fetchGroupDetails()
    {
        $user = Auth::user();

        $group_details = SendMessage::getGroupDetails($user);

        return response()->json([
            'status' => true,
            'data' => $group_details
        ], 200);
    }

    public function fetchNumbersCountFromGroup(BulkSmsRequest $request)
    {
        $user = Auth::user();

        $numbers_count  = SendMessage::getNumbersCountFromGroup($request->validated(), $user);

        return response()->json([
            'status' => true,
            'numbers_count' => $numbers_count 
        ], 200);
    }

    public function fetchNumbersCountFromCsv(BulkSmsRequest $request)
    {
        $user = Auth::user();

        $numbers = SendMessage::getNumbersCountFromCsv($request->validated(), $user);

        return response()->json([
            'status' => true,
            'numbers_count' => count($numbers)
        ], 200);
    }

    public function trackingUrlImageUpload(BulkSmsRequest $request)
    {
        $uploaded_image_path  = SendMessage::uploadTrackingUrlImage($request->validated());

        return response()->json([
            'status' => true,
            'message' => 'Image uploaded successfully.',
            'data' => [
                'image_path' => $uploaded_image_path
            ]
        ], 200);
    }

    // public function sendMessages(BulkSmsRequest $request): JsonResponse
    // {
    //     ini_set('memory_limit', '-1');
    //     ini_set('max_execution_time', 0);
        
    //     $user = Auth::user();

    //     $result = SendMessage::createAndProcess($request, $user);

    //     if(is_array($result) && isset($result['status']) && $result['status'] === false) 
    //     {
    //         return response()->json([
    //             'status' => false,
    //             'errors' => $result['message']
    //         ], 400);
    //     }

    //     return response()->json([
    //         'status' => true,
    //         'message' => 'Message created successfully.'
    //     ], 200);
    // }

    public function sendMessages(BulkSmsRequest $request): JsonResponse
    {
        ini_set('max_execution_time', -1);

        $user = Auth::user();

        // Call the modified createAndProcess function
        $result = SendMessage::createAndProcess($request, $user);

        if (is_array($result) && isset($result['status']) && $result['status'] === false) {
            return response()->json([
                'status' => false,
                'errors' => $result['message']
            ], 400);
        }

        // Check if this is an immediate response (bulk SMS)
        if (isset($result['immediate_response']) && $result['immediate_response'] === true) {
            
            // Prepare request data for background job
            $requestData = $this->prepareRequestDataForJob($request, $result['job_id']);
            
            // Dispatch background job
            ProcessBulkSmsJob::dispatch($requestData, $user, $result['job_id']);
            
            return response()->json([
                'status' => true,
                'message' => $result['message'],
                'job_id' => $result['job_id'],
                'estimated_count' => $result['estimated_count']
            ], 200);
        }

        return response()->json([
            'status' => true,
            'message' => isset($result['message']) ? $result['message'] : 'Message created successfully.'
        ], 200);
    }

    private function prepareRequestDataForJob($request, $jobId)
    {
        $data = [
            'route_name' => $request->route_name,
            'method' => $request->method,
            'campaign_name' => $request->campaign_name,
            'senderid' => $request->senderid,
            'template_ID' => $request->template_ID,
            'message' => $request->message,
            'unicode_type' => $request->unicode_type,
            'original_url' => $request->original_url,
            'numbers' => $request->numbers,
            'group_IDs' => $request->group_IDs,
            'ip' => $request->ip(),
            'form_type' => 'Bulk SMS',
        ];
        
        // Handle CSV file - store it and pass the path
        if ($request->hasFile('csv_file')) {
            $file = $request->file('csv_file');
            $fileName = 'csv_' . $jobId . '_' . time() . '.' . $file->getClientOriginalExtension();
            $filePath = $file->storeAs('temp_csv_jobs', $fileName);
            
            $data['csv_file_path'] = $filePath;
            $data['csv_file_name'] = $fileName;
            $data['csv_file_original_name'] = $file->getClientOriginalName();
            
        }
        
        return $data;
    }

    public function scheduleSendMessages(BulkSmsRequest $request): JsonResponse
    {
        $user = Auth::user();

        // Quick validation — returns immediately with job_id without parsing all numbers
        $result = ScheduleSendMessage::createAndProcessSchedule($request, $user);

        if (is_array($result) && isset($result['status']) && $result['status'] === false) {
            return response()->json([
                'status' => false,
                'errors' => $result['message'],
            ], 400);
        }

        // Immediate response path — process after response is sent (no queue worker required)
        if (isset($result['immediate_response']) && $result['immediate_response'] === true) {

            $requestData    = $this->prepareScheduleRequestDataForJob($request);
            $capturedUser   = $user;
            $capturedJobId  = $result['job_id'];

            app()->terminating(function () use ($requestData, $capturedUser, $capturedJobId) {
                @set_time_limit(0);
                @ini_set('memory_limit', '-1');

                try {
                    DB::reconnect(); // Re-establish DB connection after HTTP response is sent
                    $job = new ProcessScheduleSmsJob($requestData, $capturedUser, $capturedJobId);
                    $job->handle();
                } catch (\Throwable $e) {
                    // Exception is already logged inside handle(); swallow re-throw here.
                }
            });

            return response()->json([
                'status'          => true,
                'message'         => $result['message'],
                'job_id'          => $capturedJobId,
                'estimated_count' => $result['estimated_count'],
            ], 200);
        }

        return response()->json([
            'status'  => true,
            'message' => 'Message scheduled successfully.',
        ], 200);
    }

    private function prepareScheduleRequestDataForJob($request): array
    {
        $data = [
            '_route_context' => 'bulk_sms.scheduleSendMessages',
            'route_name'     => $request->route_name,
            'method'         => $request->method,
            'campaign_name'  => $request->campaign_name,
            'senderid'       => $request->senderid,
            'template_ID'    => $request->template_ID,
            'message'        => $request->message,
            'unicode_type'   => $request->unicode_type,
            'original_url'   => $request->original_url,
            'numbers'        => $request->numbers,
            'group_IDs'      => $request->group_IDs,
            'schedule_date'  => $request->schedule_date,
            'numbers_count'  => $request->numbers_count,
            'ip'             => $request->ip(),
        ];

        // Store large numbers string in a temp file to keep queue payload lean
        if ($request->method === 'Numbers' && !empty($request->numbers)) {
            $numbersStr = is_array($request->numbers)
                ? implode(',', $request->numbers)
                : $request->numbers;

            if (strlen($numbersStr) > 102400) { // > 100 KB — store in file
                $fileName  = 'schedule_numbers_' . uniqid() . '.txt';
                $filePath  = 'temp_schedule_jobs/' . $fileName;
                \Illuminate\Support\Facades\Storage::put($filePath, $numbersStr);
                $data['numbers']           = null;
                $data['numbers_file_path'] = $filePath;
            }
        }

        // Handle CSV upload
        if ($request->hasFile('csv_file')) {
            $file     = $request->file('csv_file');
            $fileName = 'schedule_csv_' . uniqid() . '.' . $file->getClientOriginalExtension();
            $filePath = $file->storeAs('temp_schedule_jobs', $fileName);
            $data['csv_file_path']          = $filePath;
            $data['csv_file_name']          = $fileName;
            $data['csv_file_original_name'] = $file->getClientOriginalName();
        }

        return $data;
    }
}
