<?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;
/**
 * Class DemoController
 * @package App\Http\Controllers\API
 */

class ProductInvoiceController extends BaseInvoiceController
{

    public function getProductRule(){
        return [
            '*.packing_id' => 'required|distinct|exists:production_packagings,packing_id|unique:bond_invoice_detail',
            '*.unit_price' => 'required|numeric',
            '*.amount' => 'required|numeric'
        ];
    }

    public function getUpdateProductRule(){
        return [
            'packing_id' => 'required|distinct|exists:production_packagings,packing_id|unique:bond_invoice_detail',
            'unit_price' => 'required|numeric',
            'amount' => 'required|numeric'
        ];
    }

    public function validateProductDetail($rules, $array){   
        $validator = Validator::make($array, $rules);
        //dd($input['data']);

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

    }


    public function createInvoice(Request $request){
        $invoiceRules = $this->invoiceFullRules();
        $this->validateFullInvoiceRequest( $invoiceRules, $request);
        $input = $request->all();
        $array = json_decode($input['data'], true);
        $rules = $this->getProductRule();
        $this->validateProductDetail($rules, $array);

        $success = false;

        $fullInput = $request->all();
            unset($fullInput['data']);
            $fullInput['invoice_type'] = 'PRODUCT';
            $fullInput['created_at'] = \Carbon\Carbon::now();
            $fullInput['created_by'] = \Auth::user()->id;
            $fullInput['invoice_date'] = $this->formatDate($input['invoice_date']);

        DB::beginTransaction();
        try {
            
            //$date = Carbon::createFromFormat('d-m-Y g:i a', $input['invoice_date'])->format('Y-m-d');
            $invoiceNumber = '';
            if(empty($input['invoice_number'])){
                $fullInput['invoice_number'] = \App\Models\Invoice::generateInvoiceNumber($input['invoice_date']);
            }
            $invoiceId = DB::table('invoices')->insertGetId($fullInput); 
            foreach( $array as $item){
                DB::table('bond_invoice_detail')->insert([
                    'invoice_id' => $invoiceId,
                    'packing_id' => $item['packing_id'],
                    'unit_price' => $item['unit_price'],
                    'amount' => $item['amount'],
                    'created_at' => \Carbon\Carbon::now(),
                    'created_by' => \Auth::user()->id,
                    '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'),
                    'net_amount' => $this->amount($item, 'net_amount'),
                ]); 
            }
            $invoice = \App\Models\Invoice::find($invoiceId);

            $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();
            $invoice = \App\Models\Invoice::find($invoiceId);

            return  $this->sendResponse( new \App\Http\Resources\Invoice\InvoiceResource($invoice), 'Product 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 updateInvoice($invoiceId, Request $request){
        $invoice = \App\Models\Invoice::find($invoiceId);   
        $invoiceRules = $this->invoiceFullRules();
        $invoiceRules['invoice_number'] ='required|unique:invoices,invoice_number,'.$invoiceId; 
        //dd($invoiceRules);
        $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 = $this->getUpdateProductRule();
            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';
            }
           
            //dd($rules);

            $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);
                return;
            //throw $error;
            }
        }
        

        $success = false;

        $fullInput = $request->all();
            unset($fullInput['data']);
            //unset($fullInput['invoice_number']);
            $fullInput['updated_at'] = \Carbon\Carbon::now();
            $fullInput['updated_by'] = \Auth::user()->id;
            $fullInput['invoice_date'] = $this->formatDate($input['invoice_date']);

        DB::beginTransaction();
        try {
            
            //$date = Carbon::createFromFormat('d-m-Y g:i a', $input['invoice_date'])->format('Y-m-d');
            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' => $invoiceId,
                    'packing_id' => $item['packing_id'],
                    'unit_price' => $item['unit_price'],
                    'amount' => $item['amount'],
                    'created_at' => \Carbon\Carbon::now(),
                    'created_by' => \Auth::user()->id,
                    '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'),
                    'net_amount' => $this->amount($item, 'net_amount'),
                ]); 
            }
            $invoice = \App\Models\Invoice::find($invoice->id);

            $entry = \App\Models\Entry::where('invoice_ref_id','=' ,$invoice->id)->first();
            DB::table('entries')->where('invoice_ref_id', $invoice->id)->update([
                'entrytype_id' => 6,
                'ref_number' => $invoice->invoice_number,
                'tr_date' => $fullInput['invoice_date'],
                'cr_total' => 0,
                'dr_total' => $input['totalAmount'],
                'updated_at' => \Carbon\Carbon::now(),
                'updated_by' => \Auth::user()->id,
            ]);

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

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

}

