<?php

namespace App\Http\Controllers\Accounting;

use App\Exports\FinancialAccountVoucher\ContraVoucherExport;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\CompanyAddress;
use App\Models\Account;
use App\Models\ProductBrand;
use App\Models\Product;
use App\Models\PaymentMode;
use App\Models\SaleInvoice;
use App\Models\SaleInvoiceType;
use App\Models\SaleInvoiceDetail;
use App\Models\ProductPrice;
use App\Models\ProductTestPackage;
use App\Models\SaleInvoiceSubDetails;
use App\Models\SpecialCase;
use App\Models\FinancialYear;
use App\Models\ContraVoucher;
use App\Models\ContraVoucherTransaction;
use App\Models\MenuModelPermission;
use App\Models\VoucherMaster;
use App\Models\SaleInvoiceBatch;
use App\Models\AccountTransaction;
use App\Models\Company;
use App\Models\User;
use App\Models\VoucherType;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Support\Facades\Auth;
use Carbon\Carbon;
use Illuminate\Support\Facades\Session;
use Maatwebsite\Excel\Facades\Excel;

class ContraVouchersController extends Controller
{
    function __construct()
    {
        $this->middleware('permission:contra-voucher-list', ['only' => ['index']]);
    }
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        if (!$this->modulePermissionCheck('CONTRA_VOUCHER')) {
            abort(404);
        }

        $data = ContraVoucher::select([
            'contra_vouchers.*',
            'companies.name',
            'tbl_financial_year.financial_year_name'
        ])
            ->leftjoin('tbl_financial_year', 'tbl_financial_year.financialyearid', 'contra_vouchers.financial_year_id')
            ->leftjoin('companies', 'companies.id', 'contra_vouchers.company_id');

        if ($request->ajax()) {
            $sort_by      = $request->get('sortby') ?? 10;
            $sort_type    = $request->get('sorttype');
            $search_query = $request->get('query');
            $search_type  = $request->get('search_type');

            $data = $data->when(
                !empty($search_query) && !empty($search_type),
                function ($query) use ($search_query, $search_type) {
                    if ($search_type == 'voucher_no') {
                        $query->where('contra_vouchers.voucher_no', 'like', '%' . $search_query . '%');
                    } else if ($search_type == 'company') {
                        $query->where('companies.name', 'like', '%' . $search_query . '%');
                    } else if ($search_type == 'description') {
                        $query->where('description', 'like', '%' . $search_query . '%');
                    } else if ($search_type == 'financial_year') {
                        $query->where('tbl_financial_year.financial_year_name', 'like', '%' . $search_query . '%');
                    } else if ($search_type == 'reference') {
                        $query->where('contra_vouchers.reference', 'like', '%' . $search_query . '%');
                    }
                }
            )
                ->latest()
                ->paginate($sort_by);

            return view('contra-vouchers.table', compact('data'));
        } else {
            $data = $data->latest()->paginate(10);

            return view('contra-vouchers.index', compact('data'));
        }
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $company_address = \Session::get('company_data')['companies_addresses'];
        $countryCode     = $company_address->country_code ?? 'us';

        $brands      = ProductBrand::select(['id', 'name', 'is_default'])
            ->where(['status' => 1])
            ->get();

        $financialYears = \Session::get('financialyear');
        $companyDateFormate = phpToJsDateFormat($this->companyDateFormate());

