<?php

namespace App\Http\Controllers\StockInventory\purchase;

use App\Model\account\JournalModel;
use App\Model\payment\PaymentDetailModel;
use App\Model\payment\PaymentModel;
use App\Model\product\ProductModel;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use DB;
use Auth;
use DataTables;
use App\Model\people\SupplierModel;
use App\Model\stock_inventory\PurchaseDetailsModel;
use App\Model\stock_inventory\PurchaseModel;
use App\Model\stock_inventory\StockModel;
use App\Model\product\ProductUnitModel;

class PurchaseFabricController extends Controller

{

    function __construct()
    {

        $this->middleware('permission:Purchase Material create', ['only' => ['create', 'store']]);

    }

    public function index()
    {
        return redirect()->route('purchases.index');
    }

    public function create(Request $request)
    {
        $warehouse = getWarehouse('fabric')->pluck('warehouse_name', 'id');
        $suppliers = getSupplier('fabric')->pluck('supplier_name', 'id');
        if ($request->ajax()) {
            $search = $request->barcode;
            $products = ProductModel::where('nso007_products.type', 'fabric')
                ->where(function ($q) use ($search) {
                    if ($search) {
                        $q->where('nso007_products.barcode', 'LIKE', '%' . $search . '%');
                        $q->orwhere('nso007_products.product_name', 'LIKE', '%' . $search . '%');
                    }
                })
                ->paginate(12);
            return view('stock-inventory.purchases.fabric.result-create', ['products' => $products]);
        }
        return view('stock-inventory.purchases.fabric.create', ['warehouse' => $warehouse, 'suppliers' => $suppliers]);
    }

    public function add_supplier(Request $request)
    {
        if ($request->ajax()) {
            if ($request->input('supplier_name')) {
                $supplier = new SupplierModel();
                $supplier->supplier_name = $request->input('supplier_name');
                $supplier->supplier_phone = $request->input('supplier_phone');
                $supplier->type = 'fabric';
                $supplier->save();
                return response()->json(['supplier' => $supplier]);
            }
        }
    }

