<?php

namespace App\Http\Controllers\Api\Sales;

use App\Http\Controllers\Controller;

use App\Models\CreditNote;

use App\Models\CreditNoteItem;

use App\Models\Customer;

use App\Models\Transaction;

use App\Models\Invoice;

use App\Models\InvoiceItem;

use App\Service\StockEntryService;

use Illuminate\Http\Request;

use Illuminate\Support\Facades\Redirect;

use Auth;

use App\Service\AccountsTransactionService;

use App\Service\StaticMaster;

class CreditNoteController extends Controller

{

    public function list(Request $request){

        $user=Auth::user();

        // Validate 
        $validator=validator($request->all(),[

            'fy'=>'required',
            // 'warehouse_id'=>'required'

        ]);

        if ($validator->fails()) {

            return [
                'success' => false, 
                'message' => $validator->errors()->first()
            ];

        } else {

            $creditnotes= CreditNote::with('customer','invoice');
                    // ->where('organisation_id',$user['active_organisation'])
                // ->where('warehouse_id',$request['warehouse_id'])
                // ->where('fy',$request['fy']);

            if ($request['status']!='' && isset($request['status'])) {

                $creditnotes=$creditnotes->where('status',$request['status']);
            }

            if ($request['customer_id']!='' && $request['customer_id']!=null && isset($request['customer_id'])) {
                $creditnotes=$creditnotes->where('customer_id',$request['customer_id']);
            }

            //Search Filter
            if($request['search']!=null && $request['search']!=''){

                $creditnotes = $creditnotes->where(function ($query) use ($request) {
                        
                    $query->where('credit_note_id', 'LIKE', '%' . $request['search'] . '%')

                        ->orWhere('reference_no', 'LIKE', '%' . $request['search'] . '%')

                        ->orWhere('display_name', 'LIKE', '%' . $request['search'] . '%')

                        ->orWhere('customer_type', 'LIKE', '%' . $request['search'] . '%')

                        ->orWhere('phone', 'LIKE', '%' . $request['search'] . '%')

                        ->orWhere('email', 'LIKE', '%' . $request['search'] . '%');

                });

            }

            // get alphabetically data by customer_name
            if ($request['customer_name']!='' && isset($request['customer_name'])) {

                $creditnotes=$creditnotes->orderBy('customer_name');
            }
                // get custom_date data by transaction_date

            if ($request['custom_date']!='' && isset($request['custom_date'])) {

                $customDate = $request->custom_date;

                $creditnotes = $creditnotes->whereDate('transaction_date', $customDate);

            }

            // get last modified data by updated_at
            if ($request['updated_at']!='' && isset($request['updated_at'])) {

                $creditnotes=$creditnotes->orderBy('updated_at');
            }

            // get fromDate toDate data by created_at
            if ($request['from_date']!='' && isset($request['to_date'])) {

                $fromDate = $request->from_date;

                $toDate = $request->to_date;
                // 'fromDate' and 'toDate'

                $creditnotes = $creditnotes->whereBetween('transaction_date', [$fromDate, $toDate]);

            }

            $count=$creditnotes->count();

            if(isset($request['sort_by']) && $request['sort_by']!='' && $request['sort_by']!=null){
                
                $sort_order=$request['sort_order']==1?'asc':'desc';

                $creditnotes = $creditnotes->orderby($request['sort_by'],$sort_order);

            }else{
                $creditnotes = $creditnotes->orderby('id','desc');
            }

            $creditnotes= $creditnotes->skip($request['noofrec']*($request['currentpage']-1))->take($request['noofrec']??100)
                        ->get();

            $response=[
                'count'=>$count,
                'success'=>true,
                'message'=>'Credit Note List Fetched Successfully',
                'creditnote'=>$creditnotes
            ];

            return response()->json($response);

        }

    }


    public function details(Request $request) {

        $user=Auth::user();

        // Validate 
        $validator=validator($request->all(),[
            'id'=>'required',
            // 'warehouse_id'=>'required'
        ]);

        if ($validator->fails()) {

            return [
                'success' => false, 
                'message' => $validator->errors()->first()
            ];

        } else {

            $creditnotes = CreditNote::where('id',$request['id'])

                ->where('organisation_id',$user['active_organisation'])

                ->with('items','customer','items.item')

                ->first();

            $transaction=Transaction::where('transaction_type',StaticMaster::$CREDIT_NOTE)
                ->where('transaction_id',$request['id'])
                ->where('is_disabled',0)
                ->with('account:id,account_name,account_code')
                ->get();


            $response=[
                'message'=>'details fetch successfully',
                'CreditNote'=>$creditnotes,
                'transaction'=>$transaction
            ];

            return response()->json($response);

        }



    }


