<?php

namespace App\Http\Controllers\Admin;

use App\DataTables\Customer\CustomersDataTable;
use App\DataTables\Customer\CustomerInvoicesDataTable;
use App\Http\Requests\Customer\CustomerStoreRequest;
use App\Http\Requests\Customer\CustomerUpdateReuest;
use App\Models\Branch;
use App\Models\Customer;
use Brian2694\Toastr\Facades\Toastr;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Payment;
use App\Models\SalePayment;
use App\Models\Sale;
use App\Models\Transaction;

class CustomerController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @param CustomersDataTable $dataTable
     * @return void
     */
    public function index(CustomersDataTable $dataTable)
    {
        if (auth()->user()->can('view_customer'))
        {
            return $dataTable->render('admin.customer.index');
        }
        abort(403);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        if (auth()->user()->can('create_customer'))
        {
            return view('admin.customer.create');
        }
        abort(403);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(CustomerStoreRequest $request)
    {
        if (auth()->user()->can('create_customer'))
        {
            $customer = Customer::create([
               'name'                   => $request->name,
                'phone'                 => $request->phone,
                'address'               => $request->address,
                'opening_balance'       => $request->opening_balance,
            ]);
            if ($customer)
            {
                Toastr::success('Customer Added Successfully','success');
                return redirect()->route('admin.customer.index');
            }
            abort(404);
        }
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show(CustomerInvoicesDataTable $dataTable,$id)
    {
        $id = Customer::findOrFail($id);
        if (auth()->user()->can('view_customer'))
        {
            return $dataTable->with('id',$id)->render('admin.customer.show',compact('id'));
        }
        abort(403);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param Customer $customer
     * @return void
     */
    public function edit(Customer $customer)
    {
        if (auth()->user()->can('edit_customer')) {

            return view('admin.customer.edit', $customer, compact('customer'));
        }
        abort(403);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(CustomerUpdateReuest $request, Customer $customer)
    {
        if (auth()->user()->can('edit_customer'))
        {
            $updateCustomer = $customer->update([
               'name'                   => $request->name,
                'phone'                 => $request->phone,
                'address'               => $request->address,
                'opening_balance'       => $request->opening_balance,
            ]);
            if ($updateCustomer)
            {
                Toastr::success('Customer Updated Success','success');
                return redirect()->route('admin.customer.index');
            }else{
                Toastr::success('Customer Updated Failed','error');
                return redirect()->route('admin.customer.index');
            }
        }
        abort(403);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(Customer $customer)
    {
        try{
            if (auth()->user()->can('delete_customer'))
            {
                $customer->delete();
                Toastr::success('Deleted Successfully','success');
                return redirect()->route('admin.customer.index');
            }
        }catch (\Illuminate\Database\QueryException $e)
        {
            Toastr::success('Can Not be Deleted! This Customer has an Invoice.');
            return redirect()->route('admin.customer.index');
        }
    }
    
    public function collectDuePaymentView( Request $request,Customer $customer ){
        
        if ( $request->method() == 'POST' ) {
            $amount_to_collect = Sale::whereIn('id',$request->input('invoices') )->sum('due');
            $invoices          = $request->input('invoices');
        } else {
            $amount_to_collect = $request->from == 'opening_balance' ? $customer->opening_balance : $customer->totalDue();
            $invoices          = [];
        }
        
        return view('admin.customer.due', $customer, compact('customer','amount_to_collect','invoices'));
    }
    
    public function collectDuePayment(Request $request, Customer $customer )
    {
        $rules = [
            'payment_gateway' => 'required',
            'purposehead_id'  => 'required|exists:purpose_heads,id',
        ];
        
        if ( $request->from !== 'opening_balance' ) {
            $rules['payment_amount'] = 'required|numeric|max:' . $customer->totalDue();
        } else{
            $rules['payment_amount'] = 'required|numeric|max:' . $customer->opening_balance;
        }
        
        $request->validate($rules);
        
        if( $request->from == 'opening_balance' ) {
            Transaction::create([
                'payer'             => $customer->id,
                'purpose'           => request('purposehead_id'),
                'amount'            => request('payment_amount'),
                'status'            => 'credit',
                'processor'         => auth()->user()->id,
                'payer_payee_model' => $customer::class,
                'gateway'           => request('payment_gateway')
            ]);
            
            $customer->opening_balance -= request('payment_amount');
            $customer->save();
            
        }else {
            if ( $request->invoices ) {
                $dueInvoices = Sale::whereIn('id',$request->invoices)->get();
            } else {
                $dueInvoices = $customer->invoices()->where("due", ">","0")->get();
            }
            
            $dueInvoices->map(function( $invoice ) use( $request ){
                SalePayment::create([
                    'sale_id'       => $invoice->id,
                    'payment'       => $invoice->due,
                    'purpose'       => request('purposehead_id'),
                    'status'        => 1,
                    'gateway'       => request('payment_gateway'),
                    'created_at'    => Carbon::parse(request('payment_date'))
                ]);
                
                $invoice->due = 0;
                $invoice->save();
            });
        }

        return redirect()->route("admin.customer.show",[$customer->id]);
    }
}
