<?php

namespace App\Http\Controllers\Administrator\production;

use App\Fun\Fun;
use App\Http\Controllers\Controller;
use App\Model\payment\PaymentDetailModel;
use App\Model\payment\PaymentModel;
use App\Model\production\TailorStockPaymentModel;
use App\Model\people\TailorModel;
use App\Model\production\cutting\CuttingDetailModel;
use App\Model\production\cutting\CuttingModel;
use App\Model\production\ProductionDoneDetailModel;
use App\Model\production\ProductionDoneModel;
use App\Model\production\ProductionRequestDetailModel;
use App\Model\production\ProductionRequestModel;
use App\Model\production\ProductionTemplateDetailModel;
use App\Model\production\ProductionTemplateModel;
use App\Model\product\ProductUnitModel;
use App\Model\stock_inventory\StockModel;
use App\Model\setup\WarehouseModel;
use App\User;
use Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Validation\ValidationException;
use Yajra\DataTables\DataTables;

class ProductionRequestController extends Controller
{
    public function __construct()
    {
        $this->middleware('permission:Production Request Create', ['only' => ['create', 'store']]);
        $this->middleware('permission:Production Request List', ['only' => ['index']]);
        $this->middleware('permission:Production Request Show', ['only' => ['show']]);
        $this->middleware('permission:Production Request Approve', ['only' => ['update_status']]);
        $this->middleware('permission:Production Request Return Item', ['only' => ['import_stock']]);
        Fun::lang();
    }

    public function index(Request $request)
    {

        if ($request->ajax()) {
            $user_id = $request->user_id;
            $tailor = $request->tailor_id;
            $data = ProductionRequestModel::where(function ($query) use ($user_id) {
                if ($user_id) {
                    $query->Where('nso007_production_request.user_id', $user_id);
                }
            })
                ->where(function ($query) use ($tailor) {
                    if ($tailor) {
                        $query->Where('nso007_production_request.tailor_id', $tailor);
                    }
                })
                ->orderBy('nso007_production_request.id', 'DESC');
            return DataTables::of($data)
                ->addColumn('user_id', function ($production) {
                    $user = findUser($production->user_id);
                    return $user ? $user->name : '';
                })
                ->addColumn('tailor_id', function ($production) {
                    return $production->tailor_id ? TailorModel::find($production->tailor_id)->name : '';
                })
                ->addColumn('date', function ($production) {
                    return date('d-m-Y', strtotime($production->date));
                })
                ->addColumn('total', function ($production) {
                    $cur = findCurrency($production->currency_id);
                    $production->symbol = $cur->symbol ?? '';
                    return $production->symbol . ($production->total_item * $production->cost_per_item);
                })
                ->editColumn('cost_per_item', function ($production) {
                    $cur = findCurrency($production->currency_id);
                    $production->symbol = $cur->symbol ?? '';
                    return $production->symbol . ($production->cost_per_item);
                })
                ->editColumn('paid', function ($production) {
                    return $production->paid ? ($production->symbol . $production->paid) : '';
                })
                ->editColumn('type', function ($production) {
                    if ($production->type) {
                        $type = $production->type === 'in' ? 'internal' : $production->type;
                        $type = $type === 'ex' ? 'external' : $production->type;
                        return __('administrator.' . $type);
                    }
                })
                ->editColumn('done', function ($production) {
                    if ($production->done) {
                        return '<span class="label label-success">' . __('administrator.done') . '</span>';
                    }
                })
                ->addColumn('cost_per_item', function ($production) {
                    return $production->symbol . ($production->cost_per_item);
                })
                ->addColumn('return_qty', function ($production) {
                    $production_done = ProductionDoneModel::where('production_id', $production->id)->pluck('id');
                    $qty = ProductionDoneDetailModel::whereIn('production_done_id', $production_done)->sum('qty');
                    return $qty;
                })
                ->addColumn('action', function ($production) {
                    if (Gate::check('Production Request Show')) {
                        $show = '<a data-id="' . $production->id . '" data-href="' . route("production-request.show", $production->id) . '" title="' . __('administrator.show') . '" class="button_info show_request">' . __('administrator.show') . '</a>';
                        $show .= '<a data-href="' . route("production-request-get-return-item-list", $production->id) . '"
                                 title="' . __('administrator.return_item') . '" class="button_primary return_item"
                                 data-return_href="' . route('production-request-get-return-item-form', $production->id) . '"
                                 data-done_href="' . route('production-request-done', $production->id) . '"
                                 data-status="' . $production->done . '"
                                >' . __('administrator.return_item') . "</a>";
                        if ($production->packing_qty < $production->return_qty) {
                            $show .= '<a  data-href="' . route("production-packing.create") . '?prdid=' . $production->id . '" title="' . __('administrator.packing') . '" class="button_success to_packing">' . __('administrator.packing') . '</a>';
                        }
                        if(!$production->packing_qty)$show .= '<a class="button_danger btn_delete" data-href="' . route('production-delete', $production->id) . '"><i class="fa fa-trash"></i></a>';

                    } else {
                        $show = '';
                    }
                    return $show;
                })
                ->addIndexColumn()
                ->rawColumns(['action', 'total', 'return_qty', 'done'])
                ->make(true);
        }
        $user = ProductionRequestModel::groupBy('user_id')->pluck('user_id');
        $user = User::whereIn('id', $user)->pluck('name', 'id');
        $tailor_id = ProductionRequestModel::groupBy('tailor_id')->pluck('tailor_id');
        $tailor_id = TailorModel::whereIn('id', $tailor_id)->pluck('name', 'id');
        $cut_piece_warehouse = WarehouseModel::where('branch_id', Auth::user()->branch_id)->where('warehouse_type', 'cut_piece')->pluck('warehouse_name', 'id');
        $material_warehouse = WarehouseModel::where('branch_id', Auth::user()->branch_id)->where('warehouse_type', 'material')->pluck('warehouse_name', 'id');
        return view('administrator.production-request.index', compact('user', 'tailor_id', 'cut_piece_warehouse', 'material_warehouse'));
    }

