<?php

namespace App\Http\Controllers;

use App\Models\Client;
use App\Mail\InvoiceSend;
use App\Models\Billpayment;
use App\Models\Clientsinfo;
use App\Jobs\SendInvoiceJob;
use App\Jobs\SendMailJob;
use App\Models\BillGenerate;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use App\Models\CompanyInformation;
use App\Models\MailLog;
use App\Models\Pop;
use App\Models\Reseller;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Database\Eloquent\Model;
use niklasravnsborg\LaravelPdf\Facades\Pdf;
use Illuminate\Support\Facades\Notification;
use App\Notifications\InvoiceSendNotification;

class CustomerInvoiceController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request, $id)
    {
        $cid = Client::list()->where('id', $id)->first();
        $customer_info = Clientsinfo::where('client_id', $id)->first();
        $company_info = siteinfo();

        $bill = BillGenerate::where('client_id', $id)->orderBy('id', 'desc')->latest()->first();

        $payments = Billpayment::where('client_id', $id)
            ->whereBetween('created_at', [Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth()])
            ->get();

        $total_paid = $payments->sum('paid_amount');
        $total_discount = $payments->sum('discount_amount');
        $previous_due = $bill->due_amount > 0 ? abs($bill->bill_amount - $bill->due_amount) : 0;
        $total_amount = $bill->bill_amount + $previous_due;
        $balance_due = $total_amount - ($total_paid + $total_discount);

        $data = [
            'company_info' => $company_info,
            'cid' => $cid,
            'customer_info' => $customer_info,
            'bill' => $bill,
            'payments' => $payments,
            'previous_due' => $previous_due,
            'balance_due' => $balance_due,
            'total_paid' => $total_paid,
            'id' => $id,
            'total_discount' => $total_discount
        ];

        return view('customerInvoice.invoiceview', $data);
    }

    public function sendInvoice($id)
    {

        $client = Client::list()->where('id', $id)->first();


        if ($client->clientsinfo->email) {

            $data = $this->download($client);

            SendMailJob::dispatch($data, $client);

            return response()->json([
                'message' => 'Invoice Sent Successfully',
                'status' => 'success'
            ]);
        } else {

            MailLog::create([
                'clients_id' => $client->id,
                'subject' => 'Invoice Send',
                'message' => '',
                'status' => 'error',
                'error' => 'Email Not Found',
                'to' => $client->clientsinfo->email,
                'cid' => $client
            ]);

            return response()->json([
                'message' => 'Email Not Found',
                'status' => 'error'
            ]);
        }
    }

    function batchSendInvoice($client)
    {
        if ($client->clientsinfo->email) {

            $data = $this->download($client);



            if ($data != false) {

                SendMailJob::dispatch($data, $client);

                return response()->json([
                    'message' => 'Invoice Sent Successfully',
                    'status' => 'success'
                ]);
            } else {

                MailLog::create([
                    'clients_id' => $client->id,
                    'subject' => 'Invoice Send',
                    'message' => '',
                    'status' => 'error',
                    'error' => 'Invoice Not Found',
                    'to' => $client->clientsinfo->email,
                ]);

                return response()->json([
                    'message' => 'Invoice Not Found',
                    'status' => 'error'
                ]);
            }
        } else {

            MailLog::create([
                'clients_id' => $client->id,
                'subject' => 'Invoice Send',
                'message' => '',
                'status' => 'error',
                'error' => 'Email Not Found',
                'to' => $client->clientsinfo->email,
            ]);

            return response()->json([
                'message' => 'Email Not Found',
                'status' => 'error'
            ]);
        }
    }




    function download($client)
    {

        $customer_info = $client->clientsinfo;
        $company_info = siteinfo();

        $bill = BillGenerate::where('client_id', $client->id)->orderBy('id', 'desc')->latest()->first();

        if ($bill) {
            $payments = Billpayment::where('client_id', $client->id)
                ->whereBetween('created_at', [Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth()])
                ->get();

            $total_paid = $payments->sum('paid_amount');
            $previous_due = $bill->due_amount > 0 ? abs($bill->bill_amount - $bill->due_amount) : 0;
            $total_amount = $bill->bill_amount + $previous_due;
            $balance_due = $total_amount - $total_paid;


            $data = [
                'company_info' => $company_info,
                'cid' => $client->id,
                'customer_info' => $customer_info,
                'bill' => $bill,
                'payments' => $payments,
                'previous_due' => $previous_due,
                'balance_due' => $balance_due,
                'total_paid' => $total_paid,
                'id' => $client->id,
                'client' => $client
            ];
            return $data;
        } else {
            return false;
        }
    }



    public function generate_pdf(Request $request, $id)
    {

        $cid = Client::withTrashed()->find($id);
        $customer_info = Clientsinfo::where('client_id', $cid->id)->first();

        $company_info = siteinfo();

        $total_due = BillGenerate::where('client_id', $id)->where('billing_type', 'monthly')->latest()->first();



        $data = [
            'company_info' => $company_info,
            'cid' => $cid,
            'customer_info' => $customer_info,
            'total_due' => $total_due
        ];
        $pdf = PDF::loadView(
            'customerInvoice.invoice',
            $data,
            [],
            [
                'format' => 'A4-P',
                'orientation' => 'P',
                'margin-left' => 1,

                '', // mode - default ''
                '', // format - A4, for example, default ''
                0, // font size - default 0
                '', // default font family
                1, // margin_left
                1, // margin right
                1, // margin top
                1, // margin bottom
                1, // margin header
                1, // margin footer
                'L', // L - landscape, P - portrait

            ]
        );

        return $pdf->stream('invoice.pdf');
    }

    public function allInvoicePdf(Request $request)
    {

        $company_info = CompanyInformation::first();
        $start  = now()->firstOfMonth();
        $end    = now()->endOfMonth();
        $sortBy = $request->query('sortBy'); // id | userid | code | area | pop

        if ($request->isMethod('post')) {;
            $date = Carbon::createFromDate('2023', $request->selectedValue, 1);
            $request->session()->put('invoice_pdf_print_date',$date);
        }

        if($request->session()->get('invoice_pdf_print_date')){
            $start  = Carbon::parse($request->session()->get('invoice_pdf_print_date'))->firstOfMonth();
            $end    = Carbon::parse($request->session()->get('invoice_pdf_print_date'))->lastOfMonth();
        }
        $resellers = Reseller::list()->where('reseller_type', 'own');
        $popes = Pop::whereIn('reseller_id', $resellers->pluck('id'))->get();
        $list = DB::table('clients')
            ->leftJoin('clientsinfo', 'clientsinfo.client_id', '=', 'clients.id')
            ->leftJoin('packages', 'packages.id', '=', 'clients.package_id')
            ->leftJoin('pops', 'pops.id', '=', 'clients.pop_id')
            ->leftJoin('customer_accounts', 'customer_accounts.client_id', '=', 'clients.id')
            ->leftJoin('bill_generates', 'bill_generates.client_id', '=', 'clients.id')
            ->select(
                'clients.*',
                'otc_due',
                'customer_accounts.dueAmount',
                'customer_accounts.totalPaid',
                'customer_accounts.totalDiscount',
                'customer_accounts.totalBillAmount',
                'clientsinfo.flat_no',
                'clientsinfo.building_name',
                'clientsinfo.owner_name',
                'clientsinfo.road_name',
                'clientsinfo.road_no',
                'clientsinfo.block_sector',
                'packages.package_name',
                'pops.popname',
                'clientsinfo.clients_name',
                'clientsinfo.contact_no',
                'clientsinfo.father_name',
                'clientsinfo.mother_name',
                'clientsinfo.area',
                'clientsinfo.email',
                'clientsinfo.national_id',
                'packages.package_rate',
                'billing_type',
                'due_date',
                'bill_generates.created_at as bill_create_date',
                'bill_generates.bill_amount as billamount',
                'bill_generates.paid_amount as paidAmount',
                'bill_generates.due_date as billdate',
                'bill_generates.id as invoice_id',
                'bill_generates.due_amount as due_amount',
                'bill_generates.parmanent_discount as parmanentDiscount',
                'clientsinfo.box',
            )
            ->whereIn('clients.pop_id', $popes->pluck('id'))
            ->where('pops.bill_generate', 'yes')
            ->where('billing_type', 'monthly')
            ->whereBetween('bill_generates.created_at', [$start, $end])
            ->where('clients.clients_status', '!=', 'deactive')
            ->orderBy('clients.id', 'asc');

            $type = $request->query('type');
            $criteria = $request->query('search');

            if ($criteria == 'area') {
                if ($type == 'all' || $type == null) {
                    $list->whereMonth('bill_generates.created_at', '=', date('m'))
                        ->whereYear('bill_generates.created_at', '=', date('Y'))
                        ->orderby('clients.expire_date', 'asc')
                        ->orderby('pops.id', 'asc');
                } else {
                    $list->where('clientsinfo.area', 'like', "$type")
                        ->whereMonth('bill_generates.created_at', '=', date('m'))
                        ->whereYear('bill_generates.created_at', '=', date('Y'))
                        ->orderby('clients.expire_date', 'asc')
                        ->orderby('pops.id', 'asc');
                }
            } elseif ($criteria == 'pop') {
                if ($type == 'all' || $type == null) {
                    $list->whereMonth('bill_generates.created_at', '=', date('m'))
                        ->whereYear('bill_generates.created_at', '=', date('Y'))
                        ->orderby('clients.expire_date', 'asc')
                        ->orderby('pops.id', 'asc');
                } else {
                    $list->where('pops.id', $type)
                        ->whereMonth('bill_generates.created_at', '=', date('m'))
                        ->whereYear('bill_generates.created_at', '=', date('Y'))
                        ->orderby('clients.expire_date', 'asc')
                        ->orderby('pops.id', 'asc');
                }
            } elseif ($criteria == 'resellers') {
                if ($type == 'all' || $type == null) {
                    $list->whereMonth('bill_generates.created_at', '=', date('m'))
                        ->whereYear('bill_generates.created_at', '=', date('Y'))
                        ->orderby('clients.expire_date', 'asc')
                        ->orderby('pops.id', 'asc');
                } else {
                    $list->where('pops.reseller_id', $type)
                        ->whereMonth('bill_generates.created_at', '=', date('m'))
                        ->whereYear('bill_generates.created_at', '=', date('Y'))
                        ->orderby('clients.expire_date', 'asc')
                        ->orderby('pops.id', 'asc');
                }
            } elseif ($criteria == 'username') {
                if ($type == 'all' || $type == null) {
                    $list->whereMonth('bill_generates.created_at', '=', date('m'))
                        ->whereYear('bill_generates.created_at', '=', date('Y'))
                        ->orderby('clients.expire_date', 'asc')
                        ->orderby('clients.id', 'asc');
                } else {
                    $list->where('clients.userid', 'like', '%' . $type . '%')
                        ->whereMonth('bill_generates.created_at', '=', date('m'))
                        ->whereYear('bill_generates.created_at', '=', date('Y'))
                        ->orderby('clients.expire_date', 'asc')
                        ->orderby('clients.id', 'asc');
                }
            }

            // Apply user-selected sorting as the primary ordering, if provided
            if ($sortBy) {
                $columnMap = [
                    'id'     => 'clients.id',
                    'userid' => 'clients.userid',
                    'code'   => 'clients.customer_code',
                    'area'   => 'clientsinfo.area',
                    'pop'    => 'pops.popname',
                ];
                if (array_key_exists($sortBy, $columnMap)) {
                    $list->reorder($columnMap[$sortBy], 'asc');
                }
            }



        return view('customerInvoice.list', [
            'company_info' => $company_info,
            'list' => $list->paginate(100)
        ]);


        // $total_due = BillGenerate::where('billing_type', 'monthly')
        //                          ->whereMonth('created_at', Carbon::now()->month)
        //                         ->get()->all();


        //dd($total_due);
        //  $data = [
        //     'company_info' => $company_info,
        //   //  'cid' => $cid,
        //         'list' => $list,
        //    // 'total_due' => $total_due
        // ];
        // $pdf = PDF::loadView(
        //     'customerInvoice.allInvoice',
        //     $data,
        //     [],
        //     [
        //         'format' => 'A4-P',
        //         'orientation' => 'P',
        //         'margin-left' => 1,

        //         '', // mode - default ''
        //         '', // format - A4, for example, default ''
        //         0, // font size - default 0
        //         '', // default font family
        //         1, // margin_left
        //         1, // margin right
        //         1, // margin top
        //         1, // margin bottom
        //         1, // margin header
        //         1, // margin footer
        //         'L', // L - landscape, P - portrait

        //     ]
        // );



        // return $pdf->stream('invoice.pdf');

    }
}
