<?php

namespace App\Http\Controllers\pos;

use App\Fun\Fun;
use App\Model\account\JournalModel;
use App\Model\payment\CashInOutModel;
use App\Model\payment\PaymentDetailModel;
use App\Model\payment\PaymentModel;
use App\Model\product\ProductUnitModel;
use App\Model\sale\SaleDetailHistoryModel;
use App\Model\sale\SaleHistoryModel;
use App\Model\pos\SaleDetailsModel;
use App\Model\pos\SaleModel;
use App\Model\stock_inventory\StockModel;
use App\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use DB;
use Auth;
use Illuminate\Validation\ValidationException;
use Yajra\DataTables\DataTables;

class AllSaleListController extends Controller
{
    function __construct()

    {
        // $this->middleware('permission:Purchase', ['only' => ['show', 'create', 'store']]);
    }

    public function index(Request $request)
    {
        if ($request->ajax()) {
            Fun::lang();
            $type = last(request()->segments());
            $fdate = $request->from_date;
            $tdate = $request->to_date;
            $customer = $request->customer;
            $user = $request->user_id;
            $data = SaleModel::select('nso007_sales.*', 'users.name as user_name')
                ->join('users', 'users.id', 'nso007_sales.user_id')
                ->where('nso007_sales.status', '!=', 5)
                ->where(function ($q) use ($type) {
                    if ($type === 'sale-invoice') {
                        $q->where('payment_status', '!=', 'paid');
                    }
                    if ($type === 'sale-receipt') {
                        $q->where('payment_status', '=', 'paid');
                    }
                })
                ->where(function ($q) use ($fdate) {
                    $mybr = myBranch();
                    if (!auth()->user()->can('View Sale Request All Branch')) {
                        $q->where('nso007_sales.user_id', auth()->id());
                    }
                    if (!$mybr->main) {
                        $q->where('nso007_sales.branch_id', $mybr->id);
                    }
                })
                ->where(function ($q) use ($fdate) {
                    if ($fdate) {
                        $q->whereDate('nso007_sales.sale_date', '>=', sDate($fdate));
                    }
                })
                ->where(function ($q) use ($tdate) {
                    if ($tdate) {
                        $q->whereDate('nso007_sales.sale_date', '<=', sDate($tdate));
                    }
                })
                ->where(function ($q) use ($user) {
                    if ($user) {
                        $q->where('nso007_sales.user_id', $user);
                    }
                })
                ->where(function ($q) use ($customer) {
                    if ($customer) {
                        $q->where('nso007_sales.customer_id', $customer);
                    }
                })
                ->orderBy('id', 'DESC');
            return DataTables::of($data)
                ->addColumn('customer_phone', function ($data) {
                    return $data->customer->phone ?? '';
                })
                ->addColumn('customer_id', function ($data) {
                    return $data->customer->name ?? '';
                })
                ->editColumn('user_id', function ($data) {
                    return $data->user_name;
                })
                ->editColumn('paid_amount', function ($data) {
                    $data->symbol = findCurrency($data->currency_id)->symbol ?? '';
                    return $data->symbol . number_format($data->paid_amount, 2);
                })
                ->editColumn('total', function ($data) {
                    return $data->symbol . number_format($data->grand_total, 2);
                })
                ->editColumn('owed', function ($data) {
                    $data->owed = $data->grand_total - $data->paid_amount;

                    if ($data->owed > 0)
                        return $data->symbol . number_format($data->owed, 2);
                })
                ->editColumn('change_amount', function ($data) {
                    $change = abs($data->owed);

                    if ($change)
                        return $data->symbol . number_format($change, 2);
                })
                ->editColumn('payment_status', function ($data) {
                    return checkPaymentStatus($data->payment_status);
                })
                ->editColumn('status', function ($data) {
                    if ($data->is_role == 'out_shop') {
                        return checkRequestStatus($data->status);
                    }
                })
                ->editColumn('sale_date', function ($data) {
                    return myDate($data->sale_date);
                })
                ->editColumn('sale_type', function ($data) {
                    return __('administrator.' . $data->sale_type);
                })
                ->editColumn('discount', function ($data) {
                    return $data->symbol . number_format($data->discount, 2);
                })
                ->editColumn('delivery_fee_amt', function ($data) {
                    if ($data->delivery_fee)
                        return $data->symbol . number_format($data->delivery_fee, 2) . ($data->delivery_fee_by ? (' - ' . getFeeBy($data->delivery_fee_by)) : '');
                })
                ->addColumn('action', function ($data) use ($type) {
                    $btn = '<a  class="button_info getHtmlFormShow"  data-width="900px" data-href="' . route("get-wholesale-invoice", $data->id) . '">' . __('administrator.show') . ' (A4)</a>';
                    if (auth()->id() == 1) {
                        $btn .= '<a  class="button_danger delete_sale" data-text="' . $data->invoice_number . '" data-href="' . route("sale-history.destroy", $data->id) . '">' . __('administrator.delete') . '</a>';
                    }
//                    $btn .= '<a  class="button_primary getHtmlFormShow"data-href="' . route("pos-invoice", $data->id) . '">' . __('administrator.show') . ' (80mm)</a>';
                    if ($data->status == 1 && $data->delivery_status !== 4 && $type === 'sale-history') {
                        if (myBranch()->main == 'arigato') {
                            $btn .= '<a  class="button_warning show_edit" data-href="' . route('sale-edit-history.index', $data->id) . '" data-edit="' . route('sale-history.edit', $data->id) . '" ><span class="fa fa-edit"></span></a>';
                        }
                    }
                    return $btn;
                })
                ->addIndexColumn()
                ->rawColumns(['status', 'action', 'total', 'customer_phone', 'customer_id', 'payment_status'])
                ->make(true);
        }
        $user = User::where(function ($q) {
            $myBranch = myBranch();
            if (!$myBranch->main) {
                $q->where('branch_id', $myBranch->id);
            }
        })->pluck('name', 'id');
        return view('pos.all-sale-list.sale-history', compact('user'));
    }

