<?php
namespace App\Http\Controllers\API\Invoices;

use App\Models\User;
use Illuminate\Http\Request;
use App\Http\Controllers\AppBaseController;
use Response;
use App\Http\Resources\User\UserResource;
use Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Log;
use Carbon\Carbon;
use App\Repositories\QualityCheckRepository;
use Illuminate\Validation\Rule;
/**
 * Class DemoController
 * @package App\Http\Controllers\API
 */

class PendingInvoiceController extends BaseInvoiceController
{
    
    public function getPackingRule($id){

    }
    public function validateRequest(Request $request){
        
        $input = $request->all();
        $array = json_decode($input['data'], true);

        $invoiceRules = [ 
              'invoice_date' => 'required|date|date_format:d-m-Y',
              'account_id' => 'required|integer|exists:accounts,id',
          ]; 

        $validator = Validator::make($input, $invoiceRules);
          //dd($input['data']);
  
         // $request->validate($rules);
          if ($validator->fails()) 
           { 
             throw new \Illuminate\Validation\ValidationException($validator);
             //throw $error;
           }
    }

    public function validatePackingDetail($array){
        $rules = [
            '*.packing_id' => 'required|distinct|exists:production_packagings,packing_id|unique:bond_invoice_detail'
        ];   
        
        $validator = Validator::make($array, $rules);
        //dd($input['data']);

       // $request->validate($rules);
        if ($validator->fails()) 
         { 
           throw new \Illuminate\Validation\ValidationException($validator);
           //throw $error;
         }

    }

    public function createPendingInvoice(Request $request){
        $this->validateRequest($request);
       
        $input = $request->all();
        $array = json_decode($input['data'], true);
        $this->validatePackingDetail($array);
        $success = false;
        DB::beginTransaction();
        try {
            
            if(!isset($input['invoice_number']) || empty($input['invoice_number'])){
                $input['invoice_number'] = \App\Models\Invoice::generateInvoiceNumber($input['invoice_date']);
            }
            $input['created_at'] = \Carbon\Carbon::now();
            $input['created_by'] = \Auth::user()->id;
            $input['invoice_date'] = $this->formatDate($input['invoice_date']);
           // $input['invoice_date'] = $this->formatDate($input['invoice_date']);
            
            unset($input['data']);
            //$date = Carbon::createFromFormat('d-m-Y g:i a', $input['invoice_date'])->format('Y-m-d');
            //$invoiceNumber = \App\Models\Invoice::generateInvoiceNumber($input['invoice_date']);
            $invoiceId = DB::table('invoices')->insertGetId($input); 
            foreach( $array as $item){
                DB::table('bond_invoice_detail')->insert([
                    'invoice_id' => $invoiceId,
                    'packing_id' => $item['packing_id'],
                    'created_at' => \Carbon\Carbon::now(),
                    'created_by' => \Auth::user()->id
                ]); 
            }
            
            DB::commit();
            $invoice = \App\Models\Invoice::find($invoiceId);

            return  $this->sendResponse( new \App\Http\Resources\Invoice\InvoiceResource($invoice), 'Pending Invoice created successfully.');
            $success = true;
        } catch (\Exception $e) {
            DB::rollback();
            return $this->handleDBException($e);
        } catch (\Throwable $e) {
            DB::rollback();
            return $this->handleDBException($e);
        }   
    }


    public function updatePendingInvoice($invoiceId, Request $request){
        $invoice = \App\Models\Invoice::find($invoiceId);   
        //dd($invoice);    
        $this->validateRequest($request);
        $input = $request->all();
        $array = json_decode($input['data'], true);
        
        foreach( $array as $item){
            $alreadyExists = \App\Models\BondInvoiceDetail::where([['packing_id','=', (int)$item['packing_id']],['invoice_id','=',$invoice->id]])->first();
           
            $rules = [];
            if(!empty($alreadyExists)){
                $rules = [
                    'packing_id' => 'required|distinct|exists:production_packagings,packing_id|unique:bond_invoice_detail,id,'.$alreadyExists->id
                ];
            }else{
                $rules = [
                    'packing_id' => 'required|distinct|exists:production_packagings,packing_id|unique:bond_invoice_detail'
                ];
            }
           


            $validator = Validator::make($item, $rules);
            //dd($validator->fails());
        //dd($input['data']);
        //dd($validator->fails());

       // $request->validate($rules);
            if ($validator->fails()) 
            { 
                throw new \Illuminate\Validation\ValidationException($validator);
            //throw $error;
            }
        }
        $success = false;
        DB::beginTransaction();
        try {
            
            //$date = Carbon::createFromFormat('d-m-Y g:i a', $input['invoice_date'])->format('Y-m-d');
            //$invoiceNumber = \App\Models\Invoice::generateInvoiceNumber($input['invoice_date']);
            $input['updated_at'] = \Carbon\Carbon::now();
            $input['updated_by'] = \Auth::user()->id;
            $input['invoice_date'] = $this->formatDate($input['invoice_date']);
            //$input['invoice_date'] = $this->formatDate($input['invoice_date']);
            
            unset($input['data']);

            $invoiceId = DB::table('invoices')->where('id', $invoice->id)->update($input);

            DB::table('bond_invoice_detail')->where('invoice_id', '=', $invoice->id)->delete();
            foreach( $array as $item){
                DB::table('bond_invoice_detail')->insert([
                    'invoice_id' => $invoice->id,
                    'packing_id' => $item['packing_id'],
                    'created_at' => \Carbon\Carbon::now(),
                    'created_by' => \Auth::user()->id
                ]); 
            }
            
            DB::commit();
            $invoice = \App\Models\Invoice::find($invoice->id);
            return  $this->sendResponse( new \App\Http\Resources\Invoice\InvoiceResource($invoice), 'Pending Invoice updated successfully.');
            $success = true;
        } catch (\Exception $e) {
            DB::rollback();
            return $this->handleDBException($e);
        } catch (\Throwable $e) {
            DB::rollback();
            return $this->handleDBException($e);
        }
    }

    