    public function store(Request $request)
    {
        $this->validate($request, [
            'invoice_number' => 'required',
            'supplier_id' => 'required',
            'warehouse_id' => 'required',
            'cost.*' => 'required',
            'qty.*' => 'required',
            'product_id' => 'required',
        ]);
        $product_id = $request->product_id;
        $qty = $request->qty;
        $cost = $request->cost;
        $dis = $request->dis;
        $qty_per_unit = $request->qty_per_unit;

        $paid = $request->paid ? $request->paid : 0;
        $total = $request->g_total_hidden;
        //Insert to Purchases
        if ($paid >= $total) {
            $payment_status = 'paid';
        } else {
            if ($paid > 0) {
                $payment_status = 'partial';
            } else {
                $payment_status = 'due';
            }
        }
        $purchase = new PurchaseModel();
        $purchase->user_id = Auth::user()->id;
        $purchase->supplier_id = $request->supplier_id;
        $purchase->payment_status = $payment_status;
        $purchase->invoice_number = $request->invoice_number;
        $purchase->transaction_code = 'PURS' . date('YmdHis');
        $purchase->purchase_date = date('Y-m-d', strtotime($request->date)) . ' ' . date('H:i:s');
        $purchase->year = date('Y');
        $purchase->user_id = Auth::user()->id;
        $purchase->rate = getRate();
        $purchase->paid = $paid;
        $purchase->currency_id = user_currency()->id;
        $purchase->discount = $request->discount;
        $purchase->warehouse_id = $request->warehouse_id;
        $purchase->type = 'fabric';
        $purchase->save();

        $last_id_purchase = $purchase->id;
        $arr_journal = [
            'branch_id' => myBranch()->id,
            'journal_by_supplier' => $purchase->supplier_id,
            'journal_type' => 1,
            'voucher_type' => 2,
            'journal_transactiondate' => sDate($request->date),
            'journal_paydate' => sDate($request->date),
            'journal_currency' => 2,
            'transaction_type' => 'Purchase Item',
            'journal_referenceid' => $purchase->id,
            'voucher_ref' => "V-" . generate_voucher_number((maxJournalId() + 1), 8),
            'journal_by' => \Auth::id(),
            'journal_reference_number' => $purchase->invoice_number,
            'journal_tran_id' => maxJournalId() + 1,
        ];
        foreach ($product_id as $key => $value) {
            //Insert to Purchase Details
            $product = getProductById($value);
            $pd = new PurchaseDetailsModel();
            $pd->purchase_id = $purchase->id;
            $pd->product_id = $value;
            $pd->qty = $qty[$key];
            $pd->qty_per_unit = $qty_per_unit[$key];
            $pd->cost_per_unit = $cost[$key];
            $pd->cost = $cost[$key] * $qty_per_unit[$key];
            $pd->dis = $dis[$key];
            $pd->barcode = $product->barcode;
            $pd->created_at = date('Y-m-d h:i:s');
            $pd->updated_at = date('Y-m-d h:i:s');
            $pd->save();
            //Insert to Stock
            $stock_qty = $qty[$key] * $qty_per_unit[$key];
            $stock = StockModel::where(array(
                'product_id' => $value,
                'barcode' => $product->barcode,
                'type' => 'fabric',
                'warehouse_id' => $request->warehouse_id
            ))->whereBetween('qty_per_unit', [$request->qty_per_unit[$key] - 0.01, $request->qty_per_unit[$key] + 0.01])->first();

            if(!$stock){
                $stock = new StockModel();
            }
            $stock->stock_qty += $stock_qty;
            $stock->warehouse_id = $request->warehouse_id;
            $stock->type = 'fabric';
            $stock->product_id = $value;
            $stock->barcode = $product->barcode;
            $stock->qty_per_unit = $qty_per_unit[$key];
            $stock->save();

            $s_total = $pd->cost * $pd->qty;
            $own_total = ($s_total) - (($s_total) * ($pd->dis / 100));

            if ($purchase->currency_id === 1) {
                $own_total /= user_currency()->rate;
                $own_total = (float)number_format($own_total, 2);
            }

            $product = getProductById($stock->product_id);
            $arr_journal['journal_acccode'] = '11006';
            $arr_journal['journal_des'] = 'បានចូលស្តុក ' . ($product->product_name ?? '') . '(' . ($product->barcode ?? '') . ") => $own_total$";
            $arr_journal['journal_debit'] = $own_total;
            $arr_journal['journal_credit'] = 0;
            addJournal($arr_journal);
        }
        $payment = new PaymentModel();
        $payment->user_id = Auth::user()->id;
        $payment->payment_invoice = generate_inv('nso007_purchases', 'PU');
        $payment->invoice_id = $last_id_purchase;
        $payment->payment_date = date('Y-m-d');
        $payment->payment_amount = $total;
        $payment->paid_amount = $paid;
        $payment->currency_id = user_currency()->id;
        $payment->payment_status = $payment_status;
        $payment->supplier_id = $request->supplier_id;
        $payment->year = date('Y');
        $payment->status = 1;
        $payment->type = 'purchase';
        $payment->save();
        $payment_detail = array(
            'payment_id' => $payment->id,
            'paid_amount' => $paid,
            'payment_date' => date('Y-m-d', strtotime($request->date)),
            'status' => 1,
        );
        PaymentDetailModel::insert($payment_detail);


        if ($purchase->currency_id === 1) {
            $paid /= user_currency()->rate;
            $total /= user_currency()->rate;

            $paid = (float)number_format($paid, 2);
            $total = (float)number_format($total, 2);
        }
        if ($payment_status === 'paid') {
            $arr_journal['journal_acccode'] = 11001;
            $arr_journal['journal_des'] = "បានបង់ $total$ ($purchase->invoice_number)";
            $arr_journal['journal_debit'] = 0;
            $arr_journal['journal_credit'] = $total;
            addJournal($arr_journal);
        } else {
            if ($payment_status === 'partial') {
                $arr_journal['journal_acccode'] = 11001;
                $arr_journal['journal_des'] = "បានបង់ $paid$ ($purchase->invoice_number)";
                $arr_journal['journal_credit'] = $paid;
                addJournal($arr_journal);

                $owe = $total - $paid;
                $arr_journal['journal_acccode'] = $branch->acc_account_payable ?? '21001';
                $arr_journal['journal_des'] = "បានជំពាក់ $owe$ ($purchase->invoice_number)";
                $arr_journal['journal_debit'] = 0;
                $arr_journal['journal_credit'] = $owe;
                addJournal($arr_journal);
            } else {
                $arr_journal['journal_acccode'] = $branch->acc_account_payable ?? '21001';
                $arr_journal['journal_des'] =  "បានជំពាក់ $total$ ($purchase->invoice_number)";
                $arr_journal['journal_debit'] = 0;
                $arr_journal['journal_credit'] = $total;
                addJournal($arr_journal);
            }
        }

        session()->put('success', 'Product created successfully');
        return response()->json(['status' => 'success', 'route' => route('purchases.index')]);

    }

    public function scan_code(Request $request)

    {
        $std = new \stdClass();
        $value = $request->barcode;
        if ($value) {
            $stock_item = ProductUnitModel::select('nso007_product_unit.*', 'nso007_products.product_name', 'nso007_products.currency')
                ->join('nso007_products', 'nso007_products.id', 'nso007_product_unit.product_id')
                ->where('nso007_products.type', 'fabric')
                ->where(function ($q) use ($value) {
                    $q->where('nso007_product_unit.barcode', $value);
                })->first();
            if ($stock_item) {
                $std->id = $stock_item->id;
                $std->qty_per_unit = $stock_item->qty_per_unit;
                $std->name = getProductById($stock_item->product_id)->product_name;
                $std->stock = $stock_item->stock_qty;
                $std->code = $stock_item->barcode;
                $std->unit = findUnit($stock_item->unit_id)->unit;
                $std->price = ProductUnitModel::where('barcode', $stock_item->barcode)->first()->cost;
                $std->symbol = findProductCurrency($stock_item->product_id);
            }
        } else {
            $stock_item = null;
        }
        return response()->json(['data' => $std]);

    }
}