    public function get_edit_history($sale_id)
    {
        $history = SaleHistoryModel::where('sale_id', $sale_id)->get();
        return view('pos.all-sale-list.sale-edit-history', compact('history'))->render();
    }

    public function edit(Request $request, $id)
    {
        $sale = findSale($id);
        $stock_item = StockModel::where(['warehouse_id' => (getMainWarehouse('item') ? getMainWarehouse('item')->id : 0), 'type' => 'product'])
            ->where('stock_qty', '>', 0)
            ->paginate(20);
        if ($request->ajax()) {
            $html = view('pos.clothes-pos.result-create', compact('stock_item'))->render();
            return response()->json(['html' => $html]);
        }
        return view('pos.all-sale-list.edit', compact('stock_item', 'sale'));
    }

    public function update(Request $request, $id)
    {
        $this->validate($request, [
            'product_unit' => 'required',
            'product_unit.*' => 'required',
            'dis.*' => 'required',
            'qty.*' => 'required',
            'retail_price' => 'required',
            'qty' => 'required',
            'customer' => 'required',
            'date' => 'required',
        ]);
        return DB::transaction(function () use ($request, $id) {
            DB::beginTransaction();
            try {
                $pos_clothes = findSale($id);
                $ifedit = $pos_clothes->edited_by;
                $product_unit_id = $request->product_unit;
                $qty = $request->qty;
                $price = $request->retail_price;
                $discount = $request->dis;
                $detail_id = $request->sale_detail;
                $additional_charge = $request->additional_charge;
                $refund = $request->refund_amount;
                $refund = $refund ? $refund : 0;
                $additional_charge = $additional_charge ? $additional_charge : 0;
                if ($additional_charge && $refund) {
                    throw ValidationException::withMessages(['field_name' => 'Invalid Refund and Additional Charge']);
                }
                $sale_detail = getSaleDetail($id);
                $not_sale = SaleDetailsModel::whereNotIn('id', $detail_id)->where('sale_id', $id)->get();
                $total_refund = 0;
                foreach ($not_sale as $row) {
                    $find_detail = SaleDetailsModel::find($row->id);
                    $total_refund += $find_detail->sale_price * $find_detail->qty;
                    $stock = StockModel::updateOrCreate(array(
                        'product_id' => $row->product_id,
                        'barcode' => $row->barcode,
                        'type' => 'product',
                        'warehouse_id' => $pos_clothes->warehouse_id
                    ));
                    $stock->stock_qty += $find_detail->qty;
                    $stock->save();
                }
                $sale_detail_id = SaleDetailsModel::whereNotIn('id', $detail_id)->where('sale_id', $id)->pluck('id');
                foreach ($detail_id as $key => $row) {
                    $find_detail = SaleDetailsModel::find($row);
                    if ($find_detail) {
                        $stock = StockModel::updateOrCreate(array(
                            'product_id' => $find_detail->product_id,
                            'barcode' => $find_detail->barcode,
                            'type' => 'product',
                            'warehouse_id' => $pos_clothes->warehouse_id
                        ));
                        if ($qty[$key] > $find_detail->qty) {
                            $stock->stock_qty -= ($qty[$key] - $find_detail->qty);
                            $stock->save();
                        }
                        if ($find_detail->qty > $qty[$key]) {
                            $stock->stock_qty += ($find_detail->qty - $qty[$key]);
                            $stock->save();
                        }
                        $find_detail->sale_price = $price[$key];
                        $find_detail->dis = @$discount[$key];
                        $find_detail->qty = $qty[$key];
                        $find_detail->update();

                    } else {
                        $product_unit = ProductUnitModel::find($product_unit_id[$key]);
                        SaleDetailsModel::insert(
                            [
                                'sale_id' => $id,
                                'barcode' => $product_unit->barcode,
                                'product_id' => $product_unit->product_id,
                                'qty' => $qty[$key],
                                'sale_price' => $price[$key],
                                'dis' => @$discount[$key],
                                'unit_id' => $product_unit->unit_id,
                                'size_code' => $product_unit->size_code,
                                'color_code' => $product_unit->color_code,
                                'created_at' => date('Y-m-d H:i:s'),
                                'updated_at' => date('Y-m-d H:i:s'),
                            ]
                        );
                        $stock = StockModel::updateOrCreate(array(
                            'product_id' => $product_unit->product_id,
                            'barcode' => $product_unit->barcode,
                            'type' => 'product',
                            'warehouse_id' => $pos_clothes->warehouse_id
                        ));
                        if ($qty[$key]) {
                            $stock->type = 'product';
                            $stock->product_id = $pos_clothes->product_id;
                            $stock->barcode = $pos_clothes->barcode;
                            $stock->warehouse_id = $pos_clothes->warehouse_id;
                            $stock->size_code = $product_unit->size_code;
                            $stock->color_code = $product_unit->color_code;
                            $stock->stock_qty -= ($qty[$key]);
                            $stock->save();
                        }
                    }
                }

                SaleDetailsModel::whereIn('id', $sale_detail_id)->delete();
                $history_id = DB::table('nso007_sales_history')->insertGetId([
                    'edited_by' => $pos_clothes->edited_by ? $pos_clothes->edited_by : Auth::user()->id,
                    'edited_at' => $pos_clothes->edited_at ? $pos_clothes->edited_at : date('Y-m-d H:i:s'),
                    'sale_id' => $pos_clothes->id,
                    'user_id' => $pos_clothes->user_id,
                    'is_role' => $pos_clothes->is_role,
                    'branch_id' => $pos_clothes->branch_id,
                    'customer_id' => $pos_clothes->customer_id,
                    'payment_status' => $pos_clothes->payment_status,
                    'invoice_number' => $pos_clothes->invoice_number,
                    'sale_date' => $pos_clothes->sale_date,
                    'year' => $pos_clothes->year,
                    'rate' => $pos_clothes->rate,
                    'sale_type' => $pos_clothes->sale_type,
                    'paid_amount' => $pos_clothes->paid_amount,
                    'additional_charge' => $pos_clothes->additional_charge,
                    'currency_id' => $pos_clothes->currency_id,
                    'discount' => $pos_clothes->discount,
                    'warehouse_id' => $pos_clothes->warehouse_id,
                    'daily_order_number' => $pos_clothes->daily_order_number,
                    'refund_amount' => $pos_clothes->refund_amount,
                    'refund_reason' => $pos_clothes->refund_reason,
                    'refund_status' => $pos_clothes->refund_status,

                    'driver_id' => $pos_clothes->driver_id,
                    'request_by' => $pos_clothes->request_by,
                    'status' => $pos_clothes->status,
                    'note' => $pos_clothes->note,
                    'return_status' => $pos_clothes->return_status,
                    'request_type' => $pos_clothes->request_type,
                    'seen_at' => $pos_clothes->seen_at,
                    'delivery_fee' => $pos_clothes->delivery_fee,
                    'delivery_note' => $pos_clothes->delivery_note,
                    'delivery_phone' => $pos_clothes->delivery_phone,
                    'delivery_status' => $pos_clothes->delivery_status,
                    'done_date' => $pos_clothes->done_date,

                    'payment_method_id' => $request->payment_method_id,
                    'reference_file' => $pos_clothes->reference_file,
                    'delivery_fee_by' => $request->delivery_fee_by,
                ]);
                if ($pos_clothes->reference_file) {
                    $filee = str_replace('/', '\\', $pos_clothes->reference_file);
                    $dest = str_replace('reference_file', 'history', $pos_clothes->reference_file);
                    \File::copy($filee, $dest);
                }
                if ($files = $request->file('reference_file')) {
                    $reference_file = $pos_clothes->reference_file;
                    if ($reference_file) {
                        if (file_exists(public_path() . '/' . $reference_file)) {
                            unlink(public_path() . '/' . $reference_file);
                        }
                    }
                    $original_name = 'IMG' . date('ymdhis') . '.png';
                    $destinationPath = 'images/reference_file';
                    $files->move($destinationPath, $original_name);
                    $pos_clothes->reference_file = 'images/reference_file/' . $original_name;
                }
                if (($pos_clothes->paid_amount) >= $request->g_total_hidden) {
                    $payment_status = 'paid';
                } else {
                    if ($request->paid > 0) {
                        $payment_status = 'partial';
                    } else {
                        $payment_status = 'due';
                    }
                }
                $pos_clothes->edited_by = Auth::user()->id;
                $pos_clothes->edited_at = date('Y-m-d H:i:s');
                $pos_clothes->discount = $request->discount;
                $pos_clothes->customer_id = $request->customer;
                $pos_clothes->refund_amount = $refund;
                $pos_clothes->refund_reason = $request->refund_reason;
                $pos_clothes->additional_charge = $additional_charge;
                $pos_clothes->payment_method_id = $request->payment_method_id;
                $pos_clothes->delivery_fee = $request->delivery_fee;
                $pos_clothes->delivery_fee_by = $request->delivery_fee_by;
                $pos_clothes->refund_status = 1;
                $pos_clothes->payment_status = $payment_status;
                $pos_clothes->update();
                foreach ($sale_detail as $key => $value) {
                    $detail_history = array(
                        'sale_id' => $history_id,
                        'product_id' => $value->product_id,
                        'qty' => $value->qty,
                        'sale_price' => $value->sale_price,
                        'barcode' => $value->barcode,
                        'size_code' => $value->size_code,
                        'color_code' => $value->color_code,
                        'dis' => $value->dis,
                        'unit_id' => $value->unit_id,
                        'created_at' => date('Y-m-d h:i:s'),
                        'updated_at' => date('Y-m-d h:i:s'),
                    );
                    DB::table('nso007_sale_details_history')->insert($detail_history);
                }
                $sale_type = $pos_clothes->out_shop;
                if ($sale_type == 'out_shop') {
                    $sale_type = 'sale-request';
                }
                if ($pos_clothes->status == 1) {
                    $payment = PaymentModel::where(['invoice_id' => $id, 'type' => $sale_type])->first();
                    $inv = $payment ? $payment->payment_invoice : generate_inv('nso007_sales', 'POS' . Auth::user()->branch_id);
                    $date = $payment ? $payment->payment_date : date('Y-m-d');
                    $currency = $payment ? $payment->currency_id : user_currency()->id;
                    $UCpayment = PaymentModel::firstOrNew(array('invoice_id' => $id, 'type' => 'pos'));
                    $UCpayment->user_id = Auth::user()->id;
                    $UCpayment->payment_invoice = $inv;
                    $UCpayment->invoice_id = $pos_clothes->id;
                    $UCpayment->payment_date = $date;
                    //$UCpayment->payment_amount = $request->g_total_hidden;
                    $UCpayment->paid_amount = $pos_clothes->paid_amount;
                    $UCpayment->refund_amount = $refund;
                    $UCpayment->additional_charge = $additional_charge;
                    $UCpayment->currency_id = $currency;
                    $UCpayment->payment_status = $payment_status;
                    $UCpayment->customer_id = $pos_clothes->customer_id;
                    $UCpayment->year = date('Y');
                    $UCpayment->status = 1;
                    $UCpayment->type = 'pos';
                    $UCpayment->save();
                    if ($additional_charge && !$ifedit) {
                        $payment_detail = new PaymentDetailModel();
                        $payment_detail->payment_id = $UCpayment->id;
                        $payment_detail->paid_amount = $additional_charge;
                        $payment_detail->payment_date = date('Y-m-d');
                        $payment_detail->note = 'Additional Charge';
                        $payment_detail->status = 1;
                        $payment_detail->type = 'paid';
                        $payment_detail->save();
                    }
                    if ($refund && !$ifedit) {
                        $payment_detail = new PaymentDetailModel();
                        $payment_detail->payment_id = $UCpayment->id;
                        $payment_detail->paid_amount = $refund;
                        $payment_detail->payment_date = date('Y-m-d');
                        $payment_detail->note = 'Refund';
                        $payment_detail->status = 1;
                        $payment_detail->type = 'refund';
                        $payment_detail->save();
                    }
                }

                DB::commit();
                session()->put('success', 'Record was Edit successfully');
                return response()->json(['route' => route('all-sale-history.index'), 'status' => 'success']);
            } catch (\Exception $e) {
                DB::rollback();
                throw ValidationException::withMessages(['field_name' => $e->getMessage()]);
            }
        });
    }