    public function finializePendingInvoice($invoiceId, Request $request){
        $invoice = \App\Models\Invoice::find($invoiceId);  
        //dd($invoice);
        $invoiceRules = $this->invoiceFullRules();
        $this->validateFullInvoiceRequest($invoiceRules, $request);
        $input = $request->all();
        $array = json_decode($input['data'], true);
        
        foreach( $array as $item){
            $alreadyExists = \App\Models\BondInvoiceDetail::where([['packing_id','=', (int)$item['packing_id']],['invoice_id','=',$invoice->id]])->first();
           
            $rules = [
                'packing_id' => [
                    'required',
                    Rule::exists('bond_invoice_detail')->where(function ($query) use ($invoice){
                        $query->where('invoice_id', $invoice->id);
                    })],
                'unit_price' => 'required|numeric|gt:0',
                'amount' => 'required|numeric|gt:0',
                'cgst' => 'nullable|numeric',
                'sgst' => 'nullable|numeric',
                'igst' => 'nullable|numeric',
                'cgst_value' => 'nullable|numeric',
                'sgst_value' => 'nullable|numeric',
                'igst_value' => 'nullable|numeric',
                'discount' => 'nullable|numeric',
                'discount_val' => 'nullable|numeric',
            ];
           


            $validator = Validator::make($item, $rules);
        //dd($input['data']);
        //dd($validator->fails());

       // $request->validate($rules);
            if ($validator->fails()) 
            { 
                throw new \Illuminate\Validation\ValidationException($validator);
            //throw $error;
            }
        }
        $success = false;
        DB::beginTransaction();
        try {
            
            //$date = Carbon::createFromFormat('d-m-Y g:i a', $input['invoice_date'])->format('Y-m-d');
            //$invoiceNumber = \App\Models\Invoice::generateInvoiceNumber($input['invoice_date']);
            $fullInput = $request->all();
            unset($fullInput['data']);
            $fullInput['invoice_type'] = 'PRODUCT';
            $fullInput['updated_at'] = \Carbon\Carbon::now();
            $fullInput['updated_by'] = \Auth::user()->id;
            $fullInput['invoice_date'] = $this->formatDate($input['invoice_date']);
            $fullInput['invoice_final_date'] = $this->formatDate($input['invoice_final_date']);

            $invoiceId = DB::table('invoices')->where('id', $invoice->id)->update($fullInput); 
            DB::table('bond_invoice_detail')->where('invoice_id', '=', $invoice->id)->delete();
            foreach( $array as $item){
                DB::table('bond_invoice_detail')->insert([
                    'invoice_id' => $invoice->id,
                    'packing_id' => $item['packing_id'],
                    'unit_price' => $item['unit_price'],
                    'amount' => $item['amount'],
                    'cgst' => $this->amount($item, 'cgst'),
                    'sgst' => $this->amount($item, 'sgst'),
                    'igst' => $this->amount($item, 'igst'),
                    'cgst_value' => $this->amount($item, 'cgst_value'),
                    'sgst_value' => $this->amount($item, 'sgst_value'),
                    'igst_value' => $this->amount($item, 'igst_value'),
                    'discount' => $this->amount($item, 'discount'),
                    'discount_val' => $this->amount($item, 'discount_val'),
                    'net_gst' => $this->amount($item, 'net_gst'),
                    'created_at' => \Carbon\Carbon::now(),
                    'created_by' => \Auth::user()->id,
                ]); 
            }
            $invoice = \App\Models\Invoice::find($invoice->id);

            $entryId = DB::table('entries')->insertGetId([
                'entrytype_id' => 6,
                'ref_number' => $invoice->invoice_number,
                'invoice_ref_id' => $invoice->id,
                'tr_date' => $fullInput['invoice_date'],
                'cr_total' => 0,
                'dr_total' => $input['totalAmount'],
                'created_at' => \Carbon\Carbon::now(),
                'created_by' => \Auth::user()->id,
            ]);


            DB::table('entryitems')->insertGetId([
                'entry_id' => $entryId,
                'account_id' => $invoice->account_id,
                'cr_total' => 0,
                'dr_total' => $input['totalAmount'],
                'created_at' => \Carbon\Carbon::now(),
            ]);
            
            DB::commit();
            //dd($invoiceId);
            $invoice = \App\Models\Invoice::find($invoice->id);

            //dd($invoice);
            return  $this->sendResponse( new \App\Http\Resources\Invoice\InvoiceResource($invoice), 'Invoice finalized successfully.');
            $success = true;
        } catch (\Exception $e) {
            DB::rollback();
            throw $e;
           // return $this->handleDBException($e);
        } catch (\Throwable $e) {
            DB::rollback();
           // return $this->handleDBException($e);
        }
    }

}