    public function create(Request $request)
    {
        if ($request->ajax()) {
            $barcode = $request['barcode'];
            $check = checkProductExist($barcode);
            return response()->json($check ? 1 : 0);
        }
        $cutting_id = $request['cutting_id'] ? decrypt($request['cutting_id']) : '';
        $cutting = CuttingModel::find($cutting_id);
        $detail = CuttingDetailModel::where(['cutting_id' => $cutting_id])->where('type', 'cut_piece')->get();
        $template = ProductionTemplateModel::pluck('name', 'id');
        return view('administrator.production-request.create', compact('template', 'detail', 'cutting'));
    }

    public function store(Request $request)
    {
        $tailor_type = $request['tailor_type'];
        $this->validate($request, [
            'invoice_number' => 'required',
            'tailor_type' => 'required',
            'tailor_id' => 'required',
            'cutting_id' => 'required',

            'detail_id' => 'required',
            'detail_id.*' => 'required',
            'c_qty.*' => 'required',
            'cost.*' => 'required',
            'currency_id.*' => 'required',
        ]);
        $tailor = $request->tailor_id;
        $warehouse_id = WarehouseModel::where(['tailor_id' => $tailor, 'warehouse_type' => 'tailor'])->first();
        $warehouse_id = $warehouse_id->id ?? '';

        $c_qty = $request['c_qty'];
        $total_piece = array_sum($c_qty);
        $detail_id = $request['detail_id'];
        $sewing_price = $request['sewing_price'];
        $template_id = $request['template_id'];

        $cutting_id = $request->cutting_id ? decrypt($request->cutting_id) : 0;
        $cutting = CuttingModel::find($cutting_id);
        $tailor_cutting = findWarehouse($cutting->from_warehouse)->tailor_id ?? 0;

        $check_qty = array_sum($c_qty);
        if (!$check_qty) {
            throw ValidationException::withMessages(['no' => 'សូមបញ្ចូលចំនួន']);
        }

        $arr_qty = [];
        $arr_check = [];
        if (!(int)$request['checked_item']) {
            foreach ($template_id as $key => $tp_id) {
                $template_detail = ProductionTemplateDetailModel::where(['template_id' => $tp_id, 'type' => 'material'])->get();
                if ($template_detail) {
                    foreach ($template_detail as $row) {
                        $product_unit = ProductUnitModel::where(['product_id' => $row->material_id, 'unit_id' => $row->unit_id])->first();
                        $arr_qty[$row->material_id] = ($arr_qty[$row->material_id] ?? 0) + ($c_qty[$key] * (($product_unit->qty_per_unit ?? 1) * $row->qty));
                    }

                    foreach ($arr_qty as $p_id => $qty) {
                        $stock = StockModel::where(['product_id' => $p_id, 'warehouse_id' => $warehouse_id, 'type' => 'material'])->first();
                        $product = getProductById($p_id)->product_name ?? '';
                        if ($stock) {
                            if ($stock->stock_qty < $qty) {
                                $arr_check[$p_id] = $product . ' មិនមានគ្រប់ចនួន។';
                            }
                        } else {
                            $arr_check[$p_id] = $product . ' មិនមានក្នុងឃ្លាំង។';
                        }
                    }
                }
            }
            if (count($arr_check) > 0) {
                return response()->json(['alert' => $arr_check, 'checked_item' => 1]);
            }
        }


        $production = new ProductionRequestModel();
        $production->invoice_number = $request['invoice_number'];
        $production->cutting_id = $cutting->id;
        $production->user_id = Auth::user()->id;
        $production->tailor_id = $request->tailor_id;
        $production->type = $tailor_type;
        $production->material_warehouse = $warehouse_id;
        $production->year = date('Y');
        $production->status = 0;
        $production->currency_id = 1;
        $production->date = date('Y-m-d');
        $production->total_item = $total_piece;
        $production->rate = getRate();
        $production->rate_baht = getRate(1);
        $production->save();


        foreach ($detail_id as $key => $value) {
            $qty = $c_qty[$key];
            if ($qty) {
                $cutting_detail = CuttingDetailModel::find($value);
                $cutting_detail->remain_qty -= $qty;
                $cutting_detail->update();

                $con_tsp = [
                    'model'=>get_class($cutting),
                    'model_id'=>$cutting->id,
                    'tailor_id' => $tailor_cutting,
                    'type' => 'cutting',
                    'product_id' => $cutting_detail->code_of_pant,
                    'barcode' => $cutting_detail->barcode,
                    'price' => $cutting_detail->cutting_price,
                    'currency_id' => 1,
                ];
                $old_tsp = TailorStockPaymentModel::where($con_tsp)->first()->stock_qty ?? 0;
                TailorStockPaymentModel::updateOrCreate($con_tsp, array_merge($con_tsp, ['stock_qty' => ($old_tsp + $qty)]));


                $add_item = new ProductionRequestDetailModel();
                $add_item->production_id = $production->id;
                $add_item->type = 'item';
                $add_item->product_id = $cutting_detail->code_of_pant;
                $add_item->barcode = $cutting_detail->barcode;
                $add_item->size_code = $cutting_detail->size_code;
                $add_item->color_code = $cutting_detail->color_code;
                $add_item->qty = $qty;
                $add_item->template_qty = 1;
                $add_item->template_id = $template_id[$key];
                $add_item->cutting_price = $cutting_detail->cutting_price;
                $add_item->sewing_price = $sewing_price[$key];
                $add_item->currency_id = 1;
                $add_item->save();
            }
            if (!(int)$request['checked_item']) {
                $template_detail = ProductionTemplateDetailModel::where(['template_id' => $template_id[$key], 'type' => 'material'])->get();
                if ($template_detail) {
                    foreach ($template_detail as $row) {
                        $product_unit = ProductUnitModel::where(['product_id' => $row->material_id, 'unit_id' => $row->unit_id])->first();
                        $cm_qty = $qty * (($product_unit->qty_per_unit ?? 1) * $row->qty);
                        $stock = StockModel::where(['product_id' => $row->material_id, 'warehouse_id' => $warehouse_id, 'type' => 'material'])->first();
                        if ($stock) {
                            $stock->stock_qty -= $cm_qty;
                            $stock->save();
                        }
                    }
                }
            }
        }
        $remain = CuttingDetailModel::where('cutting_id', $cutting->id)->where('type', 'cut_piece')->sum('remain_qty');
        if ($remain === 0) {
            $cutting->done_production = 1;
            $cutting->update();
        }
        return response()->json(['status' => 'success', 'route' => route('production-request.index')]);
    }

