<?php

namespace App\Http\Controllers\pos;

use App\Fun\Fun;
use App\Model\payment\PaymentDetailModel;
use App\Model\payment\PaymentModel;
use App\Model\pos\SaleDetailsModel;
use App\Model\pos\SaleModel;
use App\Model\product\ColorModel;
use App\Model\product\ProductModel;
use App\Model\product\SizeModel;
use App\Model\ProductReturn\ProductReturnDetailModel;
use App\Model\ProductReturn\ProductReturnModel;
use App\Model\product\ProductUnitModel;
use App\Model\setup\MemberModel;
use App\Model\setup\MemberTypeModel;
use App\Model\stock_inventory\StockModel;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Auth;
use DB;
use Illuminate\Validation\ValidationException;
use Yajra\DataTables\DataTables;

class ProductReturnController extends Controller
{
    function __construct()

    {
//            $this->middleware('permission:Product Return Create', ['only' => ['create', 'store']]);
//            $this->middleware('permission:Product Return List', ['only' => ['show', 'index']]);
    }

    public function index(Request $request)
    {
        Fun::lang();
        if ($request->ajax()) {
            $customer = $request->customer_id;
            $date = $request->date;
            $data = ProductReturnModel::with(['customer', 'user'])
                ->where('user_id', auth()->id())
                ->when($customer, function ($q) use ($customer) {
                    $q->where('customer_id', $customer);
                })
                ->when($date, function ($q) use ($date) {
                    $q->whereDate('date', sDate($date));
                })->latest();
            return DataTables::of($data)
                ->editColumn('date', function ($data) {
                    return myDate($data->date);
                })
                ->editColumn('grand_total', function ($data) {
                    $return = ProductReturnDetailModel::where(['type' => 'return', 'product_return_id' => $data->id])->selectRaw("SUM(qty*price) as total")->first()->total ?? 0;
                    $change = ProductReturnDetailModel::where(['type' => 'change', 'product_return_id' => $data->id])->selectRaw("SUM(qty*price) as total")->first()->total ?? 0;
                    return findCurrency($data->currency_id)->symbol . ($change - $return);
                })
                ->addColumn('action', function ($data) {
                    $route = route('product-return.show', $data->id);
                    return "<button type='button' class='button_info fa fa-eye getHtmlFormShow' data-width='800px' data-href='$route'></button>";
                })
                ->addIndexColumn()
                ->rawColumns(['action'])
                ->make(true);

        }
        return view('pos.product-return.index');
    }

    public function create(Request $request)
    {
        if ($request->ajax()) {
            if ($request->getInvoice) {
                $sale = SaleModel::where(['id' => $request->sale_id, 'return_status' => 0])->selectRaw('id,customer_id,member_type_id,currency_id')->first();
                $sale->customer = findCustomer($sale->customer_id)->name ?? '';
                $sale->member_type = MemberTypeModel::find($sale->member_type_id)->name ?? '';
                $sale->currency = findCurrency($sale->currency_id)->symbol ?? '';
                if ($sale) {
                    $detail = SaleDetailsModel::where('sale_id', $sale->id)->selectRaw(
                        'id as detail_id,
                            sale_id,
                            product_id,
                            qty,
                            sale_price,
                            barcode,
                            unit_id,
                            size_code,
                            color_code,
                            item_grand_total
                           '
                    )->get()->map(function ($data) {
                        $data->product_name = getProductById($data->product_id)->product_name ?? '';
                        $data->unit = findUnit($data->unit_id)->unit ?? '';
                        $data->size = findSize($data->size_code)->size ?? '';
                        $data->color = findColor($data->color_code)->name ?? '';
                        return $data;
                    });

                    return response()->json(['sale' => $sale, 'detail' => $detail]);
                }
                return response()->json('no-data');
            }

            if ($request->size_code && $request->color_code && $request->product_id && $request->sale_id) {
                $sale = SaleModel::where(['id' => $request->sale_id, 'return_status' => 0])->first();
                $price = MemberModel::where(['product_id' => $request->product_id, 'member_type' => $sale->member_type_id])->first();
                if ($price) {
                    $price = $sale->currency_id === 1 ? $price->price_riel : $price->price_usd;
                } else {
                    $price = 0;
                }
                return response()->json(['price' => $price]);
            }

            $size = ProductUnitModel::where('product_id', $request->product_id)->pluck('size_code');
            $color = ProductUnitModel::where('product_id', $request->product_id)->pluck('color_code');
            $size = SizeModel::whereIn('code', $size)->pluck('size', 'code');
            $color = ColorModel::whereIn('code', $color)->pluck('name', 'code');
            return response()->json(['color' => $color, 'size' => $size]);
        }
        return view('pos.product-return.create');
    }

