<?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 App\Models\TaxSettingMain;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;

class StockorderController extends Controller
{
    public function getStockOutDue(Request $request)
    {

        $data = Stocktransaction::with('contact', 'cashin', 'cashout', 'substocktransaction', 'substocktransaction.product.unit', 'credit', 'credit.cashin')->whereNotNull('cashin_id')->where('pending', 1);

        $data = $data->with('contact', 'cashout')->orderBy('date', 'ASC')->get();

        foreach ($data as $key => $value) {
            $day = date('Y-m-d', time());
            if ($value->date < $day) {
                $value->date = Carbon::create($value->date)->diffForHumans(null, true) . " lagi";
            } else {
                $value->date = Carbon::create($value->date)->diffForHumans(null, true) . " yang lalu";
            }
        }

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

        return response($response, 200);
    }
    public function getStockTransactionDetail(Request $request)
    {

        $data = Stocktransaction::where('id', $request->id)->with('contact', 'cashin', 'cashout', 'substocktransaction', 'substocktransaction.product.unit', 'credit', 'credit.cashin')->get();

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

        return response($response, 200);
    }

    public function getStockIn(Request $request)
    {

        $data = Stocktransaction::with('contact', 'cashout', 'credit.cashin', 'credit.cashout', 'substocktransaction.product.unit')->whereNotNull('cashout_id')->whereNotNull('pending');

        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('created_at', 'DESC')->get();

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

        ];