    public function show($id, Request $request)
    {
        $production = ProductionRequestModel::find($id);
        $dproduct = ProductionRequestDetailModel::where(['production_id' => $id, 'type' => 'item'])->get();
        $view = view('administrator.production-request.show', compact('production', 'dproduct'))->render();
        if ($request['htmlonly']) {
            return $view;
        }
        return response()->json(['html' => $view, 'status' => $production->status, 'done_status' => $production->done_status]);
    }

    public function gen_template(Request $request)
    {
        $template_id = $request['template_id'];
        $template = ProductionTemplateModel::find($template_id);
        $sewing_price = $template->sewing_price;
        $template_detail = ProductionTemplateDetailModel::where('template_id', $template_id)->orderBy('material_id', 'ASC')->get();
        foreach ($template_detail as $key => $row) {
            $unit = findUnit($row->unit_id);
            $pro = getProductById($row->material_id);
            $cur = findCurrency(1);
            $row->material = $pro->product_name ?? 'Cut Piece';
            $row->unit = $unit->unit ?? 'Piece';
            $row->currency = $cur->symbol;
            $row->total = $row->qty * $row->price;
        }
        return response()->json(['detail' => $template_detail, 'sewing_price' => $sewing_price]);
    }

    public function get_return_item_list($id)
    {
        $production = ProductionRequestModel::find($id);
        $production_done = ProductionDoneModel::where('production_id', $id)->latest()->get();
        return view('administrator.production-request.return-item-list', compact('production_done', 'production'));
    }

