<?php

namespace App\Http\Controllers\Admin\SaleInvoice;

use App\DataTables\Invoices\SaleDataTable;
use App\Models\Customer;
use App\Models\Farmer;
use App\Models\FarmerInvoice;
use App\Models\Inventory;
use App\Models\Payment;
use App\Models\ProductPrice;
use App\Models\PurposeHead;
use App\Models\Sale;
use App\Models\Branch;
use App\Models\FarmerBatch;
use App\Models\FarmerInvoiceItem;
use App\Models\SaleItem;
use App\Models\SalePayment;
use App\Models\SaleTempItem;
use Brian2694\Toastr\Facades\Toastr;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use \DB;
use PhpSpec\Exception\Exception;

class SaleInvoiceController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @param SaleDataTable $dataTable
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request,SaleDataTable $dataTable)
    {
        $data['invoices']           = $dataTable->query();
        $data['invoicePayments']    = SalePayment::latest()->get();
        return $dataTable->render('admin.saleinvoice.index', $data);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create( Request $request )
    {
        if (auth()->user()->can('create_sale')) {
            $for       = $request->input('for') ?? 'customer';
            $customers = $for == 'customer' ? Customer::pluck('id', 'name') : Farmer::pluck('id', 'name');
            $sale      = Sale::orderBy('id', 'DESC')->first();
            if (auth()->user()->hasRole('superadmin')) {
                $branches = Branch::get(['id','name']);
            } else {
                $branches = auth()->user()->branches()->get(['branches.id','branches.name']);
                if ($branches->isEmpty() && auth()->user()->branch_id) {
                     $branches = Branch::where('id', auth()->user()->branch_id)->get(['id', 'name']);
                }
            }
            return view('admin.saleinvoice.create',compact('for','customers','sale', 'branches'));
        }
        toastr()->error('Do Not Have Permission!');
        return redirect()->back();
    }

    public function store(Request $request)
    {
       
        if (auth()->user()->can('create_sale')) {
            $request->validate([
                'user_id'            => 'required',
                'branch_id'          => 'required',
                'customer_id'        => 'required',
                'phone'              => 'required|min:11',
                'sale_date'          => 'required',
                'due_date'           => 'required',
                'payment_processor'  => 'required',
                'sub_total'          => 'required',
                'invoiceDiscount'    => 'required',
                'payment'            => 'required',
                'grand_total'        => 'required',
                'due'                => 'required',
                'for'                => 'required',
            ]);
       
            $customer = request('for') == 'customer' ? Customer::find( request('customer_id') ) : Farmer::find( request('customer_id') );
            $products = SaleTempItem::where('user_id', request('user_id'))->get();

            if ( ! $customer ||  $products->count() <= 0  ) {
                return redirect()->back();
            }
            
            if ( $request->input('grand_total') - $request->input('due') >= 0 && ! request('purpose_head') ) {
                Toastr::success('Froget to select purpose head ?', 'error');
                return redirect()->back();
            }
            
            $sale = Sale::create([
                'user_id'            => auth()->user()->id,
                'customer_id'        => $customer->id,
                'branch_id'          => $request->input('branch_id'),
                'sale_no'            => 'SALE - ' . sprintf('%1$03d', $this->getSaleNo()),
                'sale_date'          => Carbon::parse($request->input('sale_date'))->format('Y-m-d'),
                'due_date'           => Carbon::parse($request->input('due_date'))->format('Y-m-d'),
                'payment_type'       => $request->input('due') > 0 ? 'partial' : 'paid',
                'payment_processor'  => $request->input('payment_processor'),
                'sub_total'          => $request->input('sub_total'),
                'discount'           => $request->input('invoiceDiscount'),
                'grand_total'        => $request->input('grand_total'),
                'due'                => $request->input('due'),
                'status'             => 1,
                'remarks'            => $request->input('remarks'),
            ]);

            if ( $request->input('grand_total') - $request->input('due') != 0 ) {
                $payment = SalePayment::create([
                    'sale_id'       => $sale->id,
                    'payment'       => $request->input('grand_total') - $request->input('due'),
                    'purpose'       => request('purpose_head'),
                    'status'        => 1,
                    'gateway'       => request('payment_processor'),
                    'created_at'    => Carbon::now()
                ]);
            }
            
            if ( $customer instanceof Farmer ) {
                
                $invoice = FarmerInvoice::create([
                    'farmer_id'         => $customer->id,
                    'user_id'           => auth()->user()->id,
                    'batch_number'      => FarmerBatch::where('farmer_id',$customer->id)->where('status','active')->first()?->batch_number ?? Carbon::now()->format('M-d'),
                    'date'              => Carbon::now(),
                    'invoice_number'    => 'Farmer-'. $customer->farmerinvoice->count() + 1 ,
                    'total_amount'      => $request->input('grand_total'),
                    'status'            => 1,
                    'remarks'           => "Farmer Selling Invoice",
                    'receipt_no'        => $customer->farmerinvoice->count() + 1,                    
                ]);
                
                if ( $invoice ) {
                    $products->map(function ( $product ) use( $invoice ) {
                        $invoiceItems = FarmerInvoiceItem::create([
                            'farmerinvoice_id'      => $invoice->id,
                            'product_id'            => $product->product_id,
                            'unit_id'               => $product->unit_id,
                            'batch_number'          => $invoice->batch_number,
                            'cost_price'            => $product->cost_price,
                            'selling_price'         => $product->selling_price,
                            'quantity'              => $product->quantity,
                            'total_cost'            => $product->total_cost,
                            'total_selling'         => $product->total_selling,                            
                        ]);

                    });
                }
                
            }

            if ( $sale ) {
                $products->map(function ( $product ) use( $sale ) {
                    $saleItem               = $product->toArray();
                    $saleItem['sale_id']    = $sale->id;
                    $saleItem['created_at'] = Carbon::now();
                    SaleItem::create($saleItem);
                    $product->delete();
                });
            }

            Toastr::success('Sale Created', 'success');
            return redirect()->route('admin.sales.index');
        }

        Toastr::error('Do Not Have Permission to Sale', 'error');
        return redirect()->to('/');
    }

    /**
     * Get Sale No with Prefix 00
     * @return int
     */
    protected function getSaleNo()
    {
        $saleId = Sale::orderBy('id', 'DESC')->first();
        if ($saleId) {
            $id = $saleId->id + 1;
            return (int) $id;
        } else {
            return 1;
        }
    }

    public function show($id)
    {
        return view('admin.saleinvoice.show',[
            'invoice' => Sale::findOrFail($id)
        ]);
    }

    public function collectPartialPayment( Request $request,Sale $id,string $status )
    {
        if ( $request->method() == 'POST' ) {
            $request->validate([
                'payment_amount'  => 'required|numeric|max:' . $id->due,
                'payment_gateway' => 'required',
                'purposehead_id'  => 'required|exists:purpose_heads,id',
            ]);
           
            $payment = SalePayment::create([
                'sale_id'       => $id->id,
                'payment'      => request('payment_amount'),
                'purpose'      => request('purposehead_id'),
                'status'       => 1,
                'gateway'      => request('payment_gateway'),
                'created_at'   => Carbon::parse(request('payment_date'))
            ]);

            if ( $payment && $payment->payment >= $id->due ) {
                $id->payment_type = 'paid';
                $id->due = 0;
            } else {
                $id->due -= request('payment_amount');
            }
            $id->save();
            return redirect()->route('admin.sales.show', [$id->id]);
        }
        $purposeHeads = PurposeHead::get(['id','name']);
        return view('admin.saleinvoice.partial.payment',compact('id','purposeHeads'));
    }
}
