<?php

namespace App\Http\Controllers\Administrator\production;

use App\Fun\Fun;
use App\Http\Controllers\Controller;
use App\Model\production\cutting\CuttingCodeOfPantModel;
use App\Model\production\ProductionTemplateModel;
use App\Model\production\cutting\CuttingDetailModel;
use App\Model\production\cutting\CuttingModel;
use App\Model\production\cutting\CuttingPieceSizeModel;
use App\Model\product\ProductModel;
use App\Model\product\ProductUnitModel;
use App\Model\stock_inventory\StockModel;
use App\Model\setup\WarehouseModel;
use DB;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
use Yajra\DataTables\DataTables;


class ProductionCuttingController extends Controller
{

    public function __construct()
    {

    }

    public function index(Request $request)
    {
        if ($request->ajax()) {
            Fun::lang();
            $production = CuttingModel::where(['branch_id' => Auth::user()->branch_id])->orderBy('id', 'DESC');
            return DataTables::of($production->take(20))
                ->with([
                    "recordsTotal" => $production->count(),
                    "recordsFiltered" => $production->count(),
                ])
                ->addIndexColumn()
                ->editColumn('date', function ($cutting) {
                    return date('d-m-Y', strtotime($cutting->date));
                })
                ->editColumn('tailor_id', function ($cutting) {
                    $tailor = findTailor($cutting->tailor_id);
                    return $tailor->name ?? '';
                })
                ->editColumn('done_production', function ($cutting) {
                    if ($cutting->done_production === 1) {
                        return '<span class="label label-success">' . __('administrator.done') . '</span>';
                    }
                    return '';
                })
                ->editColumn('from_warehouse', function ($cutting) {
                    $wh = findWarehouse($cutting->from_warehouse);
                    return $wh->warehouse_name ?? '';
                })
                ->editColumn('type', function ($cutting) {
                    $type = $cutting->type === 'in' ? 'internal' : 'external';
                    return __('administrator.' . $type);
                })
                ->addColumn('total_qty', function ($cutting) {
                    return CuttingDetailModel::where('cutting_id', $cutting->id)->where('type', 'cut_piece')->sum('total_qty') . ' ឯកតា';
                })
                ->addColumn('remain_qty', function ($cutting) {
                    return CuttingDetailModel::where('cutting_id', $cutting->id)->where('type', 'cut_piece')->sum('remain_qty') . ' ឯកតា';
                })
                ->addColumn('action', function ($cutting) {
                    $btn = '<a title="' . __('administrator.show') . '"
                    class="button_info btn_show"
                    data-url = "' . route("production-cutting.show", $cutting->id) . '"  >' . __('administrator.show') . '</a>';
                    if (!$cutting->done_production) {
                        $btn .= '<a title="' . __('administrator.production') . '"
                    class="button_primary"
                    href = "' . route("production-request.create") . '?cutting_id=' . (encrypt($cutting->id)) . '"  >' . __('administrator.production') . '</a>';
                    }
                    return $btn;
                })
                ->rawColumns(['action', 'done_production', 'status', 'amount', 'paid', 'due', 'payment_status', 'done_status', 'total_qty', 'remain_qty'])
                ->make(true);
        }
        $warehouse = WarehouseModel::where('branch_id', Auth::user()->branch_id)->pluck('warehouse_name', 'id');
        return view('administrator.production-cutting.index', compact('warehouse'));
    }

    public function create(Request $request)
    {
        if ($request->get_item_cutting_price) {
            $item_code = explode(',', $request->item_code);
            $item = [];
            foreach ($item_code as $row) {
                if ($row) {
                    $row = explode('::', $row);
                    $fabric_id = $row[0];
                    $product_id = $row[1];
                    $barcode = $row[2];
                    $piece_qty = $row[3];
                    $template = ProductionTemplateModel::where(['product_id' => $product_id, 'barcode' => $barcode])->first();
                    // some item done have template
                    $pro_unit = ProductUnitModel::where(['product_id' => $product_id, 'barcode' => $barcode])->first();

                    $cur = $template ? findCurrency(1) : user_currency();

                    if ($pro_unit) {
                        $color = findColor($pro_unit->color_code);
                        $size = findSize($pro_unit->size_code);
                        $item[$barcode]['piece_qty'] = $piece_qty;
                        $item[$barcode]['color'] = $color->color;
                        $item[$barcode]['color_name'] = $color->name;
                        $item[$barcode]['color_code'] = $color->code;
                        $item[$barcode]['size_name'] = $size->size;
                        $item[$barcode]['size_code'] = $size->code;
                        $item[$barcode]['barcode'] = $barcode;
                        $item[$barcode]['fabric_id'] = $fabric_id;
                        $item[$barcode]['product_id'] = $product_id;
                        $item[$barcode]['cutting_price'] = $template->cutting_price ?? 0;
                        $item[$barcode]['cur'] = $cur->symbol;
                        $item[$barcode]['currency_id'] = 1;
                    }
                }
            }
            return response()->json($item);
        }
        return view('administrator.production-cutting.create');
    }