    function view_history($id)
    {
        $master = SaleHistoryModel::find($id);
        $detail = SaleDetailHistoryModel::where('sale_id', $id)->get();
        return view('pos.all-sale-list.pos-invoice-history', compact('master', 'detail'));
    }

    public function sale_edited(Request $request)
    {
        if ($request->ajax()) {
            $fdate = $request->from_date;
            $tdate = $request->to_date;
            $customer = $request->customer;
            $user = $request->user_id;
            $count_total = SaleModel::count();
            $data = SaleModel::select('nso007_sales.*', 'users.name as user_name')
                ->join('users', 'users.id', 'nso007_sales.user_id')
                ->where('edited_at', '!=', null)
                ->where('edited_by', '!=', null)
                ->where(function ($q) use ($fdate) {
                    if ($fdate) {
                        $q->whereDate('nso007_sales.sale_date', '>=', date('Y-m-d', strtotime($fdate)));
                    }
                })
                ->where(function ($q) use ($tdate) {
                    if ($tdate) {
                        $q->whereDate('nso007_sales.sale_date', '<=', date('Y-m-d', strtotime($tdate)));
                    }
                })
                ->where(function ($q) use ($user) {
                    if ($user) {
                        $q->where('nso007_sales.user_id', $user);
                    }
                })
                ->where(function ($q) use ($customer) {
                    if ($customer) {
                        $q->where('nso007_sales.customer_id', $customer);
                    }
                })
                ->orderBy('created_at', 'DESC');
            $count_filter = $data->count();
            return DataTables::of($data->take(20))
                ->with([
                    "recordsTotal" => $count_total,
                    "recordsFiltered" => $count_filter,
                ])
                ->addColumn('customer_phone', function ($data) {
                    return $data->customer->phone;
                })
                ->editColumn('customer_id', function ($data) {
                    return $data->customer->name;
                })
                ->editColumn('user_id', function ($data) {
                    return $data->user_name;
                })
                ->editColumn('paid_amount', function ($data) {
                    $data->symbol = findCurrency($data->currency_id)->symbol ?? '';
                    return $data->symbol . number_format($data->paid_amount, 2);
                })
                ->editColumn('total', function ($data) {
                    return $data->symbol . number_format($data->grand_total, 2);
                })
                ->editColumn('owed', function ($data) {
                    $owed = $data->grand_total - $data->paid_amount;
                    return $data->symbol . number_format($owed, 2);
                })
                ->editColumn('payment_status', function ($data) {
                    return checkPaymentStatus($data->payment_status);
                })
                ->editColumn('status', function ($data) {
                    if ($data->is_role == 'out_shop') {
                        return checkRequestStatus($data->status);
                    }
                })
                ->editColumn('sale_date', function ($data) {
                    return date('d-m-Y H:i', strtotime($data->sale_date));
                })
                ->editColumn('edited_at', function ($data) {
                    return date('d-m-Y H:i', strtotime($data->edited_at));
                })
                ->editColumn('edited_by', function ($data) {
                    return findUser($data->edited_by)->name;
                })
                ->editColumn('discount', function ($data) {
                    return $data->symbol . number_format($data->discount, 2);
                })
                ->addColumn('action', function ($data) {
                    $btn = '<a  class="button_info show_invoice" data-href="' . route("get-wholesale-invoice", $data->id) . '" data-boxwidth="50%" data-print_=".print_invoice_wholesale">' . __('administrator.show') . ' (A4)</a>';
                    $btn .= '<a  class="button_warning show_edit" data-href="' . route('sale-edit-history.index', $data->id) . '" data-edit="' . route('sale-history.edit', $data->id) . '" >' . __('administrator.history') . '</a>';
                    return $btn;
                })
                ->addIndexColumn()
                ->rawColumns(['status', 'action', 'total', 'customer_id', 'payment_status', 'customer_phone',])
                ->make(true);
        }
        $user = SaleModel::groupBy('user_id')->pluck('user_id');
        $user = User::whereIn('id', $user)->pluck('name', 'id');
        return view('pos.all-sale-list.sale-edited-list', compact('user'));
    }