    public function store(Request $request)
    {
        $this->validate($request, [
            'date' => 'required',
            'sale_id' => 'required',
            'detail_id' => 'required',
            'detail_id.*' => 'required',
            'return_qty.*' => 'required',

            'size_id.*' => 'required',
            'size_code.*' => 'required',
            'qty.*' => 'required',
            'price.*' => 'required',
            'grand_total' => 'required',
        ]);

        $sale = SaleModel::where(['id' => $request->sale_id, 'return_status' => 0])->first();

        $total_return = array_sum($request->return_qty);
        $total_qty = array_sum($request->qty ?? []);
        $wh = $sale->warehouse_id;

        if (!$sale) throw ValidationException::withMessages(['sale_id' => 'Invoice is invalid !!!']);
        if (!$total_return) throw ValidationException::withMessages(['return qty' => 'Please add return item !!!']);

        if ($request->product_id) {
            $error = [];
            foreach ($request->product_id as $key => $item) {
                $product_unit = ProductUnitModel::where(['product_id' => $item, 'size_code' => $request->size_code[$key], 'color_code' => $request->color_code[$key]])->first();
                $stock_data = [
                    'barcode' => $product_unit->barcode,
                    'size_code' => $product_unit->size_code,
                    'color_code' => $product_unit->color_code,
                    'product_id' => $item,
                    'warehouse_id' => $wh
                ];
                $stock = StockModel::where($stock_data)->first();
                $stock = $stock->stock_qty ?? 0;
                if ($request->qty[$key] > $stock) {
                    $product = ProductModel::find($product_unit->product_id)->product_name ?? '';
                    $size = findSize($product_unit->size_code)->size ?? '';
                    $color = findColor($product_unit->color_code)->name ?? '';
                    $error["qty[$key]"] = "$product ($size,$color) មានចំនួនមិនគ្រប់គ្រាន់ ។";
                }
            }
            if (count($error)) throw ValidationException::withMessages($error);
        }
        $data = $request->all();
        $data['user_id'] = auth()->id();
        $data['branch_id'] = auth()->user()->branch_id;
        $data['date'] = sDate($request->date);
        $data['currency_id'] = $sale->currency_id;
        $data['warehouse_id'] = $wh;
        $data['member_type_id'] = $sale->member_type_id;
        $data['customer_id'] = $sale->customer_id;
        $data['reference_number'] = $sale->invoice_number;

        $product_return = ProductReturnModel::create($data);
        $sale->return_status = 1;
        $sale->total_qty = ($sale->total_qty + $total_qty) - $total_return;
        $total_discount_foreach_item = $sale->discount / $sale->total_qty;

        $grand_total = $sale->grand_total;
        foreach ($request->detail_id as $key => $item) {
            $return_qty = $request->return_qty[$key];
            $detail = SaleDetailsModel::find($item);
            $detail->qty -= $return_qty;
            $total_amount_item = $detail->sale_price * $detail->qty;
            $item_discount_in_cash = $detail->dis;
            $total_discount_foreach_item_qty = $total_discount_foreach_item * $detail->qty;
            $item_grand_total = $total_amount_item - $total_discount_foreach_item_qty - $item_discount_in_cash;
            if ($return_qty) {
                $grand_total -= $detail->sale_price * $return_qty;

                $stock_data = [
                    'barcode' => $detail->barcode,
                    'size_code' => $detail->size_code,
                    'color_code' => $detail->color_code,
                    'product_id' => $detail->product_id,
                    'warehouse_id' => $wh
                ];
                ProductReturnDetailModel::create(array_merge($stock_data, [
                    'product_return_id' => $product_return->id,
                    'qty' => $return_qty,
                    'price' => $detail->sale_price,
                    'type' => 'return'
                ]));
                $detail->return_qty = $return_qty;

                $detail->total_amount = $total_amount_item;
                $detail->item_discount_in_cash = $item_discount_in_cash;
                $detail->total_discount_in_cash = $total_discount_foreach_item_qty;
                $detail->item_grand_total = $item_grand_total;
                $detail->save();
                $old_stock = StockModel::where($stock_data)->first()->stock_qty ?? 0;
                StockModel::updateOrCreate($stock_data, array_merge($stock_data, ['type' => 'product', 'stock_qty' => ($old_stock + $return_qty)]));

            }

        }

        if ($request->product_id) {
            foreach ($request->product_id as $key => $item) {
                $qty = $request->qty[$key];
                $price = $request->price[$key];
                $product_unit = ProductUnitModel::where(['product_id' => $item, 'size_code' => $request->size_code[$key], 'color_code' => $request->color_code[$key]])->first();
                $stock_data = [
                    'barcode' => $product_unit->barcode,
                    'size_code' => $product_unit->size_code,
                    'color_code' => $product_unit->color_code,
                    'product_id' => $item,
                    'warehouse_id' => $wh
                ];
                ProductReturnDetailModel::create(array_merge($stock_data, [
                    'product_return_id' => $product_return->id,
                    'qty' => $qty,
                    'price' => $price,
                    'type' => 'change'
                ]));
                $total_amount_item = $price * $qty;
                $total_discount_foreach_item_qty = $total_discount_foreach_item * $qty;
                $item_grand_total = $total_amount_item - $total_discount_foreach_item_qty;
                if ($sale->currency_id === 1) {
                    if ($product_unit->cost_riel) {
                        $cost = $product_unit->cost_riel;
                    } else {
                        $cost = $product_unit->cost_usd * getRate();
                    }
                } else {
                    if ($product_unit->cost_usd) {
                        $cost = $product_unit->cost_usd;
                    } else {
                        $cost = $product_unit->cost_riel / getRate();
                    }
                }
                $sale_detail = array(
                    'sale_id' => $sale->id,
                    'product_id' => $item,
                    'qty' => $qty,
                    'sale_price' => $price,
                    'barcode' => $product_unit->barcode,
                    'size_code' => $product_unit->size_code,
                    'color_code' => $product_unit->color_code,
                    'unit_id' => $product_unit->unit_id,
                    'product_cost' => $cost,
                    'total_amount' => $total_amount_item,
                    'total_discount_in_cash' => $total_discount_foreach_item_qty,
                    'item_grand_total' => $item_grand_total,
                );
                SaleDetailsModel::create($sale_detail);
                $grand_total += $item_grand_total;

                $old_stock = StockModel::where($stock_data)->first()->stock_qty ?? 0;
                StockModel::updateOrCreate($stock_data, array_merge($stock_data, ['type' => 'product', 'stock_qty' => ($old_stock - $request->qty[$key])]));
            }
        }

        $payment = PaymentModel::where(['invoice_id' => $sale->id])->whereIn('type',['sale-request','retail','wholesale'])->first();

        $sale->grand_total = $grand_total;

        if ($payment) {
            $payment->payment_amount = $grand_total;

            if ($sale->payment_status == 'paid') {
                $payment->paid_amount = $grand_total;
                PaymentDetailModel::where('payment_id',$payment->id)->delete();
                $payment_detail = array(
                    'payment_id' => $payment->id,
                    'payment_by' => $payment->user_id,
                    'paid_amount' => $grand_total,
                    'payment_date' => date('Y-m-d'),
                    'status' => 1,
                );
                PaymentDetailModel::create($payment_detail);
            }
            $payment->save();
        }

        if ($sale->payment_status == 'paid') {
            $sale->paid_amount = $grand_total;
        }
        $sale->save();


        return response()->json(['status' => 'success', 'route' => route('product-return.index')]);

    }

    public function show($id)
    {
        $master = ProductReturnModel::find($id);
        return view('pos.product-return.show', compact('master'));
    }
}