    public function get_return_item_form(Request $request, $id)
    {
        $master = ProductionRequestModel::find($id);

        $detail = ProductionRequestDetailModel::where('production_id', $id)->where('type', 'item')->get();
        if ($request->method() === 'POST') {
            if (!array_sum($request['return_item_qty'])) {
                throw ValidationException::withMessages(['field_name' => 'No Item Return']);
            }
            $this->validate($request, [
//                'export_to'=>'required',
            ]);
            $data = $request->all();
            $data['currency_id'] = 1;
            $data['production_id'] = $id;
            $data['year'] = date('Y');
            $data['invoice_number'] = generate_inv('nso007_production_done', 'PRT');
            $data['date'] = date('Y-m-d');
            $data['user_id'] = Auth::user()->id;
            $done = ProductionDoneModel::create($data);

            foreach ($request['detail_id'] as $key => $row) {
                $detail = ProductionRequestDetailModel::find($row);
                $detail->return_qty += $request['return_item_qty'][$key];
                $detail->update();
                if ($request['return_item_qty'][$key]) {
                    $done_detail = new ProductionDoneDetailModel();
                    $done_detail->production_done_id = $done->id;
                    $done_detail->barcode = $detail->barcode;
                    $done_detail->qty = $request['return_item_qty'][$key];
                    $done_detail->save();

                    $con_tsp = [
                        'model'=>get_class($master),
                        'model_id'=>$master->id,
                        'tailor_id' => $master->tailor_id,
                        'type' => 'sewing',
                        'product_id' => $detail->product_id,
                        'barcode' => $detail->barcode,
                        'price' => $detail->sewing_price,
                        'currency_id' => 1,
                    ];
                    $old_tsp = TailorStockPaymentModel::where($con_tsp)->first()->stock_qty ?? 0;
                    TailorStockPaymentModel::updateOrCreate($con_tsp, array_merge($con_tsp, ['stock_qty' => ($old_tsp + $done_detail->qty)]));
                }
            }

            $master->return_qty += array_sum($request['return_item_qty']);
            $master->update();
            return response()->json(['status' => 'ok']);
        }
        return view('administrator.production-request.return-item-form', compact('detail', 'master'));
    }

    public function view_done($id)
    {
        $master = ProductionDoneModel::find($id);
        $detail = ProductionDoneDetailModel::where('production_done_id', $id)->get();
        return view('administrator.production-request.view-production-done', compact('master', 'detail'));
    }

    public function done($id)
    {
        $production = ProductionRequestModel::find($id);
        $production->done = 1;
        $production->update();
        return response()->json('ok');
    }

    public function getCutPieceStock(Request $request)
    {
        $tailor = $request->tailor_id;
        $warehouse = WarehouseModel::where(['tailor_id' => $tailor, 'warehouse_type' => 'tailor'])->first();
        if ($warehouse) {
            return StockModel::where('warehouse_id', $warehouse->id)->whereIn('barcode', $request['c_barcode'])->pluck('stock_qty', 'barcode');
        } else {
            return [];
        }
    }