    public function destroy(Request $request){

        // Validate Item

        $validator=validator($request->all(),[

            'id'=>'required'

        ]);

        if ($validator->fails()) { 

            return [

                'success' => false, 

                'message' => $validator->errors()->first()

            ];

        } else {
            try{

                $creditnote = CreditNote::findOrFail($request['id']);

            } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {

                // Return error message in JSON if ID not found

                return response()->json(['message' => 'Invalid Id to update'], 404);

            }

            if($creditnote['is_approved']==0){

                $creditnote->delete();

                $creditnote_items=CreditNoteItem::where('transaction_id',$creditnote['id'])->get();

                foreach ($creditnote_items as $value){
                    //also update the credit note quantity in invoice item table
                    $invoice_item=InvoiceItem::where('transaction_id',$credit_note['invoice_id'])
                        ->where('item_id',$value['item_id'])
                        ->where('is_disabled',0)
                        ->first();

                    if($invoice_item!=null){

                        $invoice_item->update(['credit_note_qty'=>$invoice_item['credit_note_qty'] - $value['quantity']]);
                    }

                    $value->delete();

                    //update invoice status
                    $invoice=Invoice::where('id',$creditnote['invoice_id'])->first();
                    $invoice->update(['is_credit_note_close'=>0]);
                }

                $response=[
                    'success'=>true,
                    'message'=>'Credit Note deleted Successfully'
                ];

            }else{

                $response=[

                    'success'=>false,

                    'message'=>'Credit Note is Approved. You can\'t delete this Credit Note.'

                ];

            }
            return response()->json($response);

        }

    }


    public function approveCreditNote(Request $request){

        $validator=Validator::make($request->all(),[

            'credit_note_id'=>'required'
        ]);

        $entity='CreditNote';

        if ($validator->fails()) {

            # code...
            $response=[ 

                'success'=>false,

                'message'=>$validator->errors()->first()
            ];

            return response()->json($response);    

        }

        else{

            $transaction = CreditNote::find($request->credit_note_id);

            $transaction['is_approved']=1;
            $transaction['status']=1;

            $transaction->update();  

            // Saving Accounts Entries
            $accountsEntryService = new AccountsTransactionService;
            $accountsEntryService->creditNote_accounts_transaction($transaction);

            // $stockEntryService = new StockEntryService;
            // $stockEntryService->saveStockEntries( $transaction,$entity,1);

        }

        $response=[ 

            'success'=>true,
            'message'=>'Credit Note Approved Successfully'
        ];



        return response()->json($response);

    }

    public function statusCreditNote(Request $request){
        // Validate Item
        $status_change='';

        $validator=validator($request->all(),[

            'id'=>'required',
            'status'=>'required'

        ]);

        if ($validator->fails()) { 

            return [
                'success' => false, 
                'message' => $validator->errors()->first()
            ];

        } else {
            $transaction = CreditNote::findOrFail($request->id);

            $invoice = Invoice::findOrFail($transaction['invoice_id']);

            $transaction['status']=$request['status'];

            // if the credit note is approved
            if($request['status']==1){

                $status_change='Approved';
                $transaction['is_approved']=1;

                $entity='CreditNote';

                // get balance Amount
                $balance_amount=$invoice['total'] - $invoice['amount_paid'];

                //check the invoice payment status and update the amount paid in invoice table
                if($balance_amount == $transaction['total']){

                    $invoice['amount_paid']=$invoice['amount_paid'] + $transaction['total'];
                    $invoice->update();

                    //update credit note amount_paid
                    $transaction['amount_paid']= $transaction['amount_paid'] + $transaction['total'];
                    $transaction->update();
                    
                }else if($balance_amount < $transaction['total']){

                    $invoice['amount_paid']=$invoice['amount_paid'] + $balance_amount;
                    $invoice->update();

                    //update credit note amount_paid
                    $transaction['amount_paid']=$balance_amount;
                    $transaction->update();

                }else{

                    $invoice['amount_paid']=$invoice['amount_paid'] + $transaction['total'];
                    $invoice->update();

                    //update credit note amount_paid
                    $transaction['amount_paid']=$transaction['amount_paid'] + $transaction['total'];
                    $transaction->update();
                }


                // Saving Stock Entries
                $stockEntryService = new StockEntryService;
                $stockEntryService->saveStockEntries( $transaction,$entity,1);

                // Saving Accounts Entries
                $accountsEntryService = new AccountsTransactionService;
                $accountsEntryService->creditNote_accounts_transaction($transaction);

            }

            if($request['status']==2){

                $status_change='Declined';
                $transaction['is_approved']=0;

            }
            if($request['status']==0){

                $status_change='Draft';
            }

            $transaction->update();  

            $response=[ 

                'success'=>true,
    
                'message'=>'Credit Note '.$status_change.' Updated Successfully'
    
            ];

            return response()->json($response);

        }
    }

}