        return response($response, 200);
    }

    public function getStockOut(Request $request)
    {
        $data = Stocktransaction::with('contact', 'sales', 'cashin', 'credit.cashin', 'credit.cashout', 'substocktransaction.product.unit')->whereNotNull('cashin_id')->whereNotNull('pending');

        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('date', 'DESC')->get();

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

        ];

        return response($response, 200);
    }

    public function createStockIn(Request $request)
    {
        $request->validate([
            'contact_id' => 'required',
            'cashout_id' => 'nullable',
            'staff' => 'required',
            'paid' => 'required',
            'payment_due' => 'nullable',
            'date' => 'required',
            'discount' => 'nullable',

            'product_id.*' => 'required',
            'qty.*'  => 'required',
            'purchase_price.*'  => 'required',
            'ppn_amount.*'  => 'nullable',
            'total.*'  => 'required|numeric',
        ]);

        if (empty($request->cashout_id)) {
            $request->cashout_id = Akun::where('iscash', true)->first()->id;
        }

        // Check apakah PKP
        $is_pkp = TaxSettingMain::where('name', 'vat_registered ')->first()->vat_registered ?? false;

        DB::beginTransaction();

        try {
            $stock = new Stocktransaction;
            $stock->contact_id = $request->contact_id;
            $stock->cashout_id = $request->cashout_id;
            $stock->staff = $request->staff;
            $stock->description = $request->desc;
            $stock->pending = 1;
            $stock->date = date("Y-m-d", strtotime($request->date));
            $stock->paid = $request->paid;
            $stock->payment_due = date("Y-m-d", strtotime($request->payment_due));
            $stock->is_pkp = $is_pkp;
            $stock->total_ppn = 0;
            $stock->save();

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

            foreach ($data as $key => $value) {
                $total = $total + $request->total[$key];
                $total_ppn = $total_ppn + ($request->ppn_amount[$key] ?? 0);

                $subtotal = !$is_pkp ? $request->total[$key] : $request->total[$key] - ($request->ppn_amount[$key] ?? 0);

                $sub = new Substocktransaction;
                $sub->stocktransaction_id = $stock->id;
                $sub->product_id = $request->product_id[$key];
                $sub->qty = $request->qty[$key];
                $sub->purchase_price = $request->purchase_price[$key];
                $sub->total = $subtotal;
                $sub->ppn_amount = $request->ppn_amount[$key] ?? 0;
                $sub->save();

                $substocktransactions[] = $sub;
            }

            $akun = Akun::find($request->cashout_id);
            $akun->total = $akun->total - $stock->paid;
            $akun->save();

            $akun = Akun::where('name', '=', 'Uang Muka Pesanan Pembelian')->first();
            $akun = Akun::find($akun->id);
            $akun->total = $akun->total + $stock->paid;
            $akun->save();

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

            $credit = new Credit;
            $credit->stocktransaction_id = $stock->id;
            $credit->cashout_id = $request->cashout_id;
            $credit->staff = $request->staff;
            $credit->total = $stock->paid;
            $credit->date = date("Y-m-d", strtotime($stock->date));
            $credit->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 stock in: ' . $e->getMessage(),
            ];

            return response($response, 500);
        }
    }

    public function createStockOut(Request $request)
    {
        $request->validate([
            'contact_id' => 'required',
            'cashin_id' => 'nullable',
            'sales_person' => 'nullable',
            'staff' => 'required',
            'paid' => 'required',
            'date' => 'required',
            'discount' => 'nullable',
            'date' => 'required',

            'payment_due' => 'nullable',
            'product_id.*' => 'required',
            'selling_price.*' => 'required',
            'qty.*' => 'required',
            'ppn_amount.*' => 'nullable',
            'total.*' => 'required|numeric',
        ]);

        if (!empty($request->paid) || $request->paid > 0) {
            $request->validate([
                'cashin_id' => 'required',
            ]);
        }

        if (empty($request->cashin_id)) {
            $request->cashin_id = Akun::where('iscash', true)->first()->id;
        }

        // Check apakah PKP
        $is_pkp = TaxSettingMain::where('name', 'vat_registered ')->first()->vat_registered ?? false;

        DB::beginTransaction();

        try {
            $contact = Contact::with('type')->where('id', $request->contact_id)->first();
            $sum = 0;
            foreach ($request->total as $key => $value) {
                $sum = $sum + $request->total[$key];
            }

            $hutang = ($sum - $request->paid) - $request->paid;

            $stock = new Stocktransaction;
            $stock->contact_id = $request->contact_id;
            $stock->cashin_id = $request->cashin_id;
            $stock->sales_person = $request->sales_person;
            $stock->staff = $request->staff;
            $stock->description = $request->desc;
            $stock->pending = true;
            $stock->date = date("Y-m-d", strtotime($request->date));
            $stock->paid = $request->paid;
            $stock->payment_due = date("Y-m-d", strtotime($request->payment_due));
            $stock->is_pkp = $is_pkp;
            $stock->total_ppn = 0;
            $stock->save();

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

            foreach ($data as $key => $value) {
                $subtotal = !$is_pkp ? $request->total[$key] : $request->total[$key] - ($request->ppn_amount[$key] ?? 0);

                $sub = new Substocktransaction;
                $sub->stocktransaction_id = $stock->id;
                $sub->product_id = $request->product_id[$key];
                $sub->selling_price = $request->selling_price[$key];
                $sub->qty = $request->qty[$key];
                $sub->total = $subtotal;
                $sub->ppn_amount = $request->ppn_amount[$key] ?? 0;
                $sub->save();

                $substocktransactions[] = $sub;
                $total = $total + $sub->total;
                $total_ppn = $total_ppn + $sub->ppn_amount;
            }

            $akun = Akun::where('name', '=', 'Hutang Pesanan Penjualan')->first();
            $akun = Akun::find($akun->id);
            $akun->total = $akun->total + $stock->paid;
            $akun->save();

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

            $akun = Akun::find($request->cashin_id);
            $akun->total = $akun->total + $stock->paid;
            $akun->save();

            $credit = new Credit;
            $credit->stocktransaction_id = $stock->id;
            $credit->cashin_id = $request->cashin_id;
            $credit->staff = $request->staff;
            $credit->total = $stock->paid;
            $credit->date = date("Y-m-d", strtotime($stock->date));
            $credit->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 stock out: ' . $e->getMessage(),
            ];

            return response($response, 500);
        }
    }

    public function updateProductStock(Request $request)
    {
        $request->validate([
            'url' => 'required',
            'desc' => 'nullable',
            'product_id.*' => 'required',
            'qty.*'  => 'required',
            'purchase_price.*'  => 'nullable',
            'selling_price.*'  => 'nullable',
            'total.*'  => 'required|numeric',
        ]);

        $stock = Stocktransaction::find($request->id);
        $substock = Substocktransaction::where('stocktransaction_id', '=', $request->id)->get();
        foreach ($substock as $key => $value) {
            $value->delete();
        }

        $data = $request->product_id;
        $total = 0;
        foreach ($data as $key => $value) {
            $sub = new Substocktransaction;
            $sub->stocktransaction_id = $stock->id;
            $sub->product_id = $request->product_id[$key];
            $sub->qty = $request->qty[$key];
            if ($request->url === 'in') {
                $sub->purchase_price = $request->purchase_price[$key];
            }
            if ($request->url === 'out') {
                $sub->selling_price = $request->selling_price[$key];
            }
            $sub->total = $request->total[$key];
            $sub->save();

            $substocktransaction[] = $sub;

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

        $stock->total = $total;
        if (!empty($request->desc)) {
            $stock->description = $request->desc;
        }
        $stock->save();

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

        return response($response, 200);
    }

    public function updateCashOrder(Request $request)
    {
        $request->validate([
            'cashin_id' => 'nullable',
            'cashout_id' => 'nullable',
            'id' => 'required',
            'date' => 'required',
            'staff' => 'required',
            'total' => 'required',
        ]);

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

        $credit = new Credit;
        $credit->stocktransaction_id = $stock->id;
        $credit->staff = $request->staff;
        $credit->total = $request->total;
        $credit->date = date("Y-m-d", strtotime($request->date));;
        if ($request->cashin_id) {
            $credit->cashin_id = $request->cashin_id;
        } elseif ($request->cashout_id) {
            $credit->cashout_id = $request->cashout_id;
        }
        $credit->save();

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

        return response($response, 200);
    }

    public function updateStockOut(Request $request)
    {
        $request->validate([
            'pending' => 'required',
        ]);

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

        if (!$stock) {
            return response()->json(['message' => 'Stocktransaction not found'], 404);
        }

        $stock->pending = $request->pending;
        $stock->save();

        $response = [
            'success' => true,
            'stocktransaction' => $stock,
        ];
        return response($response, 200);
    }

    public function pendingCancel(Request $request)
    {
        $stock = Stocktransaction::find($request->id);
        if ($stock->paid != 0) {
            $response = [
                'success' => false,
                'message' => 'Pesanan sudah dicicil tidak dapat di cancel',
            ];
            return response($response, 400);
        }

        $stock->pending = 4;
        $stock->save();

        $response = [
            'success' => true,
            'stockktransaction' => $stock,
        ];
        return response($response, 200);
    }

    public function pendingRefund(Request $request)
    {
        $request->validate([
            'cashin_id' => 'nullable',
            'cashout_id' => 'nullable',
            'desc' => 'nullable',
            'date' => 'required',
            'staff' => 'required',
        ]);

        $stock = Stocktransaction::find($request->id);
        if (!$stock) {
            return response()->json(['message' => 'Stocktransaction not found'], 404);
        }

        $stock->pending = 3;
        $stock->save();

        $akun = [];

        $cash = new Cashtransaction();
        $cash->staff = $request->staff;
        $cash->date = date("Y-m-d", strtotime($request->date));
        if ($request->cashout_id) {
            $akun = Akun::where('name', '=', 'Hutang Pesanan Penjualan')->first();
            $cash->from = $request->cashout_id;
            $cash->transaction_category = 'refund_pesanan_penjualan';
            $cash->cashin = 0;
            $cash->cashout = $stock->paid;
        }
        if ($request->cashin_id) {
            $akun = Akun::where('name', '=', 'Uang Muka Pesanan Pembelian')->first();
            $cash->to = $request->cashin_id;
            $cash->transaction_category = 'refund_pesanan_pembelian';
            $cash->cashout = 0;
            $cash->cashin = $stock->paid;
        }
        $cash->stocktransaction_id = $stock->id;
        $cash->transfer = 0;
        $cash->desc = $request->desc;
        $cash->save();

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

        $sub = new Subcashtransaction;
        $sub->cashtransaction_id = $cash->id;
        $sub->akun_id = $akun->id;
        $sub->total = $stock->paid;
        $sub->desc = $request->desc;
        $sub->save();
    }

    public function deleteRefund(Request $request)
    {
        $cash = Cashtransaction::find($request->id);

        if (!$cash) {
            return response()->json(['message' => 'Cashtransaction not found'], 404);
        }

        $stock = Stocktransaction::find($cash->stocktransaction_id);
        $stock->pending = 1;
        $stock->save();

        $cash->delete();
    }

    public function deleteStockTransaction(Request $request)
    {
        $stock = Stocktransaction::find($request->id);
        if ($stock->cashin_id) {

            $akun = Akun::find($stock->cashin_id);
            $akun->total = $akun->total - $stock->paid;
            $akun->save();

            $akun = Akun::where('name', '=', 'Hutang Pesanan Penjualan')->first();
            $akun = Akun::find($akun->id);
            $akun->total = ($akun->total - $akun->discount) - $stock->paid;
            $akun->save();

            Substocktransaction::where('stocktransaction_id', '=', $stock->id)->delete();
        } elseif ($stock->cashout_id) {
            $akun = Akun::find($stock->cashout_id);
            $akun->total = $akun->total + $stock->paid;
            $akun->save();

            $totalhpp = 0;

            $akun = Akun::where('name', '=', 'Uang Muka Pesanan Pembelian')->first();
            $akun = Akun::find($akun->id);
            $akun->total = ($akun->total - $akun->discount) -  $stock->paid;
            $akun->save();

            Substocktransaction::where('stocktransaction_id', '=', $stock->id)->delete();
        }
        $stock->delete();
        $stock->credit()->delete();

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

        return response($response, 200);
    }
}
