<?php

namespace App\Http\Controllers;

use App\Jobs\ResellerClientBillPaymentSyncJob;
use App\Jobs\ResellerClientMonthlyBillGenerateJob;
use App\Models\Client;
use App\Models\Pop;
use App\Models\Reseller;
use App\Models\ResellerBillGenerate;
use Brian2694\Toastr\Facades\Toastr;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class ResellerBillGenerateController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\ResellerBillGenerate  $resellerBillGenerate
     * @return \Illuminate\Http\Response
     */
    public function show(ResellerBillGenerate $resellerBillGenerate)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\ResellerBillGenerate  $resellerBillGenerate
     * @return \Illuminate\Http\Response
     */
    public function edit(ResellerBillGenerate $resellerBillGenerate)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\ResellerBillGenerate  $resellerBillGenerate
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, ResellerBillGenerate $resellerBillGenerate)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\ResellerBillGenerate  $resellerBillGenerate
     * @return \Illuminate\Http\Response
     */
    public function destroy(ResellerBillGenerate $resellerBillGenerate)
    {
        //
    }

    public function generateMonthlyBill($bill_month = null)
    {
        $resellersIds = Reseller::where('reseller_type','other')->pluck('id');
        $pops_id = Pop::whereIn('reseller_id', $resellersIds)->pluck('id');

            Client::with('pops','subpack','packages')
                    ->where('clients_status', '!=', 'deactive')
                    ->where('clients_status', '!=', 'close')
                    ->where('is_free', '!=', '1')
                    ->whereIn('pop_id', $pops_id)
                    ->select('id', 'expire_date', 'package_id', 'parmanent_discount')
            ->chunk(100, function ($clients) use ($bill_month) {
                ResellerClientMonthlyBillGenerateJob::dispatch($clients, $bill_month);
            });


    }

    public function billGenerateResellerClient(Request $request)
    {
        $clients = Client::with('pops','subpack','packages')->where('id',$request->id)->get();
        ResellerClientMonthlyBillGenerateJob::dispatch($clients,now());

        Toastr::success('Bill Generate Successfully');
        return redirect()->back();
    }

    public function addBillOtherResellerCustomer(Request $request)
    {
        try {
            DB::transaction(function () use ($request) {
                $client = Client::with('pops')->find($request->client_id);

                $resellerBillGenerate = new ResellerBillGenerate();
                $resellerBillGenerate->reseller_id = $client->pops->reseller_id;
                $resellerBillGenerate->client_id = $request->client_id;
                $resellerBillGenerate->amount = $request->amount;
                $resellerBillGenerate->paid_amount = 0;
                $resellerBillGenerate->due_amount = 0;
                $resellerBillGenerate->description = $request->description. ' by '. ' '.auth()->user()->name;
                $resellerBillGenerate->type = 'other';
                $resellerBillGenerate->save();


                if($client->customer_account_balance_reseller < 0){
                    ResellerClientBillPaymentSyncJob::dispatch($client->id);
                }

                $client->customer_account_balance_reseller = $client->customer_account_balance_reseller + $request->amount;
                $client->save();


            });
            Toastr::success('Bill Generate Successfully');
            return redirect()->back();

        }catch (\Exception $e) {

            Toastr::error('Something went wrong');
            return redirect()->back();
        }
    }

    public function resellerBillGenerateReport()
    {
        $resellers = Reseller::list()->where('reseller_type', '=', 'other');


        $start_date = now()->startOfMonth();
        $end_date = now()->endOfMonth();

        $clientsids = Client::list()->pluck('id');

        $start = Carbon::parse($start_date)->format('Y-m-d 00:00:00');
        $end = Carbon::parse($end_date)->format('Y-m-d 23:59:59');

        $resellerBillGenerates = ResellerBillGenerate::with('client','reseller')->whereIn('client_id', $clientsids)
        ->whereBetween('created_at', [$start, $end])->get();

       $data = [
        'reseller' => $resellers,
        'start' => $start_date,
        'end' => $end_date,
        'resellerBillGenerates' => $resellerBillGenerates,
       ];

    //    dd($resellerBillGenerates,$start,$end,$clientsids);

       return view('report.resellerClientAccount.billGenerate.report', $data);
    }

    public function resellerBillGenerateReportSearch(Request $request)
    {

        if($request->reseller_id){
            $resellers = Reseller::list()->where('reseller_type', '=', 'other')->where('id', $request->reseller_id)->pluck('id');
        }else{
            $resellers = Reseller::list()->where('reseller_type', '=', 'other')->pluck('id');
        }

        if($request->pop_id){
            $pops = Pop::where('reseller_id', $request->reseller_id)->pluck('id');
        }else{
            $pops = Pop::whereIn('reseller_id', $resellers)->pluck('id');
        }

        $clientsids = Client::whereIn('pop_id', $pops)->pluck('id');

        $start_date = Carbon::parse($request->from_date)->format('Y-m-d 00:00:00');
        $end_date = Carbon::parse($request->to_date)->format('Y-m-d 23:59:59');

        $resellerBillGenerates = ResellerBillGenerate::with('client','reseller')->whereIn('client_id', $clientsids)
                            ->whereBetween('created_at', [$start_date, $end_date])->get();


        $data = [
            'resellerBillGenerates' => $resellerBillGenerates,

        ];

        return view('report.resellerClientAccount.billGenerate.result', $data);
    }

    public function resellerClientBillDelete($id)
    {
        try {
            $clientId = null;
            $originalAmount = 0;

            DB::transaction(function () use ($id, &$clientId, &$originalAmount) {
                $resellerBillGenerate = ResellerBillGenerate::findOrFail($id);
                $originalAmount = $resellerBillGenerate->amount;

                if($originalAmount <= 0){
                    Toastr::error('Bill amount is less than 0');
                    return redirect()->back();
                }

                // Update bill
                $resellerBillGenerate->amount = 0;
                $resellerBillGenerate->description = "Bill amount {$originalAmount} deleted by " . auth()->user()->name . " at " . now();
                $resellerBillGenerate->type = "Deleted";
                $resellerBillGenerate->save();

                // Update client balance
                $client = Client::findOrFail($resellerBillGenerate->client_id);
                $client->customer_account_balance_reseller -= $originalAmount;
                $client->save();


                $clientId = $client->id;
            }, 1); // Retry once if deadlock

            // Dispatch job after transaction
            ResellerClientBillPaymentSyncJob::dispatch($clientId);

            Toastr::success('Bill deleted successfully');
        } catch (\Exception $e) {

            Toastr::error('Something went wrong while deleting the bill.');
        }

        return redirect()->back();
    }

}