    public function destroy($id)
    {
        $sale = SaleModel::where(['id'=>$id,'status'=>1,'return_Status'=>0])->first();
        if (!$sale) throw_error(['gg' => 'Invoice not found']);

        JournalModel::where(['journal_referenceid' => $sale->id, 'transaction_type' => "POS $sale->sale_type"])->delete();
        $payment = PaymentModel::where(['invoice_id' => $sale->id, 'type' => $sale->sale_type])->first();
        if ($payment) {
            PaymentDetailModel::where('payment_id', $payment->id)->delete();
            $payment->delete();
        }

        CashInOutModel::where('invoice_id', $sale->id)->delete();
        $sale_detail = SaleDetailsModel::where('sale_id', $sale->id)->get();
        foreach ($sale_detail as $row) {
            if ($sale->status == 1) {
                $stock = StockModel::where(array(
                    'product_id' => $row->product_id,
                    'size_code' => $row->size_code,
                    'color_code' => $row->color_code,
                    'barcode' => $row->barcode,
                    'type' => 'product',
                    'warehouse_id' => $sale->warehouse_id
                ))->first();
                if ($stock) {
                    $stock->stock_qty += $row->qty;
                    $stock->save();
                }
            }
            $row->delete();
        }
        $sale->delete();
        return response()->json(['status' => 'success']);

    }
}
