<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Models\Stocktransaction;
use App\Models\Substocktransaction;
use App\Models\Product;
use App\Models\Akun;
use App\Models\Cashtransaction;
use App\Models\Credit;
use App\Models\Contact;
use App\Models\Subcashtransaction;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;

class ReturnController extends Controller
{
    public function getReturnIn(Request $request)
    {

        $data = Stocktransaction::with('contact', 'cashout', 'credit', 'substocktransaction.product.unit')->where('return', 'in');

        if (!empty($request->start_date) && !empty($request->end_date)) {
            $request->start_date = date('Y-m-d', strtotime($request->start_date));
            $request->end_date = date('Y-m-d', strtotime($request->end_date));
            $data = $data->whereBetween('date', [$request->start_date, $request->end_date]);
        }
        // else{
        //     $data = $data->whereBetween('date',[date('Y-m-01',time()),date('Y-m-d',time())]);
        // }
        $data = $data->orderBy('id', 'desc')->get();

        $response = [
            'success' => true,
            'stocktransaction' => $data,
        ];

        return response($response, 200);
    }

    public function getReturnOut(Request $request)
    {
        $data = Stocktransaction::with('contact', 'cashin', 'credit', 'substocktransaction.product.unit')->where('return', 'out');

        if (!empty($request->start_date) && !empty($request->end_date)) {
            $request->start_date = date('Y-m-d', strtotime($request->start_date));
            $request->end_date = date('Y-m-d', strtotime($request->end_date));
            $data = $data->whereBetween('date', [$request->start_date, $request->end_date]);
        }
        // else{
        //     $data = $data->whereBetween('date',[date('Y-m-01',time()),date('Y-m-d',time())]);
        // }

        $data = $data->orderBy('id', 'desc')->get();

        $response = [
            'success' => true,
            'stocktransaction' => $data,
        ];

        return response($response, 200);
    }

    public function getReturnDetail(Request $request)
    {
        $data = Stocktransaction::where('id', $request->id)->with('contact', 'substocktransaction', 'substocktransaction.product')->get();
        $response = [
            'success' => true,
            'stocktransaction' => $data,

        ];

        return response($response, 200);
    }

