<?php

namespace App\Services;

use App\Models\SalesInvoice;
use App\Models\SalesInvoiceItem;
use App\Models\SalesOrder;
use Illuminate\Support\Facades\DB;

class SalesInvoiceService
{
    private function generateInvoiceNumber($invoice)
    {
        return 'INV'.str_pad($invoice->id,6,'0',STR_PAD_LEFT);
    }

    public function generate($request)
    {
        return DB::transaction(function() use($request){

            $order = SalesOrder::with('items')
                        ->findOrFail($request->sales_order_id);

            if($order->status!='Confirmed'){
                throw new \Exception(
                    'Only confirmed orders can be invoiced.'
                );
            }

            if(SalesInvoice::where(
                'sales_order_id',
                $order->id
            )->exists()){
                throw new \Exception(
                    'Invoice already generated.'
                );
            }

            $invoice = SalesInvoice::create([

                'invoice_no'=>'',

                'sales_order_id'=>$order->id,

                'client_id'=>$order->client_id,

                'invoice_date'=>$request->invoice_date,

                'total_amount'=>$order->total_amount,

                'discount_amount'=>$order->discount_amount,

                'tax_amount'=>$order->tax_amount,

                'grand_total'=>$order->grand_total,

                'paid_amount'=>0,

                'balance_amount'=>$order->grand_total,

                'payment_status'=>'Pending',

                'remarks'=>$request->remarks,

                'created_by'=>auth()->id()

            ]);

            $invoice->update([

                'invoice_no'=>$this->generateInvoiceNumber($invoice)

            ]);

            foreach($order->items as $item){

                SalesInvoiceItem::create([

                    'sales_invoice_id'=>$invoice->id,

                    'product_id'=>$item->product_id,

                    'quantity'=>$item->quantity,

                    'unit_price'=>$item->unit_price,

                    'discount'=>$item->discount,

                    'total'=>$item->total

                ]);

            }

            return $invoice->load([
                'client',
                'order',
                'items.product'
            ]);

        });
    }
    
    public function list($request)
    {
        $query = SalesInvoice::with([
            'client',
            'order'
        ]);
    
        if ($request->filled('search')) {
    
            $query->where(function ($q) use ($request) {
    
                $q->where('invoice_no', 'like', "%{$request->search}%")
                  ->orWhereHas('client', function ($client) use ($request) {
    
                      $client->where(
                          'client_name',
                          'like',
                          "%{$request->search}%"
                      );
    
                  });
    
            });
    
        }
    
        if ($request->filled('payment_status')) {
    
            $query->where(
                'payment_status',
                $request->payment_status
            );
    
        }
    
        return $query->latest()->paginate(10);
    }
    
    public function show(SalesInvoice $invoice)
    {
        return $invoice->load([
            'client',
            'order',
            'items.product'
        ]);
    }
}