    public function find_fabric(Request $request)
    {
        $this->validate($request, [
            'from_warehouse_id' => 'required'
        ]);

        $warehouse = $request->from_warehouse_id;
        $stock_id = $request->stock_id;
        $stock = StockModel::where(['id' => $stock_id, 'type' => 'fabric', 'warehouse_id' => $warehouse])->first();
        if ($stock) {
            $product = getProductById($stock->product_id);
            $std = new \stdClass();
            $std->color = '';
            if ($product->color_code) {
                $color = findColor($product->color_code);
                $name = $color->name ?? '';
                $color = $color->color ?? 'transparent';
                $std->color = "<i class='fa fa-stop border' style='border:1px solid rgba(1,1,1,0.4);color: $color'></i> $name";
            }


            $std->color_code = $product->color_code;
            $std->name = $product->product_name;
            $std->product_id = $product->id;
            $std->unit = findUnit($product->unit_id)->unit;
            $std->child_unit = findUnit($product->child_unit)->unit;
            $std->barcode = $stock->barcode;
            $std->qty_per_unit = $stock->qty_per_unit;
            $std->stock_qty = $stock->stock_qty;
            $std->id = $stock->id;
            return response()->json($std);
        } else {
            $stock_id = ($stock_id == 'search' ? null : $stock_id);
            $stock = StockModel::join('nso007_products', 'nso007_products.id', 'nso007_stocks.product_id')
                ->join('nso007_unit', 'nso007_products.child_unit', 'nso007_unit.id')
                ->where(['nso007_stocks.type' => 'fabric', 'nso007_stocks.warehouse_id' => $warehouse])
                ->HAVING('stock_convert', '>', 0)
                ->where(function ($q) use ($stock_id) {
                    if ($stock_id) {
                        $q->where('nso007_products.product_name', 'like', "%$stock_id%");
                        $q->orwhere('nso007_stocks.barcode', 'like', "%$stock_id%");
                    }
                })
                ->selectRaw('CONCAT(nso007_products.product_name," (",nso007_stocks.barcode,")") as name,
                nso007_stocks.qty_per_unit,nso007_stocks.id,nso007_stocks.stock_qty,nso007_products.color_code,nso007_unit.unit,
            nso007_stocks.stock_qty,ROUND(nso007_stocks.stock_qty/nso007_stocks.qty_per_unit,2) as stock_convert')
                ->orderBy('nso007_stocks.barcode', 'ASC')
                ->limit(100)
                ->get()
                ->map(function ($row) {
                    $row->color = '';
                    if ($row->color_code) {
                        $color = findColor($row->color_code);
                        $name = $color->name ?? '';
                        $color = $color->color ?? 'transparent';
                        $row->color = "<i class='fa fa-stop border' style='border:1px solid rgba(1,1,1,0.4);color: $color'></i> $name";
                    }
                    return $row;
                });
            return response()->json(['status' => 'search', 'data' => $stock]);
        }
    }

    public function store(Request $request)
    {
        $this->validate($request, [
            'date' => 'required|max:15',
            'from_warehouse_id' => 'required',
            'invoice_number' => 'required|max:30',
            'f_stock_id' => 'required',
            ['f_stock_id.required' => 'The Fabric Field is required'],
            'f_stock_id.*' => 'required',
            'f_product_id' => 'required',
            'f_product_id.*' => 'required',
            'f_qty' => 'required',
            'f_qty.*' => 'required',
            'size_id.*' => 'required',
            'c_product_id' => 'required',
            'c_product_id.*' => 'required',
            'c_size_cutpiece' => 'required',
            'c_size_cutpiece.*' => 'required',
            'c_qty_cutpiece' => 'required',
            'c_qty_cutpiece.*' => 'required',
            'c_cutting_currency_id.*' => 'required',
            'c_cutting_price.*' => 'required',
        ]);
        $f_stock_id = $request->f_stock_id;
        $c_product_id = $request->c_product_id;
        $message = [];
        $check_row = 0;
        $warehouse_id = $request->from_warehouse_id;
        if ($warehouse_id) {
            foreach ($f_stock_id as $key => $row) {
                // check if all product has enough stock
                $stock = StockModel::where(['id' => $row])->first();
                $cut_qty = ($request->f_qty[$key] * $request->f_qty_per_unit[$key]);
                if ($stock) {
                    if ($stock->stock_qty >= $cut_qty) {
                        $check_row++;
                    } else {
                        $message[$key] = "id $row is not enough quantity.";
                    }
                } else {
                    $message[$key] = "Fabric $row is not found.";
                }
            }

            if (count($message) > 0) {
                throw ValidationException::withMessages($message);
            }

            if (count($message) == 0) {
                $cutting = new CuttingModel();
                $cutting->date = date('Y-m-d', strtotime($request->date));
                $cutting->year = date('Y');
                $cutting->user_id = Auth::user()->id;
                $cutting->branch_id = Auth::user()->branch_id;
                $cutting->from_warehouse = $warehouse_id;
                $cutting->to_warehouse = 0;
                $cutting->invoice_number = $request->invoice_number;
                $cutting->description = $request->description;
                $cutting->total_template = $request->total_template;
                $cutting->cash_advance = $request->t_cash_advance_baht;
                $cutting->amount_to_pay = $request->t_amount_to_pay;
                $cutting->cost_per_piece = $request->cost_per_piece;
                $cutting->status = 1;
                $cutting->save();
                foreach ($f_stock_id as $key => $row) {
                    $stock = StockModel::find($row);

                    $detail = new CuttingDetailModel();
                    $detail->type = 'fabric';
                    $detail->cutting_id = $cutting->id;
                    $detail->fabric_id = $stock->product_id ?? '';
                    $detail->barcode = $stock->barcode ?? '';
                    $detail->qty = $request->f_qty[$key];
                    $detail->qty_per_unit = $stock->qty_per_unit ?? 1;
                    $detail->save();

                    $code_of_pant = $request["code_of_pant$detail->fabric_id"];
                    if ($code_of_pant) {
                        foreach ($code_of_pant as $item) {
                            CuttingCodeOfPantModel::create([
                                'detail_id' => $detail->id,
                                'code_of_pant_id' => $item
                            ]);
                        }
                    }

                    $cut_qty = ($request->f_qty[$key] * $request->f_qty_per_unit[$key]);

                    if ($stock) {
                        if ($stock->stock_qty >= $cut_qty) {
                            $stock->stock_qty -= $cut_qty;
                            $stock->update();
                        }
                    }
                }

                foreach ($c_product_id as $key => $row) {
                    $code = $request->c_product_code[$key];
                    $detail = new CuttingDetailModel();
                    $detail->type = 'cut_piece';
                    $detail->cutting_id = $cutting->id;
                    $detail->fabric_id = $request->c_fabric_id[$key];
                    $detail->size_code = $request->c_size_cutpiece[$key];
                    $detail->color_code = $request->c_color_cutpiece[$key];
                    $detail->size_qty = 1;
                    $detail->barcode = $code;
                    $detail->qty = $request->c_qty_cutpiece[$key];
                    $detail->total_qty = $request->c_qty_cutpiece[$key];
                    $detail->currency_id = 1;
                    $detail->cutting_price = $request->c_cutting_price[$key];
                    $detail->remain_qty = $detail->total_qty;
                    $detail->code_of_pant = $row;
                    $detail->save();
                    $product = getProductById($row);
                    $cut_piece = ProductModel::where('barcode', $code)->first();
                    if (!$cut_piece) {
                        $cut_piece = new ProductModel();
                        $cut_piece->type = 'cut_piece';
                        $cut_piece->barcode = $code;
                        $cut_piece->fabric_id = $row;
                        $cut_piece->product_name = $product->product_name;
                        $cut_piece->status = 1;
                        $cut_piece->save();
                    }
                    $pro_unit = ProductUnitModel::where(['product_id' => $cut_piece->id, 'barcode' => $code])->first();
                    if (!$pro_unit) {
                        $type = ProductUnitModel::where(['product_id' => $cut_piece->id, 'barcode' => $code, 'type' => 'parent'])->first();
                        if ($type) {
                            $type = 'child';
                        } else {
                            $type = 'parent';
                        }
                        $pro_unit = new ProductUnitModel();
                        $pro_unit->size_code = $request->c_size_cutpiece[$key];
                        $pro_unit->color_code = $request->c_color_cutpiece[$key];
                        $pro_unit->qty_per_unit = 1;
                        $pro_unit->product_id = $cut_piece->id;
                        $pro_unit->barcode = $code;
                        $pro_unit->type = $type;
                        $pro_unit->save();

                    }
                }
            }
            session()->put('success', 'Production Cutting created successfully');
            return response()->json(['status' => 'success', 'route' => route('production-cutting.index')]);
        } else {
            if (!$warehouse_id) {
                throw ValidationException::withMessages(['one' => 'Invalid Warehouse']);
            } else {
                throw ValidationException::withMessages(['three' => 'Something Wrong']);
            }
        }
    }

    public function show($id)
    {
        $cutting = CuttingModel::find($id);
        $detail = CuttingDetailModel::where(['cutting_id' => $id])->where('type', 'cut_piece')->get();
        $fabric_detail = CuttingDetailModel::
        select('nso007_production_cutting_detail.*')
            ->where(['nso007_production_cutting_detail.cutting_id' => $id])
            ->where('nso007_production_cutting_detail.type', 'fabric')
            ->get();
        $cutting_size = CuttingPieceSizeModel::where('cutting_id', $id)->get();
        $show = 0;
        if ($cutting->status == 1) {
            if ($cutting->done_status == 0) {
                $show = 1;
            }
        }
        $html = view('administrator.production-cutting.show', compact('detail', 'cutting_size', 'cutting', 'fabric_detail'))->render();
        return response()->json(['html' => $html, 'status' => $cutting->status, 'id' => $id, 'show' => $show]);
    }
}