    public function createReturnIn(Request $request)
    {
        $request->validate([
            'staff' => 'required',
            'date' => 'required',
            'cashout_id' => 'nullable',
            // 'payment_due' =>'required',
            'contact_id' => 'required',
            'stocktransaction_id' => 'required',
            'product_id.*' => 'required',
            'qty.*'  => 'required',
            'qty_retur.*'  => 'required',
            'purchase_price.*'  => 'required',
            'multi_unit.*'  => 'nullable',
            'qty_unit.*'  => 'nullable',
            'purchase_price_unit.*'  => 'nullable',
            'selling_price_unit.*'  => 'nullable',
            'total.*'  => 'required|numeric',
        ]);

        DB::beginTransaction();

        try {
            $stock = new Stocktransaction;
            $stock->staff = $request->staff;
            $stock->date = date("Y-m-d", strtotime($request->date));
            $stock->cashout_id = $request->cashout_id;
            $stock->contact_id = $request->contact_id;
            $stock->description = $request->desc;
            // $stock->payment_due = date("Y-m-d", strtotime($request->payment_due));
            $stock->contact_id = $request->contact_id;
            $stock->return = 'in';
            $stock->save();

            $cash = new Cashtransaction;
            $cash->staff = $request->staff;
            $cash->date = date("Y-m-d", strtotime($request->date));
            $cash->transaction_category = 'pendapatan_retur_in';
            $cash->stocktransaction_id = $stock->id;
            $cash->cashout = 0;
            $cash->cashin = 0;
            $cash->transfer = 0;
            $cash->save();

            $stock->cashtransaction_id = $cash->id;
            $stock->save();

            $data = $request->product_id;
            $total = 0;
            $substocktransactions = [];

            foreach ($data as $key => $value) {

                $product = Product::with('bundleItems.multiUnit')->find($value);

                // =========================
                // JIKA PRODUK BUNDLE
                // =========================
                if ($product && $product->category == 'bundle') {

                    foreach ($product->bundleItems as $bundleIndex => $bundle) {

                        if (!$bundle->product) {
                            continue;
                        }

                        $convertQty = 1;

                        $purchasePrice = $bundle->product->purchase_price ?? 0;

                        if ($bundle->multiUnit) {
                            $convertQty = $bundle->multiUnit->multi_qty;
                            $purchasePrice = $bundle->multiUnit->multi_purchase_price ?? $purchasePrice;
                        }

                        $isFirstBundle = $bundleIndex === 0;

                        $sellingPrice = $isFirstBundle
                            ? ($request->selling_price[$key] ?? 0)
                            : null;

                        $sellingPricePerUnit = $isFirstBundle
                            ? $sellingPrice / ($bundle->qty * $convertQty)
                            : null;

                        $bundleQty =
                            $bundle->qty *
                            $convertQty *
                            $request->qty[$key];

                        $sub = new Substocktransaction;
                        $sub->stocktransaction_id = $stock->id;
                        $sub->product_id = $bundle->product_id;
                        $sub->product_bundle_id = $product->id;
                        $sub->return_trans_id = $request->return_trans_id[$key];
                        $sub->qty = $bundleQty;

                        $sub->purchase_price = $purchasePrice / $convertQty;

                        // hanya bundle pertama
                        $sub->selling_price = $sellingPricePerUnit;

                        $sub->left = $bundleQty;
                        $sub->total = $bundleQty * ($purchasePrice / $convertQty);

                        $sub->multi_unit = $bundle->multi_unit_id ?? null;
                        $sub->qty_unit = $convertQty;

                        $sub->purchase_price_unit = $purchasePrice;

                        // hanya bundle pertama
                        $sub->selling_price_unit = $sellingPrice;

                        $sub->save();

                        $substocktransactions[] = $sub;

                        $bundleProduct = Product::find($bundle->product_id);

                        if ($bundleProduct) {
                            $bundleProduct->qty += $bundleQty;
                            $bundleProduct->save();
                        }
                    }

                    $s_r = Substocktransaction::where('id', $request->return_trans_id[$key])
                        ->first();

                    if ($s_r) {
                        $s_r->qty_retur += (int)$request->qty[$key];
                        $s_r->save();
                    }

                    $isstock = Stocktransaction::find(
                        $request->stocktransaction_id
                    );

                    if (
                        $isstock->total >
                        (
                            $isstock->paid +
                            $isstock->discount +
                            $isstock->return_credit
                        )
                    ) {
                        $sub->isdebt = true;
                        $sub->save();
                    }
                }

                // =========================
                // PRODUK NORMAL
                // =========================
                else {

                    $sub = new Substocktransaction;
                    $sub->stocktransaction_id = $stock->id;
                    $sub->product_id = $request->product_id[$key];
                    $sub->return_trans_id = $request->return_trans_id[$key];
                    $sub->qty = $request->qty[$key];
                    $sub->purchase_price = $request->purchase_price[$key];
                    $sub->selling_price = $request->selling_price[$key];
                    $sub->left = $request->qty[$key];
                    $sub->total = ($request->qty[$key] * $request->purchase_price[$key]);

                    $sub->multi_unit = $request->multi_unit[$key] != 'none'
                        ? $request->multi_unit[$key]
                        : null;

                    $sub->qty_unit = $request->qty_unit[$key] != 'none'
                        ? $request->qty_unit[$key]
                        : null;

                    $sub->purchase_price_unit = $request->purchase_price_unit[$key] != 'none'
                        ? $request->purchase_price_unit[$key]
                        : null;

                    $sub->selling_price_unit = $request->selling_price_unit[$key] != 'none'
                        ? $request->selling_price_unit[$key]
                        : null;

                    $sub->save();

                    $substocktransactions[] = $sub;

                    $product->qty += $sub->qty;
                    $product->save();

                    // save qty_retur
                    $s_r = Substocktransaction::where('id', $request->return_trans_id[$key])
                        ->where('product_id', $request->product_id[$key])
                        ->first();

                    if ($s_r) {
                        $s_r->qty_retur += (int)$request->qty[$key];
                        $s_r->save();
                    }

                    $isstock = Stocktransaction::find($request->stocktransaction_id);

                    if (
                        $isstock->total >
                        ($isstock->paid + $isstock->discount + $isstock->return_credit)
                    ) {
                        $sub->isdebt = true;
                        $sub->save();
                    }
                }

                $total += $request->total[$key];
            }

            $stock = Stocktransaction::find($stock->id);
            $stock->total = $total;
            $stock->paid = $request->paid;
            $stock->save();

            $credit = new Credit;
            $credit->stocktransaction_id = $stock->id;
            $credit->cashout_id = $request->cashout_id;
            $credit->total = $request->paid;
            $credit->date = date("Y-m-d", strtotime($request->date));
            $credit->cash_credit = $request->kekurangan;
            $credit->staff = $request->staff;
            $credit->save();

            $sub = new Subcashtransaction;
            $sub->cashtransaction_id = $cash->id;
            $sub->akun_id = 128;
            $sub->total = $total;
            $sub->desc = $request->desc;
            $sub->save();

            $isstock = Stocktransaction::find($request->stocktransaction_id);

            if ($isstock->total > ($isstock->paid + $isstock->discount + $isstock->return_credit)) {
                $stock = Stocktransaction::find($stock->id);
                $hutang = $isstock->total - $isstock->paid - $isstock->discount - $isstock->return_credit;
                if ($total <= $hutang) {
                    $stock->return_credit_cash = $total;
                    $stock->save();

                    $isstock->return_credit += $total;
                    $isstock->save();
                } else {
                    $stock->return_credit_cash = $hutang;
                    $stock->save();

                    $isstock->return_credit += $hutang;
                    $isstock->save();
                }
            }

            DB::commit();

            $response = [
                'success' => true,
                'stockktransaction' => $stock,
                'substocktransaction' => $substocktransactions,
            ];

            return response($response, 200);
        } catch (\Exception $e) {
            DB::rollback();

            $response = [
                'success' => false,
                'message' => 'Terjadi kesalahan saat memproses return barang masuk: ' . $e->getMessage(),
            ];

            return response($response, 500);
        }
    }

