<?php

namespace App\Http\Controllers\SMS;

use App\Helpers\Helper;
use App\Http\Controllers\ConfigurationController;
use App\Http\Controllers\Controller;
use App\Jobs\ScheduleSmsJob;
use App\Jobs\SentSMSJob;
use App\Models\JobsHistory;
use App\Models\Message;
use App\Models\Number;
use App\Models\QuickSms;
use App\Models\ScheduleSMS;
use App\Models\SenderIdRequest;
use App\Models\SMSActivity;
use App\Services\MessageProcessService;
use App\Services\ScheduleService;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class QuickSmsController extends Controller
{
    use Helper;

    public function __construct()
    {
        $this->model = new QuickSms();
    }

    public function index()
    {
        if (!can('quick_sms_view')) {
            return $this->notPermitted();
        }
        try {
            $perPage = request()->input('perPage');
            $user = auth()->user();
            $keyword = input('phone');
            $user_id = request()->input('user_id') ? request()->input('user_id') : $user->id;
            $sender_id = input('sender_id');
            $start_date = input('start_date');
            $end_date = input('end_date');
            $status = input('status');
            $delivery_status = input('delivery_status');


            $data = SmsActivity::with(['numbers', 'message', 'sender'])
                ->where('user_id', $user_id)
                ->whereHas('numbers', function ($query) {
                    $query->whereIn('type', [1, 4]);
                })
                ->when($keyword, function ($query) use ($keyword) {
                    $query->whereHas('numbers', function ($query) use ($keyword) {
                        $query->where('phone', 'LIKE', "%$keyword%");
                    });
                })
                ->when($sender_id, function ($query) use ($sender_id) {
                    $query->whereHas('sender', function ($query) use ($sender_id) {
                        $query->where('sender_id', $sender_id);
                    });
                })
                ->when(($start_date || $end_date), function ($query) use ($start_date, $end_date) {
                    if ($start_date) {
                        $query->whereDate('created_at', '>=', $start_date);
                    }
                    if ($end_date) {
                        $query->whereDate('created_at', '<=', $end_date);
                    }
                })
                ->when(($status), function ($query) use ($status) {
                    if ($status == 'pending') {
                        $query->where('job_status', 0);
                    }
                    if ($status == 'success') {
                        $query->where('api_status', 9000);
                        $query->where('mno_status', 1000);
                    }
                    if ($status == 'failed') {
                        $query->where('job_status', 1);
                        $query->where(function ($query) use ($status) {
                            $query->where('api_status', '!=', 9000)
                                ->orWhere('mno_status', '!=', 1000);
                        });
                    }
                })
                ->when(($delivery_status), function ($query) use ($delivery_status) {
                    $query->where('check_api_status', $delivery_status);
                })
                ->orderBy('id', 'desc')
                ->paginate($perPage);

            return returnData(2000, $data);
        } catch (\Exception $exception) {
            return returnData(5000, $exception->getMessage(), $exception->getMessage());
        }
    }

    public function create()
    {
        //
    }

    public function store(Request $request)
    {
        if (!can('quick_sms_add')) {
            return $this->notPermitted();
        }
        $validate = $this->model->validate($request->all());

        if ($validate->fails()) {
            return returnData(3000, $validate->errors(), 'Validation Failed');
        }

        $phoneNumbersArray = numberFromInput('phone');

        $typeId = date("ymdHms");
        $isScheduleSMS = $request->input('schedule') > 0 ? true : false;
        $sender_id_type = $request->input('sender_id_type');
        $sms_type = $sender_id_type == 1 ? 'T' : 'P';
        $user_id = auth()->user()->id;
        $content_type = $request->input('content_type');
        $text = $request->input('body');
        $characterCount = ($content_type == 3) ? mb_strlen($text, "UTF-8") : strlen($text);

        $validateNumbers = $this->numberValidation($phoneNumbersArray, 1, $typeId);

        if (count($validateNumbers->invalids) > 0) {
            return returnData(3000, $validateNumbers->invalids, count($validateNumbers->invalids) . " Invalids number on the Inputed List");
        }

        $smsParts = smsPart($characterCount, $content_type);
        if (!$smsParts->status) {
            return returnData(5000, null, $smsParts->message);
        }

        $rate = $sender_id_type == 1 ? auth()->user()->masking_rate : auth()->user()->non_masking_rate;
        $balanceCheck = balanceCheck($smsParts->part, $rate, count($validateNumbers->insertArr));

        if (($balanceCheck->crrAmount < 0) && !$balanceCheck->allowNegative) {
            return returnData(5000, null, "Insufficient Balance ( $balanceCheck->crrAmount )");
        }

        if ($balanceCheck->allowNegative && ($balanceCheck->crrAmount <= -$balanceCheck->negativeLimit)) {
            return returnData(5000, null, "You are not allow to sent any sms, current Due Amount $balanceCheck->crrAmount");
        }

        DB::beginTransaction();
        $service = new MessageProcessService();
        $insertMessage = $service->messageInsert([
            'messageData' => $request->all(),
            'user_id' => $user_id,
            'part' => $smsParts->part,
            'characterCount' => $characterCount,
            'ip' => request()->ip(),
            'content_type' => $content_type,
            'numbers' => $validateNumbers->insertArr,
            'sender_id_type' => $sender_id_type,
            'isScheduleSMS' => $isScheduleSMS,
            'typeId' => $typeId,
            'sms_type' => $sms_type,
            'rate' => $rate
        ]);

        if (!$insertMessage->status) {
            DB::rollBack();
            return returnData(5000, null, $insertMessage->message);
        }

        DB::commit();
        return returnData(2000, null, 'Successfully Inserted');
    }

    public function show($id)
    {
        $detailsData = SmsActivity::with(['numbers', 'message', 'sender_id'])
            ->where('id', $id)
            ->first();

        if (!$detailsData) {
            return returnData(2000, []);
        }

        $detailsData['api_response'] = json_decode($detailsData['api_response']);
        return returnData(2000, $detailsData);
    }


    public function edit($id)
    {
        //
    }


    public function update(Request $request, $id)
    {
        $inside = isset($request->inside) ? true : false;

        $smsActivity = SMSActivity::where('id', $id)->first();
        if ($smsActivity) {
            $number = Number::where('id', $smsActivity->number_id)->first();
            $sender = SenderIdRequest::where('id', $smsActivity->sender_id)->first();
            $message = Message::where('id', $smsActivity->message_id)->first();

            $newActivity = new SMSActivity();
            $newActivity->fill(collect($smsActivity)->toArray());
            $newActivity->filter_id = $smsActivity->filter_id;
            $newActivity->filter_date = $smsActivity->filter_date;
            $newActivity->data = is_array($smsActivity->data) ? json_encode($smsActivity->data) : json_encode([]);
            $newActivity->save();

            $messageData = (object)[
                'number' => [$number->phone],
                //                'number' => [8801946492622],
                'body' => $message->body,
                'sms_type' => $message->content_type,
                'messageType' => $message->content_type,
                'transactionType' => 'T',
                'number_id' => $number->id,
            ];

            $ResponseData = sentSms($messageData, $sender);

            if ($ResponseData) {
                DB::table('sms_activities')->where('id', $newActivity->id)
                    ->update([
                        'job_status' => 1,
                        'api_status' => isset($ResponseData->serverResponseCode) ? $ResponseData->serverResponseCode : 0,
                        'mno_status' => isset($ResponseData->mnoResponseCode) ? $ResponseData->mnoResponseCode : 0,
                        'api_response' => json_encode($ResponseData),
                    ]);
            }

            if ($ResponseData->serverResponseCode != 9000) {
                insertFailLog($number->id, "Code : $ResponseData->serverResponseCode, Message : $ResponseData->serverResponseMessage", @json_encode($messageData), @json_encode($ResponseData));

                return $inside ? false : returnData(5000, null, 'Failed to resent SMS');
            }

            return $inside ? true : returnData(2000, null, 'Successfully Resent');
        }
    }

    public function destroy($id)
    {
        if (!can('quick_sms_delete')) {
            return $this->notPermitted();
        }
        try {
            $data = SmsActivity::where('user_id', user()->id)->where('id', $id)->first();
            if ($data) {
                $data->delete();
                Number::where('user_id', user()->id)->where('id', $data->number_id)->delete();

                return returnData(2000, $data, 'Successfully Deleted');
            }
            return returnData(5000, null, 'Data Not found');
        } catch (\Exception $exception) {
            return returnData(5000, $exception->getMessage(), 'Whoops, Something Went Wrong..!!');
        }
    }

    public function checkApiResponse($messageId = null, $callInside = false)
    {
        $message_id = $messageId ? $messageId : request()->input('message_id');
        $detailsData = SmsActivity::with(['numbers', 'message', 'sender_id', 'message_apis'])
            ->where('id', $message_id)
            ->first();


        $userSenders = DB::table('message_apis')
            ->where('user_id', $detailsData->user_id)
            ->where('id', $detailsData->sender_id)
            ->where('status', 1)
            ->first();

        $api_response = json_decode($detailsData['api_response']);
        $detailsData->{'serverTxnId'} = isset($api_response->serverTxnId) ? $api_response->serverTxnId : '';


        $deliveryResponse = checkDelivery($detailsData, $userSenders);

        if ($callInside) {
            return $deliveryResponse;
        }
        $returnData = [];
        $decode  = json_decode($detailsData->check_api_response, true);
        if (!empty($deliveryResponse->deliveryStatus)) {
            $returnData = $deliveryResponse;
        } else {
            $returnData = $decode;
        }

        return returnData(2000, $returnData);
    }

    public function updateCheckApiStatus($eachSms)
    {
        $deliveryData = $this->checkApiResponse(messageId: $eachSms->id, callInside: true);
        $deliveryStatuses = isset($deliveryData->deliveryStatus) ? $deliveryData->deliveryStatus : [];

        $finalStatus = 'UnDelivered';

        if (!empty($deliveryStatuses)) {
            foreach ($deliveryStatuses as $item) {
                $parts = explode('-', $item);
                $status = strtolower(trim($parts[1] ?? ''));

                if ($status == 'delivered') {
                    $finalStatus = 'Delivered';
                    break;
                }
                if ($status == 'delivery pending') {
                    $finalStatus = 'Pending';
                }
            }
        }
        if ($finalStatus) {
            $eachSms->check_api_status = $finalStatus;
            $eachSms->check_api_response = @json_encode($deliveryData);
            $eachSms->check_api_count = ($eachSms->check_api_count + 1);
            $eachSms->save();
        }
        return true;
    }

    public function updateCheckApiStatus2()
    {
        $date = request()->input('date');

        if (!$date) {
            dd('Plese Provide like : https://sms.tmssict.com/api/manual_check_api?date=date');
        }

        $formatDate = date('Y-m-d', strtotime($date));

        $smsData = DB::table('sms_activities')
            ->whereDate('created_at', $formatDate)
            ->whereNull('check_api_status')
            ->orderBy('id', 'DESC')
            ->get();

        foreach ($smsData as $eachSms) {
            $deliveryData = $this->checkApiResponse(messageId: $eachSms->id, callInside: true);

            $deliveryStatuses = isset($deliveryData->deliveryStatus) ? $deliveryData->deliveryStatus : '';
            $finalStatus = 'UnDelivered';

            if (!empty($deliveryStatuses)) {
                foreach ($deliveryStatuses as $item) {
                    $parts = explode('-', $item);
                    $status = strtolower(trim($parts[1] ?? ''));

                    if ($status == 'delivered') {
                        $finalStatus = 'Delivered';
                        break;
                    }
                }
            }

            if ($finalStatus) {
                DB::table('sms_activities')->where('id', $eachSms->id)->update([
                    'check_api_status' => $finalStatus,
                    'check_api_response' => @json_encode($deliveryData)
                ]);
            }
        }
    }
}