    public function add_more(Request $request)
    {
        if ($request->getSewingPrice) {
            $data = $request->all();
            unset($data['getSewingPrice']);
            $template = \App\Model\production\ProductionTemplateModel::where($data)->selectRaw('sewing_price,id,currency_id,id')->first();
            $currency = $template ? findCurrency(1) : user_currency();
            if ($template) {
                $template->cur = $currency->symbol ?? '';
            }
            return response()->json($template);
        }
        if ($request->method() === 'POST') {
            $this->validate($request, [
                'invoice_number' => 'required',
                'tailor_id' => 'required',
                'product_id' => 'required',
                'product_id.*' => 'required',
                'size_code.*' => 'required',
                'color_code.*' => 'required',
                'qty.*' => 'required',
                'sewing_price.*' => 'required',
            ]);
            $tailor = findTailor($request->tailor_id);

            $production = new ProductionRequestModel();
            $production->invoice_number = $request['invoice_number'];
            $production->user_id = Auth::user()->id;
            $production->year = date('Y');
            $production->tailor_id = $request->tailor_id;
            $production->type = $tailor->type;
            $production->year = date('Y');
            $production->status = 0;
            $production->currency_id = 1;
            $production->date = date('Y-m-d');
            $production->total_item = array_sum($request->qty);
            $production->rate = getRate();
            $production->save();

            foreach ($request->product_id as $key => $value) {
                $size = $request->size_code[$key];
                $color = $request->color_code[$key];
                $template_id = $request->template_id[$key];

                $where = ['product_id' => $value, 'color_code' => $color, 'size_code' => $size];
                $production_unit = ProductUnitModel::where($where)->first();

                $add_item = new ProductionRequestDetailModel();
                $add_item->production_id = $production->id;
                $add_item->type = 'item';
                $add_item->product_id = $value;
                $add_item->barcode = $production_unit->barcode;
                $add_item->size_code = $size;
                $add_item->color_code = $color;
                $add_item->qty = $request->qty[$key];
                $add_item->sewing_price = $request->sewing_price[$key];
                $add_item->currency_id = 1;
                $add_item->template_id = $template_id;
                $add_item->template_qty = 1;
                $add_item->save();

            }
            return response()->json(['status' => 'success', 'route' => route('production-request.index')]);
        }
        return view('administrator.production-request.add-more-production');
    }

    public function destroy($id)
    {
        $production = ProductionRequestModel::find($id);
        $production_done = ProductionDoneModel::where('production_id', $id)->pluck('id');
        foreach ($production_done as $item) {
            ProductionDoneDetailModel::where('production_done_id', $item)->delete();
        }
        $cutting = CuttingModel::find($production->cutting_id);
        $cutting_detail = CuttingDetailModel::where('cutting_id', $production->cutting_id)->get();
        foreach ($cutting_detail as $item) {
            if ($item->type === 'fabric') {
                $cut_qty = ($item->qty * $item->qty_per_unit);

                $stock = StockModel::where([
                    'warehouse_id' => $cutting->from_warehouse,
                    'barcode' => $item->barcode,
                    'type' => 'fabric',
                ])
                    ->whereBetween('qty_per_unit',[$item->qty_per_unit-0.01,$item->qty_per_unit+0.01])
                    ->first();
                if ($stock) {
                    $stock->stock_qty += $cut_qty;
                    $stock->save();
                }
            }
        }
        $payment = PaymentModel::where(['invoice_id' => $id, 'type' => 'production'])->first();


        PaymentDetailModel::where(['payment_id' => $payment->id ?? 'arigato'])->delete();
        PaymentModel::where(['invoice_id' => $id, 'type' => 'production'])->delete();
        ProductionRequestDetailModel::where('production_id', $id)->delete();
        ProductionRequestModel::where('id', $id)->delete();
        ProductionDoneModel::where('production_id', $id)->delete();
        CuttingDetailModel::where('cutting_id', $production->cutting_id ?? 'arigato')->delete();
        CuttingModel::where('id', $production->cutting_id ?? 'arigato')->delete();
        return response()->json(['status' => 'ok']);
    }
}