    public function createReturnOut(Request $request)
    {
        $request->validate([
            'staff' => 'required',
            'date' => 'required',
            'cashin_id' => 'nullable',
            'contact_id' => 'required',
            'stocktransaction_id' => 'required',
            'product_id.*' => 'required',
            'qty.*'  => 'required',
        ]);

        // Mulai database transaction
        DB::beginTransaction();

        try {
            $contact = Contact::where('id', $request->contact_id)->first();
            $sum = 0;

            $data = $request->product_id;
            // Pengecekan stok produk
            foreach ($data as $key => $value) {
                $dataQty = $request->qty[$key];
                $dataProduct = Product::find($request->product_id[$key]);

                if ($dataQty > $dataProduct->qty) {
                    // Rollback transaction jika stok tidak mencukupi
                    DB::rollback();
                    return response()->json([
                        'status' => 'error',
                        'message' => 'Stok tidak mencukupi untuk produk: ' . $dataProduct->name . '. Stok tersedia: ' . $dataProduct->qty
                    ], 400);
                }
            }

            $stock = new Stocktransaction;
            $stock->staff = $request->staff;
            $stock->date = date("Y-m-d", strtotime($request->date));
            $stock->cashin_id = $request->cashin_id;
            $stock->description = $request->desc;
            $stock->return = 'out';
            // $stock->payment_due = date("Y-m-d", strtotime($request->payment_due));
            $stock->contact_id = $request->contact_id;

            $stock->save();

            $total = 0;
            $totalhpp = 0;
            $lasthb = 0;
            $cashCreatedOut = false;
            $cashCreatedIn = false;
            $subcash_id = 0;

            foreach ($data as $key => $value) {
                $sub = new Substocktransaction;
                $sub->stocktransaction_id = $stock->id;
                $sub->product_id = $request->product_id[$key];
                $sub->return_trans_id = $request->return_trans_id[$key];
                $sub->qty = $request->qty[$key];
                $sub->purchase_price = $request->purchase_price[$key];
                $sub->original_purchase_price = $request->original_purchase_price[$key];

                $sub->save();

                // save qty_retur
                $s_r = Substocktransaction::where('id', $request->return_trans_id[$key])->where('product_id', $request->product_id[$key])->first();
                if ($s_r) {
                    $s_r->qty_retur += (int)$request->qty[$key];
                    $s_r->save();
                }

                $isstock = Stocktransaction::find($request->stocktransaction_id);
                if ($isstock->total > ($isstock->paid + $isstock->discount + $isstock->return_credit)) {
                    $sub = Substocktransaction::find($sub->id);
                    $sub->isdebt = true;
                    $sub->save();
                }

                $substocktransaction[] = $sub;

                $product = Product::find($sub->product_id);
                $product->qty = $product->qty - $sub->qty;
                $product->save();

                $qty = $sub->qty;
                $subin = Substocktransaction::where('left', '>', 0)
                    ->whereHas('stocktransaction', function ($query) {
                        $query->whereNull('pending');
                    })->where('product_id', '=', $sub->product_id)->get();

                // temp array substock ids
                $substocktransactions_ids = [];

                foreach ($subin as $key => $value) {

                    // push id
                    array_push($substocktransactions_ids, $value->id);

                    if ($qty <= $value->left) {

                        $set = $value->left - $qty;

                        $sibin = Substocktransaction::find($value->id);
                        $sibin->left = $set;
                        $sibin->save();

                        $totalhpp = $totalhpp + ($value->purchase_price * $qty);
                        break;
                    } else {
                        $set = 0;
                        $qty = $qty - $value->left;
                        $totalhpp = $totalhpp + ($value->purchase_price * $value->left);

                        $sibin = Substocktransaction::find($value->id);
                        $sibin->left = $set;
                        $sibin->save();
                    }
                }
                $sibin = Substocktransaction::find($sub->id);
                $sibin->hpp = 0;
                $sibin->substocktransactions_ids = join(",", $substocktransactions_ids);
                $sibin->original_purchase_price = $subin[0]->purchase_price;
                $sibin->total = $sub->qty * $sub->purchase_price;
                $sibin->save();

                $total = $total + $sibin->total;

                if ($sibin->purchase_price < $sibin->original_purchase_price) {

                    if (!$cashCreatedOut) {
                        $cash = new Cashtransaction;
                        $cash->staff = $request->staff;
                        $cash->date = date("Y-m-d", strtotime($request->date));
                        $cash->transaction_category = 'biaya_retur_out';
                        $cash->stocktransaction_id = $stock->id;
                        $cash->cashout = 0;
                        $cash->cashin = 0;
                        $cash->transfer = 0;
                        $cash->save();

                        $cashCreatedOut = true;

                        $stock = Stocktransaction::find($stock->id);
                        $stock->cashtransaction_id = $cash->id;
                        $stock->save();

                        $subcash = new Subcashtransaction;
                        $subcash->cashtransaction_id = $cash->id;
                        $subcash->akun_id = 126;
                        $subcash->total = 0;
                        $subcash->desc = $request->desc;
                        $subcash->save();

                        $subcash_id = $subcash->id;
                    }

                    $subtotal = ($sibin->original_purchase_price - $sibin->purchase_price) * $sibin->qty;

                    $subcash = Subcashtransaction::find($subcash_id);
                    $subcash->total = $subcash->total + $subtotal;
                    $subcash->save();
                }

                if ($sibin->purchase_price > $sibin->original_purchase_price) {

                    if (!$cashCreatedIn) {
                        $cash = new Cashtransaction;
                        $cash->staff = $request->staff;
                        $cash->date = date("Y-m-d", strtotime($request->date));
                        $cash->transaction_category = 'pendapatan_retur_out';
                        $cash->stocktransaction_id = $stock->id;
                        $cash->cashout = 0;
                        $cash->cashin = 0;
                        $cash->transfer = 0;
                        $cash->save();

                        $cashCreatedIn = true;

                        $stock = Stocktransaction::find($stock->id);
                        $stock->cashtransaction_id = $cash->id;
                        $stock->save();

                        $subcash = new Subcashtransaction;
                        $subcash->cashtransaction_id = $cash->id;
                        $subcash->akun_id = 127;
                        $subcash->total = 0;
                        $subcash->desc = $request->desc;
                        $subcash->save();

                        $subcash_id = $subcash->id;
                    }

                    $subtotal = ($sibin->purchase_price - $sibin->original_purchase_price) * $sibin->qty;

                    $subcash = Subcashtransaction::find($subcash_id);
                    $subcash->total = $subcash->total + $subtotal;
                    $subcash->save();
                }
            }

            $stock = Stocktransaction::find($stock->id);
            $stock->total = $total;
            $stock->paid = $request->paid;
            $stock->save();

            $credit = new Credit;
            $credit->stocktransaction_id = $stock->id;
            $credit->cashin_id = $request->cashin_id;
            $credit->total = $request->paid;
            $credit->date = date("Y-m-d", strtotime($request->date));
            $credit->cash_credit = $request->kekurangan;
            $credit->staff = $request->staff;
            $credit->save();

            $isstock = Stocktransaction::find($request->stocktransaction_id);
            if ($isstock->total > ($isstock->paid + $isstock->discount + $isstock->return_credit)) {
                $stock = Stocktransaction::find($stock->id);
                $hutang = $isstock->total - $isstock->paid - $isstock->discount - $isstock->return_credit;
                if ($total <= $hutang) {
                    $stock->return_credit_cash = $total;
                    $stock->save();

                    $isstock->return_credit += $total;
                    $isstock->save();
                } else {
                    $stock->return_credit_cash = $hutang;
                    $stock->save();

                    $isstock->return_credit += $hutang;
                    $isstock->save();
                }
            }

            // Commit transaction jika semua berhasil
            DB::commit();

            $response = [
                'success' => true,
                'stockktransaction' => $stock,
                'substocktransaction' => $substocktransaction,
            ];
            return response($response, 200);
        } catch (\Exception $e) {
            // Rollback transaction jika terjadi error
            DB::rollback();

            return response()->json([
                'status' => 'error',
                'message' => 'Terjadi kesalahan saat memproses data: ' . $e->getMessage()
            ], 500);
        }
    }
}