        return view('contra-vouchers.create', compact('financialYears', 'countryCode', 'brands', 'companyDateFormate'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function contraVoucherUpdate(Request $request)
    {
        $transaction_date =  Carbon::createFromFormat($this->companyDateFormate(), $request->transaction_date)->format('Y-m-d');
        $item = [
            'reference'            => $request->voucher_no,
            'transaction_date'     => $transaction_date,
            'description'          => $request->description,
            'financial_year_id'    => $request->financial_year_id
        ];

        $contraVoucher = ContraVoucher::where('id', '=', $request->id)->update($item);

        $contraVoucherTransaction = ContraVoucherTransaction::where([
            // 'transaction_date'    => $transaction_date,
            'voucher_id'          => $request->id,
            'transaction_type'    => 'DEBIT',
            'voucher_type'        => 'CONTRA',
        ])
            ->first();

        $contraVoucherTransaction->update([
            'account_id'          => $request->debit_account_id ?? '',
            'details_narration'   => $request->debit_details_narration ?? '',
            'amount'              => $request->debit ?? '0',
            'financial_year_id'   => $request->financial_year_id,
            'transaction_date'    => $transaction_date,
        ]);

        AccountTransaction::updateTransaction([
            'module_code'      => 'CONTRA',
            'voucher_type'     => 'CONTRA', // SALE, PURCHASE, PAYMENT
            'voucher_id'       => $request->id,
            'transaction_type' => 'DEBIT',
        ], [
            'account_id'        => $request->debit_account_id ?? '',
            'voucher_sub_id'    => $contraVoucherTransaction->id,
            'amount'            => $request->debit,
            'financial_year_id' => $request->financial_year_id,
            'details_narration' => $request->debit_details_narration ?? '',
        ]);

        $contraVoucherTransaction = ContraVoucherTransaction::where([
            // 'transaction_date'    => $transaction_date,
            'voucher_id'          => $request->id,
            'transaction_type'    => 'CREDIT',
            'voucher_type'        => 'CONTRA',
        ])
            ->first();

        $contraVoucherTransaction->update([
            'account_id'          => $request->credit_account_id ?? '',
            'details_narration'   => $request->credit_details_narration ?? '',
            'amount'              => $request->credit ?? '0',
            'financial_year_id'   => $request->financial_year_id,
            'transaction_date'    => $transaction_date,
        ]);

        $AccountTransaction = AccountTransaction::updateTransaction([
            'module_code'      => 'CONTRA',
            'voucher_type'     => 'CONTRA', // SALE, PURCHASE, PAYMENT
            'voucher_id'       => $request->id,
            'transaction_type' => 'CREDIT',
        ], [
            'account_id'        => $request->credit_account_id ?? '',
            'voucher_sub_id'    => $contraVoucherTransaction->id,
            'amount'            => $request->credit,
            'financial_year_id' => $request->financial_year_id,
            'details_narration' => $request->credit_details_narration ?? '',
        ]);

        return response()->json(['success' => true, 'message' => 'Contra Voucher Updated Successfully!']);
    }
    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function contraVoucherSubmit(Request $request)
    {
        $transaction_date = Carbon::createFromFormat($this->companyDateFormate(), $request->transaction_date)->format('Y-m-d');

        $voucher_master = VoucherMaster::with('voucherSeries')->where('voucher_code', 'CONTRA')->where(['status' => 1])->first();

        # last voucher count for main invoice number
        $voucher_count      = ContraVoucher::select('last_voucher_count')->orderBy('created_at', 'DESC')->first();
        $last_voucher_count = isset($voucher_count) && isset($voucher_count->last_voucher_count) ? $voucher_count->last_voucher_count + 1 : ($voucher_master->voucherSeries->start_from ?? 0) + 1;

        $main_invoice_no = $this->generateCode(
            $last_voucher_count,
            ($voucher_master->voucherSeries->prefix ?? 'CV'),
            ($voucher_master->voucherSeries->postfix ?? ''),
            ($voucher_master->voucherSeries->separator ?? '-'),
            ($voucher_master->voucherSeries->length ?? 5)
        );

        $item = [
            'voucher_no'         => $main_invoice_no,
            'reference'          => $request->voucher_no,
            'transaction_date'   => $transaction_date,
            'description'        => $request->description,
            'company_id'         => \Auth::user()->company_id,
            'financial_year_id'  => $request->financial_year_id,
            'voucher_status'     => true,
            'created_by'         => \Auth::user()->id ?? '',
            'last_voucher_count' => $last_voucher_count,
            'voucher_master_id'  => ($voucher_master->id ?? ''),
            'receipt_time'        => Carbon::now(),
        ];

        $contraVoucher = ContraVoucher::create($item);
        $module        = MenuModelPermission::where('code', 'CONTRA_VOUCHER')->first();
        $module_id     = $module->id ?? '';
        $transactions_no = $this->generateRandomCode();
        $transactionsData = $this->generateTransactionNumber();

        $item1 = [
            'transactions_no'     => $transactionsData['transactions_no'],
            'transaction_date'    => $transaction_date,
            'module_id'           => $module_id,
            'voucher_id'          => $contraVoucher->id,
            'voucher_type'        => 'CONTRA',
            'account_id'          => $request->debit_account_id ?? '',
            'transaction_type'    => 'DEBIT',
            'details_narration'   => $request->debit_details_narration ?? '',
            'amount'              => $request->debit ?? '0',
            'currency_id'         => '',
            'created_by'          => \Auth::user()->id ?? '',
            'company_id'          => \Auth::user()->company_id ?? '',
            'financial_year_id'   => $request->financial_year_id,
            'transactions_status' => true
        ];

        $contraVoucherTransaction = ContraVoucherTransaction::create($item1);

        $transaction = AccountTransaction::createTransaction([
            'transactions_no'   => $transactionsData['transactions_no'],
            'transaction_date'  => $transaction_date,
            'module_code'       => 'CONTRA',
            'voucher_id'        => $contraVoucher->id,
            'voucher_sub_id'    => $contraVoucherTransaction->id,
            'voucher_type'      => 'CONTRA', // SALE, PURCHASE, PAYMENT
            'account_id'        => $request->debit_account_id ?? '',
            'transaction_type'  => 'DEBIT',
            'details_narration' => $request->debit_details_narration ?? '',
            'amount'            => $request->debit,
            'financial_year_id' => $request->financial_year_id,
            'last_id'           => $transactionsData['last_count'],
        ]);

        $item = [
            'transactions_no'     => $transactionsData['transactions_no'],
            'transaction_date'    => $transaction_date,
            'module_id'           => $module_id,
            'voucher_id'          => $contraVoucher->id,
            'voucher_type'        => 'CONTRA',
            'account_id'          => $request->credit_account_id ?? '',
            'transaction_type'    => 'CREDIT',
            'details_narration'   => $request->credit_details_narration ?? '',
            'amount'              => $request->credit ?? '0',
            'currency_id'         => '',
            'created_by'          => \Auth::user()->id ?? '',
            'company_id'          => \Auth::user()->company_id ?? '',
            'financial_year_id'   => $request->financial_year_id,
            'transactions_status' => true
        ];

        $contraVoucherTransaction = ContraVoucherTransaction::create($item);

        $transaction = AccountTransaction::createTransaction([
            'transactions_no'   => $transactionsData['transactions_no'],
            'transaction_date'  => $transaction_date,
            'module_code'       => 'CONTRA',
            'voucher_id'        => $contraVoucher->id,
            'voucher_sub_id'    => $contraVoucherTransaction->id,
            'voucher_type'      => 'CONTRA', // SALE, PURCHASE, PAYMENT
            'account_id'        => $request->credit_account_id ?? '',
            'transaction_type'  => 'CREDIT',
            'details_narration' => $request->credit_details_narration ?? '',
            'amount'            => $request->credit,
            'financial_year_id' => $request->financial_year_id,
            'last_id'           => $transactionsData['last_count'],
        ]);

        /*if (!empty($data) || isset($data['contra_voucher_entries']) || count($data['contra_voucher_entries']) > 0) {
            foreach ($data['contra_voucher_entries'] as $item) {
                $item1 = [
                   'transactions_no'     => $item['transactions_no'],
                   'transaction_date'    => $item['transaction_date'],
                   'module_id'           => $module_id,
                   'voucher_id'          => $contraVoucher->id,
                   'voucher_type'        => $item['voucher_type'],
                   'account_id'          => $item['account_id'],
                   'transaction_type'    => $item['transaction_type'],
                   'details_narration'   => $item['details_narration'],
                   'amount'              => $item['amount'],
                   'currency_id'         => $item['currency_id'],
                   'created_by'          => $item['created_by'],
                   'company_id'          => $item['company_id'],
                   'financial_year_id'   => $item['financial_year_id'],
                   'transactions_status' => true
                ];

                $contraVoucherTransaction = ContraVoucherTransaction::create($item1);
            }

           Session::put('contra_voucher_details', []);
        }*/

        return response()->json([
            'success' => true,
            'message' => 'New Contra Voucher Created Successfully!'
        ]);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $data          = Session::get('billing_products_cart') ?? [];
        $company_id    = \Auth::user()->company_id ?? '';
        $payment_terms = ($data['due_balance_amount'] < 1) ? 'CASH' : 'CREDIT';
        $sale_invoice  = [
            'type_id'                => $request->invoice_type_id,
            'payment_mode_id'        => $request->payment_mode,
            'totalbillingamount'     => $data['amount'],
            'date'                   => $data['sample_receive_date'],
            'patient_id'             => $data['patient_id'],
            'doctor_id'              => $data['doctor_id'],
            'collection_agent_id'    => $data['collection_id'],
            'refferal_lab_id'        => $data['refferal_id'],
            'reff_no'                => $request->reff_no,
            'amountreceived'         => $request->amount_recieved,
            'duebalanceamount'       => $data['due_balance_amount'],
            'sale_delivery_date'     => date('Y-m-d'),
            'sale_delivery_status'   => 'PENDING',
            'company_id'             => $company_id,
            'status'                 => 'NEWSALE',
            'remarks'                => $request->sale_remarks,
            'special_case_id'        => $request->special_case,
            'amountadjustment'       => $request->special_discount,
            'adjustment_type'        => $request->discount_type,
            'financial_year'         => $this->financialyear(),
            'payment_terms'          => $payment_terms,
            'industry_type'          => 'PATHOLOGY',
            'operator_id'            => \Auth::ID(),
        ];

        $sale_invoice    = SaleInvoice::create($sale_invoice);
        $sale_invoice_id = $this->generateCode($sale_invoice->id, 'INV');
        $sale_invoice->update(['enquiry_id' => $sale_invoice_id]);

        //sale invoice batch generate number
        $voucher_master      = VoucherMaster::with('voucherSeries')->where('voucher_code', 'Sales_Invoice_Batch')->first();
        $voucher_count_batch = SaleInvoiceBatch::select('last_voucher_count')->orderBy('created_at', 'DESC')->first();
        // dd($voucher_count_batch);

        $last_voucher_count_batch = isset($voucher_count_batch) && isset($voucher_count_batch->last_voucher_count) ? $voucher_count_batch->last_voucher_count + 1 : ($voucher_master->voucherSeries->start_from + 1 ?? 1);

        $main_invoice_no = $this->generateCode(
            $last_voucher_count_batch,
            ($voucher_master->voucherSeries->prefix ?? 'BAT'),
            ($voucher_master->voucherSeries->postfix ?? ''),
            ($voucher_master->voucherSeries->separator ?? '-'),
            ($voucher_master->voucherSeries->length ?? 5)
        );

        $invoice_batch = [
            'account_id'             => '',
            'invoice_batch_date'     => Carbon::now(),
            'invoice_batch_no'       => $main_invoice_no,
            'created_by'             => \Auth::user()->id,
            'invoice_id'             => $sale_invoice->id,
            'last_voucher_count'     => $last_voucher_count_batch,
            'sample_barcode'         => $request->sample_barcode,
            'sample_receive_date'    => $request->sample_receive_date,
            'sample_receive_time'    => $request->sample_receive_time,
            'remarks_for_technician' => $request->remarks_for_technician,
        ];
        //sale invoice batch
        $invoice_batch  = SaleInvoiceBatch::create($invoice_batch);


        foreach ($data['products'] as $key => $value) {
            $product = Product::select(['attribute_id', 'warehouse_id'])
                ->where('id', $value['product_id'])
                ->first();
            $product_price = ProductPrice::select(['batch'])
                ->where('id', $value['price_id'])
                ->first();
            $item = [
                'sale_invoice_id'      => $sale_invoice->id,
                'product_id'           => $value['product_id'],
                'item_code'            => $product->shortcode,
                'product_price_id'     => $value['price_id'],
                'sale_invoice_date'    => date('Y-m-d'),
                'item_price'           => $value['product_price'],
                'item_basic_amount'    => $value['product_price'],
                'item_discount'        => $value['per_discount'],
                'item_discount_amount' => $value['flat_discount'],
                'item_total_amount'    => $value['amount'],
                'item_details1'        => $value['product_details'],
                'item_batch'           => $product_price->batch ?? '',
                'item_details1'        => $product->description ?? '',
                'item_mqty'            => $product_price->item_min_stock_qty ?? '',
                'item_tax'             => $product->tax_slab_id ?? '',
                'delivery_status'      => 'PENDING',
            ];

            $sale_invoice_details = SaleInvoiceDetail::create($item);
            $product_test_package = ProductTestPackage::where('product_id', $value['product_id'])->get();

            foreach ($product_test_package as $package) {
                $addedTestPackage = SaleInvoiceSubDetails::create([
                    'invoice_details_id'         => $sale_invoice_details->id,
                    'invoice_id'                 => $sale_invoice->id,
                    'testpackage_id'             => $package->test_package_id,
                    'invoice_subdetails_remarks' => '',
                    'invoice_subdetails_status'  => 'SAMPLE_COLLECTION',
                ]);
            }
        }
        return redirect()->route('invoice-print', $sale_invoice_id)->with('success', "New Bill Created Successfully");
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $accountJournal = ContraVoucher::with(
            'financialYear',
            'company',
            'contraVoucherTransaction',
            'contraVoucherTransaction.financialYear',
            'contraVoucherTransaction.company',
            'contraVoucherTransaction.user',
            'contraVoucherTransaction.account',
            'contraVoucherTransaction.module'
        )
            ->where(['id' => $id])
            ->first();

        return view('contra-vouchers.show', compact('accountJournal'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $session            = Session::get('contra_voucher_details') ?? [];
        $data               = ContraVoucher::find($id);
        $contraVoucherDebit = ContraVoucherTransaction::select(
            'contra_voucher_transactions.*',
            'accounts.name as account_name',
            \DB::raw("IF(contra_voucher_transactions.transaction_type = 'DEBIT', contra_voucher_transactions.amount ,0) as debit"),
            \DB::raw("IF(contra_voucher_transactions.transaction_type = 'CREDIT', contra_voucher_transactions.amount ,0) as credit")
        )
            ->leftjoin('accounts', 'accounts.id', 'contra_voucher_transactions.account_id')
            ->where(['contra_voucher_transactions.voucher_id' => $id])
            ->where(['contra_voucher_transactions.transaction_type' => 'DEBIT'])
            ->first();
        $contraVoucherCredit = ContraVoucherTransaction::select(
            'contra_voucher_transactions.*',
            'accounts.name as account_name',
            \DB::raw("IF(contra_voucher_transactions.transaction_type = 'DEBIT', contra_voucher_transactions.amount ,0) as debit"),
            \DB::raw("IF(contra_voucher_transactions.transaction_type = 'CREDIT', contra_voucher_transactions.amount ,0) as credit")
        )
            ->leftjoin('accounts', 'accounts.id', 'contra_voucher_transactions.account_id')
            ->where(['contra_voucher_transactions.voucher_id' => $id])
            ->where(['contra_voucher_transactions.transaction_type' => 'CREDIT'])
            ->first();

        $financialYears = \Session::get('financialyear');
        $companyDateFormate = phpToJsDateFormat($this->companyDateFormate());
        return view('contra-vouchers.edit', compact(
            'data',
            'financialYears',
            'contraVoucherDebit',
            'contraVoucherCredit',
            'companyDateFormate'
        ));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(Request $request)
    {
        $data = ContraVoucher::find($request->id);
        $data->delete();

        ContraVoucherTransaction::where(['voucher_id' => $request->id])->delete();

        AccountTransaction::where([
            'module_code'       => 'CONTRA',
            'voucher_id'        => $request->id,
            'voucher_type'      => 'CONTRA'
        ])
            ->delete();

        $Redirect = 'journal-voucher';

        return response()->json([
            'success' => true,
            'message' => ['Deleted successfully'],
            'data'    => [
                'redirect' => $Redirect,
            ]
        ]);
    }

    public function searchAccounts(Request $request)
    {
        $searchTerm = $request->search_text;
        $account_id = $request->account_id ?? '';

        $results = Account::select(['accounts.id', 'accounts.name'])
            ->with('chart_of_account_sub_type')
            ->where(function ($query) {
                $query->whereHas('chart_of_account_sub_type', function ($accounting_group) {
                    $accounting_group->where('is_payment_mode', '1');
                });
            })
            ->where('accounts.name', 'LIKE', '%' . $searchTerm . '%')
            ->when(!empty($account_id), function ($query) use ($account_id) {
                return $query->where('accounts.id', '<>', $account_id);
            })
            ->get();

        return response()->json(['result' => $results, 'status' => true]);
    }

    public function contraVoucherEntries(Request $request)
    {
        $page = isset($request->page) && $request->page == 'billing' ? 1 : 0;
        $data = Session::get('contra_voucher_details') ?? [];

        return view('contra-vouchers.journal-voucher-entries', compact('data', 'page'));
    }

    public function editContraVoucherEntries(Request $request)
    {
        $page = isset($request->page) && $request->page == 'billing' ? 1 : 0;
        $data = Session::get('contra_voucher_details') ?? [];

        return view('contra-vouchers.edit-journal-voucher-entries', compact('data', 'page'));
    }

    public function addContraVouchers(Request $request)
    {
        $data = Session::get('contra_voucher_details') ?? [];

        if (!isset($data['voucher_no']) || $data['voucher_no'] == '') {
            $data['voucher_no'] = $request->voucher_no;
        }
        if (!isset($data['transaction_date']) || $data['transaction_date'] == '') {
            $transaction_date = isset($request->transaction_date) && $request->transaction_date != '' ? date('Y-m-d', strtotime($request->transaction_date)) : '';

            $data['transaction_date'] = $transaction_date;
        }

        if (!isset($data['financial_year_id']) || $data['financial_year_id'] == '') {
            $data['financial_year_id'] = $request->financial_year_id ?? '';
        }

        if (!isset($data['account_id']) || $data['account_id'] == '') {
            $data['account_id'] = $request->account_id ?? '';
        }

        if (!isset($data['account_name']) || $data['account_name'] == '') {
            $data['account_name'] = $request->account_name ?? '';
        }

        if (!isset($data['debit']) || $data['debit'] == '') {
            $data['debit'] = $request->debit ?? 0;
        }

        if (!isset($data['credit']) || $data['credit'] == '') {
            $data['credit'] = $request->credit ?? '0';
        }

        if (!isset($data['details_narration']) || $data['details_narration'] == '') {
            $data['details_narration'] = $request->details_narration ?? '';
        }

        if (!isset($data['description']) || $data['description'] == '') {
            $data['description'] = $request->description ?? '';
        }

        $company_address = \Session::get('company_data')['companies_addresses'];
        $countryCurrencyId = $company_address->currency_id ?? '0';

        $transaction_date = isset($request->transaction_date) && $request->transaction_date != '' ? date('Y-m-d', strtotime($request->transaction_date)) : '';
        $module        = MenuModelPermission::where('code', 'CONTRA_VOUCHER')->first();
        $module_id     = $module->id ?? '';

        $data['contra_voucher_entries'][] = [
            'transactions_no'       => 0,
            'transaction_date'      => $transaction_date ?? '',
            'module_id'             => $module_id,
            'voucher_type'          => 'CONTRA',
            'account_id'            => $request->account_id ?? '',
            'transaction_type'      => (isset($request->debit) && $request->debit > 0 ? 'DEBIT' : 'CREDIT'),
            'details_narration'     => $request->details_narration ?? '',
            'amount'                => (isset($request->debit) && $request->debit > 0 ? $request->debit : $request->credit),
            'created_by'            => \Auth::user()->id ?? '',
            'company_id'            => \Auth::user()->company_id ?? '',
            'currency_id'           => $countryCurrencyId,
            'financial_year_id'     => $request->financial_year_id ?? '',
            'debit'                 => $request->debit ?? '',
            'credit'                => $request->credit ?? '',
            'transactions_status'   => true,
            'account_name'          => $request->account_name ?? '',
        ];
        Session::put('contra_voucher_details', $data);

        return response()->json(['success' => true, 'message' => 'New Contra Voucher Entry Added Successfully!']);
    }

    public function editContraVouchers(Request $request)
    {
        $data = Session::get('contra_voucher_details') ?? [];

        if (!isset($data['voucher_no']) || $data['voucher_no'] == '') {
            $data['voucher_no'] = $request->voucher_no;
        }
        if (!isset($data['transaction_date']) || $data['transaction_date'] == '') {
            $transaction_date = isset($request->transaction_date) && $request->transaction_date != '' ? date('Y-m-d', strtotime($request->transaction_date)) : '';

            $data['transaction_date'] = $transaction_date;
        }

        if (!isset($data['financial_year_id']) || $data['financial_year_id'] == '') {
            $data['financial_year_id'] = $request->financial_year_id ?? '';
        }

        if (!isset($data['account_id']) || $data['account_id'] == '') {
            $data['account_id'] = $request->account_id ?? '';
        }

        if (!isset($data['account_name']) || $data['account_name'] == '') {
            $data['account_name'] = $request->account_name ?? '';
        }

        if (!isset($data['debit']) || $data['debit'] == '') {
            $data['debit'] = $request->debit ?? 0;
        }

        if (!isset($data['credit']) || $data['credit'] == '') {
            $data['credit'] = $request->credit ?? '0';
        }

        if (!isset($data['details_narration']) || $data['details_narration'] == '') {
            $data['details_narration'] = $request->details_narration ?? '';
        }

        if (!isset($data['description']) || $data['description'] == '') {
            $data['description'] = $request->description ?? '';
        }

        $company_address = \Session::get('company_data')['companies_addresses'];
        $countryCurrencyId = $company_address->currency_id ?? '0';

        $transaction_date  = isset($request->transaction_date) && $request->transaction_date != '' ? date('Y-m-d', strtotime($request->transaction_date)) : '';
        $module            = MenuModelPermission::where('code', 'CONTRA_VOUCHER')->first();
        $module_id         = $module->id ?? '';

        $data['edit_contra_voucher_entries'][] = [
            'transactions_no'       => 0,
            'transaction_date'      => $transaction_date ?? '',
            'module_id'             => $module_id,
            'voucher_type'          => 'CONTRA',
            'account_id'            => $request->account_id ?? '',
            'transaction_type'      => (isset($request->debit) && $request->debit > 0 ? 'DEBIT' : 'CREDIT'),
            'details_narration'     => $request->details_narration ?? '',
            'amount'                => (isset($request->debit) && $request->debit > 0 ? $request->debit : $request->credit),
            'created_by'            => \Auth::user()->id ?? '',
            'company_id'            => \Auth::user()->company_id ?? '',
            'currency_id'           => $countryCurrencyId,
            'financial_year_id'     => $request->financial_year_id ?? '',
            'debit'                 => $request->debit ?? '',
            'credit'                => $request->credit ?? '',
            'transactions_status'   => true,
            'account_name'          => $request->account_name ?? '',
        ];
        Session::put('contra_voucher_details', $data);

        return response()->json(['success' => true, 'message' => 'New Contra Voucher Entry Added Successfully!']);
    }

    public function cartProductRemove(Request $request)
    {
        $data = Session::get('billing_products_cart') ?? [];
        $id   = $request->id;

        $amount = $data['amount'];

        $data['products'] = array_filter($data['products'], function ($product) use ($id, &$data, &$amount) {
            if ($product['product_id'] == $id) {
                $amount = $data['amount'] - $product['amount'];
            }

            return $product['product_id'] != $id;
        });

        if (count($data['products']) == 0) {
            $data['amount'] = 0;
        } else {
            $data['amount'] = $amount;
        }

        Session::put('billing_products_cart', $data);

        return response()->json(['success' => true]);
    }

    public function cartProductUpdate(Request $request)
    {
        $data = Session::get('billing_products_cart') ?? [];

        if (isset($request->type) && $request->type == 'billing') {
            if (isset($request->invoice_date)) {
                $data['invoice_date'] = date('Y-m-d', strtotime($request->invoice_date));
            }

            if (isset($request->payment_mode)) {
                $data['payment_mode'] = $request->payment_mode;
            }

            if (isset($request->special_discount)) {
                $data['special_discount'] = $request->special_discount;
            }

            if (isset($request->discount_type)) {
                $data['discount_type'] = $request->discount_type;
            }

            if (isset($request->amount_recieved)) {
                $data['amount_recieved'] = $request->amount_recieved;
            }

            if (isset($request->special_discount) || isset($request->discount_type) || isset($request->amount_recieved)) {
                if ($data['discount_type'] == 'FLAT') {
                    $due_balance_amount = $data['amount'] - $data['special_discount'];
                    $data['due_balance_amount'] = $due_balance_amount - $data['amount_recieved'];
                } else {
                    $flat_discount = ($data['special_discount'] / 100) * $data['amount'];
                    $due_balance_amount = $data['amount'] - $flat_discount;
                    $data['due_balance_amount'] = $due_balance_amount - $data['amount_recieved'];
                }
            }
        } else {
            foreach ($data['products'] as $key => $value) {
                if ($value['product_id'] == $request->id && isset($request->product_details)) {
                    $data['products'][$key]['product_details'] = $request->product_details;
                }
                if ($value['product_id'] == $request->id && isset($request->vial_code)) {
                    $data['products'][$key]['vial_code'] = $request->vial_code;
                }
                if ($value['product_id'] == $request->id && isset($request->product_price)) {
                    $old_price = $data['products'][$key]['amount'];
                    $data['products'][$key]['product_price'] = $request->product_price;

                    $flat_discount   = ($value['per_discount'] / 100) * $request->product_price;
                    $data['products'][$key]['amount'] = $new_price = number_format($request->product_price - $flat_discount, 2, '.', '');
                    $data['products'][$key]['flat_discount'] = number_format($flat_discount, 2, '.', '');
                    $data['amount'] += ($new_price - $old_price);
                    $data['due_balance_amount'] = $data['amount'];
                }
                if ($value['product_id'] == $request->id && isset($request->per_discount)) {
                    $old_price = $data['products'][$key]['amount'];
                    $per_discount = $request->per_discount;
                    $data['products'][$key]['per_discount'] = number_format($per_discount, 2, '.', '');

                    $flat_discount = ($per_discount / 100) * $data['products'][$key]['product_price'];
                    $data['products'][$key]['amount'] = $new_price = number_format($data['products'][$key]['product_price'] - $flat_discount, 2, '.', '');
                    $data['products'][$key]['flat_discount'] = number_format($flat_discount, 2, '.', '');
                    $data['amount'] += ($new_price - $old_price);
                    $data['due_balance_amount'] = $data['amount'];
                }
                if ($value['product_id'] == $request->id && isset($request->flat_discount)) {
                    $old_price = $data['products'][$key]['amount'];
                    $per_discount  = ($request->flat_discount / $data['products'][$key]['product_price']) * 100;
                    $data['products'][$key]['per_discount']  = number_format($per_discount, 2, '.', '');
                    $data['products'][$key]['amount'] = $new_price = number_format($data['products'][$key]['product_price'] - $request->flat_discount, 2, '.', '');
                    $data['products'][$key]['flat_discount'] = number_format($request->flat_discount, 2, '.', '');
                    $data['amount'] += ($new_price - $old_price);
                    $data['due_balance_amount'] = $data['amount'];
                }
            }
        }

        Session::put('billing_products_cart', $data);

        return response()->json(['success' => true, 'data' => $data]);
    }
    public function print($id)
    {
        return view('lab-billings.print');
    }

    public function changeStatus(Request $request)
    {
        if ($request->ajax()) {
            $data   = array('voucher_status' => $request->status);
            $Update = ContraVoucher::where('id', '=', $request->id)->update($data);

            if ($Update) {
                return response()->json([
                    'success' => true,
                    'message' => ['Contra Voucher status successfully change'],
                    'data'    => [
                        'redirect' => '/contra-vouchers/',
                        'reload' => true,
                    ]
                ]);
            } else {
                return response()->json([
                    'success' => false,
                    'message' => ['Error for change status'],
                    'data'    => [
                        'redirect' => '',
                    ]
                ]);
            }
        }
    }

    public function changeApprovalStatus(Request $request)
    {
        if ($request->ajax()) {
            $data   = array('voucher_approval_status' => $request->status);
            $Update = ContraVoucher::where('id', '=', $request->id)->update($data);

            if ($Update) {
                return response()->json([
                    'success' => true,
                    'message' => ['Contra Voucher approval status successfully change'],
                    'data' => [
                        'redirect' => '/contra-vouchers/',
                        'reload' => true,
                    ]
                ]);
            } else {
                return response()->json([
                    'success' => false,
                    'message' => ['Error for change approval status'],
                    'data' => [
                        'redirect' => '',
                    ]
                ]);
            }
        }
    }

    public function contraVoucherEntryRemove(Request $request)
    {
        $index              = $request->id;
        $event_data_display = Session::get('contra_voucher_details');

        unset($event_data_display['contra_voucher_entries'][$index]);

        Session::put('contra_voucher_details', $event_data_display);

        return response()->json(['success' => true, 'message' => 'New Contra Voucher Entry Removed Successfully!']);
    }

    public function editContraVoucherEntryRemove(Request $request)
    {
        $index              = $request->id;
        $event_data_display = Session::get('contra_voucher_details');

        unset($event_data_display['edit_contra_voucher_entries'][$index]);

        Session::put('contra_voucher_details', $event_data_display);

        return response()->json([
            'success' => true,
            'message' => 'Edit Contra Voucher Entry Removed Successfully!',
            'data'    => $event_data_display
        ]);
    }

    public function printContraVoucher($id)
    {
        $accountJournal = ContraVoucher::with(
            'financialYear',
            'company',
            'contraVoucherTransaction',
            'contraVoucherTransaction.financialYear',
            'contraVoucherTransaction.company',
            'contraVoucherTransaction.user',
            'contraVoucherTransaction.account',
            'contraVoucherTransaction.module'
        )
            ->with('voucherTerm')
            ->where(['id' => $id])
            ->first();

        return view('invoice-formats.contra-voucher.contra-voucher', compact('accountJournal'));

        $pdfData  = [
            'accountJournal' => $accountJournal,
        ];

        $pdf = PDF::loadView('invoice-formats.contra-voucher.contra-voucher', $pdfData)->set_option("isPhpEnabled", true)
            ->setPaper('a4', 'portrait')
            ->setWarnings(false);

        $filename = "contra-voucher_" . date("Y_m_d_i_H") . ".pdf";

        return $pdf->download($filename);
    }

    public function contraVoucherEntryUpdate(Request $request)
    {
        $data = Session::get('contra_voucher_details') ?? [];

        foreach ($data['contra_voucher_entries'] as $key => $value) {
            if ($key == $request->id && isset($request->details_narration)) {
                $data['contra_voucher_entries'][$key]['details_narration'] = $request->details_narration;
            }
            if ($key == $request->id && isset($request->amount)) {
                $data['contra_voucher_entries'][$key]['amount'] = $request->amount;
            }
            if ($key == $request->id && isset($request->debit)) {
                $data['contra_voucher_entries'][$key]['debit'] = $request->debit;
                $data['contra_voucher_entries'][$key]['amount'] = $request->debit;
            }
            if ($key == $request->id && isset($request->credit)) {
                $data['contra_voucher_entries'][$key]['credit'] = $request->credit;
                $data['contra_voucher_entries'][$key]['amount'] = $request->credit;
            }
        }

        Session::put('contra_voucher_details', $data);

        return response()->json(['success' => true, 'data' => $data]);
    }

    public function editContraVoucherEntryUpdate(Request $request)
    {
        $data = Session::get('contra_voucher_details') ?? [];

        foreach ($data['edit_contra_voucher_entries'] as $key => $value) {
            if ($key == $request->id && isset($request->details_narration)) {
                $data['edit_contra_voucher_entries'][$key]['details_narration'] = $request->details_narration;
            }
            if ($key == $request->id && isset($request->amount)) {
                $data['edit_contra_voucher_entries'][$key]['amount'] = $request->amount;
            }
            if ($key == $request->id && isset($request->debit)) {
                $data['edit_contra_voucher_entries'][$key]['debit'] = $request->debit;
                $data['edit_contra_voucher_entries'][$key]['amount'] = $request->debit;
            }
            if ($key == $request->id && isset($request->credit)) {
                $data['edit_contra_voucher_entries'][$key]['credit'] = $request->credit;
                $data['edit_contra_voucher_entries'][$key]['amount'] = $request->credit;
            }
        }

        Session::put('contra_voucher_details', $data);

        return response()->json(['success' => true, 'data' => $data]);
    }

    public function contraVoucherStatement(Request $request)
    {
        $company = Company::find(Auth::user()->company_id);
        $companyDateFormate = phpToJsDateFormat($this->companyDateFormate());
        if ($request->ajax()) {
            $from_date       = $request->from_date ? Carbon::createFromFormat($this->companyDateFormate(), $request->from_date)->format('Y-m-d') : date('Y-m-d');
            $to_date         = $request->to_date ? Carbon::createFromFormat($this->companyDateFormate(), $request->to_date)->format('Y-m-d') : date('Y-m-d');
            $branch    = $request->branch ?? '';
            $account   = $request->account ?? '';
            $created_by  = $request->created_by ?? '';

            $accountJournal = $this->queryFilter($request);
            return view('invoice-formats.contra-voucher.statement-table', compact(
                'accountJournal',
                'from_date',
                'to_date',
                'company',
            ));
        }

        $voucher_type = VoucherType::where('code', 'CONTRA')->where(['status' => 1])->first();

        return view('invoice-formats.contra-voucher.statement', compact(
            'company',
            'voucher_type',
            'companyDateFormate'
        ));
    }

    public function exportStatement(Request $request)
    {
        $from_date       = $request->from_date ? Carbon::createFromFormat($this->companyDateFormate(), $request->from_date)->format('Y-m-d') : date('Y-m-d');
        $to_date         = $request->to_date ? Carbon::createFromFormat($this->companyDateFormate(), $request->to_date)->format('Y-m-d') : date('Y-m-d');
        $data = $this->queryFilter($request);
        $fileName = 'Contra-Voucher-Statements' . ' From ' . $from_date . ' To ' . $to_date . '.xlsx';
        return Excel::download(new ContraVoucherExport($data->toArray()), $fileName);
    }
    public function queryFilter(Request $request)
    {
        $from_date          = $request->from_date ? Carbon::createFromFormat($this->companyDateFormate(), $request->from_date)->format('Y-m-d') : date('Y-m-d');
        $to_date            = $request->to_date ? Carbon::createFromFormat($this->companyDateFormate(), $request->to_date)->format('Y-m-d') : date('Y-m-d');
        $branch             = $request->branch ?? '';
        $account            = $request->account ?? '';
        $paymentMode        = $request->payment_mode ?? '';
        $created_by         = $request->created_by??'';
        $voucher_type_search= $request->voucher_type??'';

        $accountJournal = ContraVoucher::with(
            'contraVoucherTransaction',
            'contraVoucherTransaction.financialYear',
            'contraVoucherTransaction.company',
            'contraVoucherTransaction.user',
            'contraVoucherTransaction.account',
            'contraVoucherTransaction.module'
        )
            ->when($from_date != '' && $to_date != '', function ($query) use ($from_date, $to_date) {
                $query->whereBetween('contra_vouchers.transaction_date', [
                    date('Y-m-d', strtotime($from_date)),
                    date('Y-m-d', strtotime($to_date))
                ]);
            })
            ->when($branch != '', function ($query) use ($branch) {
                $query->where('contra_vouchers.company_id', $branch);
            })
            ->when($created_by != '', function ($query) use ($created_by) {
                $query->where('created_by', $created_by);
            })
            ->when($paymentMode != '', function ($query) use ($paymentMode) {
                $query->whereHas('contraVoucherTransaction', function ($query) use ($paymentMode) {
                    $query->where('contra_voucher_transactions.account_id',$paymentMode);
                });
            })
            ->when($account != '', function ($query) use ($account) {
                $query->whereHas('contraVoucherTransaction', function ($query) use ($account) {
                    $query->where('contra_voucher_transactions.account_id',$account);
                });
            })
            ->get();
        return $accountJournal;
    }
}
