<?php

namespace App\Http\Controllers;

use App\Models\Akun;
use App\Models\Cashtransaction;
use App\Models\Language;
use App\Models\Licence;
use App\Models\Product;
use App\Models\Stocktransaction;
use App\Models\Subcashtransaction;
use App\Models\Substocktransaction;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class BeginningBalanceController extends Controller
{
    private function loadAkunMapping($langCode = 'id')
    {
        $jsonPath = config_path("lang/{$langCode}/akun.json");
        if (!file_exists($jsonPath)) {
            $jsonPath = config_path('lang/id/akun.json');
        }
        if (!file_exists($jsonPath)) {
            return [];
        }
        return json_decode(file_get_contents($jsonPath), true) ?? [];
    }

    private function translateAccountName($accountName, $companyType, $mappingData)
    {
        if ($companyType && isset($mappingData[$companyType][$accountName])) {
            return $mappingData[$companyType][$accountName];
        }
        if (isset($mappingData['akun_umum'][$accountName])) {
            return $mappingData['akun_umum'][$accountName];
        }
        return $accountName;
    }

    private function setAkunRename($akun, $companyType, $mappingData)
    {
        if ($akun && is_object($akun) && isset($akun->name)) {
            $akun->rename = $this->translateAccountName($akun->name, $companyType, $mappingData);
        }
    }

    public function getBeginningBalance()
    {
        $transaction = false;
        $stock = Stocktransaction::first();
        $cash = Cashtransaction::first();
        if ($stock || $cash) {
            $transaction = true;
        }

        $date = Cashtransaction::where('transaction_category', 'saldo_awal')
            ->where('beginning_balance', true)
            ->where('cashin', '>', 0)
            ->first();
        if ($date) {
            $date = $date->date;
        }

        $product = Stocktransaction::where('beginning_balance', true)
            ->sum('total');

        $akun = Akun::where('name', '=', 'Modal Awal')->first();
        $modal_awal = Subcashtransaction::where('akun_id', $akun->id)
            ->whereHas('cashtransaction', function ($sub) {
                $sub->where('beginning_balance', true);
            })
            ->sum('total');

        $akun = Akun::where('name', '=', 'Laba Ditahan')->first();
        $laba_ditahan = Subcashtransaction::where('akun_id', $akun->id)
            ->whereHas('cashtransaction', function ($sub) {
                $sub->where('beginning_balance', true);
            })
            ->sum('total');

        $simpanan_wajib = 0;
        $akun = Akun::where('name', '=', 'Simpanan Wajib')->first();
        if ($akun) {
            $simpanan_wajib = Subcashtransaction::where('akun_id', $akun->id)
                ->whereHas('cashtransaction', function ($sub) {
                    $sub->where('beginning_balance', true);
                })
                ->sum('total');
        }

        $kas = Cashtransaction::where('transaction_category', 'saldo_awal')
            ->where('beginning_balance', true)
            ->where('cashin', '>', 0)
            ->sum('cashin');

        $aset = Cashtransaction::where('transaction_category', 'modal_aset')
            ->where('beginning_balance', true)
            ->sum('cashin');

        $hutang = Cashtransaction::where('transaction_category', 'hutang')
            ->where('beginning_balance', true)
            ->sum('cashin');

        $piutang = Cashtransaction::where('transaction_category', '=', 'catat_piutang')
            ->where('beginning_balance', true)
            ->sum('cashout');

        $response = [
            'success' => true,
            'data' => [
                'product' => $product,
                'piutang' => $piutang,
                'cash' => $kas,
                'aset' => $aset,
                'modal_awal' => $modal_awal,
                'simpanan_wajib' => $simpanan_wajib,
                'laba_ditahan' => $laba_ditahan,
                'hutang' => $hutang,
                'date' => $date,
                'transaction' => $transaction
            ]
        ];

        return response()->json($response);
    }

    public function detailBeginningBalance(Request $request)
    {
        $data = [];

        if ($request->type == 'product') {
            $product = Stocktransaction::where('beginning_balance', true)
                ->with('substocktransaction.product.unit')
                ->get();
            $data = $product;
        }
        if ($request->type == 'hutang') {
            $hutang = Cashtransaction::where('transaction_category', 'hutang')
                ->where('beginning_balance', true)
                ->with('subcashtransaction', 'from', 'to', 'subcashtransaction.akun')
                ->get();
            $data = $hutang;
        }
        if ($request->type == 'piutang') {
            $piutang = Cashtransaction::where('transaction_category', '=', 'catat_piutang')
                ->where('beginning_balance', true)
                ->with('subcashtransaction', 'from', 'to', 'subcashtransaction.akun')
                ->get();
            $data = $piutang;
        }
        if ($request->type == 'aset') {
            $aset = Cashtransaction::where('transaction_category', 'modal_aset')
                ->where('beginning_balance', true)
                ->with('subcashtransaction', 'from', 'to', 'subcashtransaction.akun')
                ->get();
            $data = $aset;
        }
        if ($request->type == 'cash') {
            $kas = Cashtransaction::where('transaction_category', 'saldo_awal')
                ->where('beginning_balance', true)
                ->with('subcashtransaction', 'from', 'to', 'subcashtransaction.akun')
                ->where('cashin', '>', 0)
                ->get();
            $data = $kas;
        }
        if ($request->type == 'modal_awal') {
            $akun = Akun::where('name', '=', 'Modal Awal')->first();
            $modal_awal = Cashtransaction::where('transaction_category', 'saldo_awal')
                ->where('beginning_balance', true)
                ->whereHas('subcashtransaction', function ($sub) use ($akun) {
                    $sub->where('akun_id', $akun->id);
                })
                ->with('subcashtransaction', 'from', 'to', 'subcashtransaction.akun')
                ->get();
            $data = $modal_awal;
        }
        if ($request->type == 'laba_ditahan') {
            $akun = Akun::where('name', '=', 'Laba Ditahan')->first();
            $laba_ditahan = Cashtransaction::where('transaction_category', 'saldo_awal')
                ->where('beginning_balance', true)
                ->whereHas('subcashtransaction', function ($sub) use ($akun) {
                    $sub->where('akun_id', $akun->id);
                })
                ->with('subcashtransaction', 'from', 'to', 'subcashtransaction.akun')
                ->get();
            $data = $laba_ditahan;
        }
        if ($request->type == 'simpanan_wajib') {
            $akun = Akun::where('name', '=', 'Simpanan Wajib')->first();
            if ($akun) {
                $simpanan_wajib = Cashtransaction::where('transaction_category', 'saldo_awal')
                    ->where('beginning_balance', true)
                    ->whereHas('subcashtransaction', function ($sub) use ($akun) {
                        $sub->where('akun_id', $akun->id);
                    })
                    ->with('subcashtransaction', 'from', 'to', 'subcashtransaction.akun')
                    ->get();
                $data = $simpanan_wajib;
            }
        }

        if ($request->type !== 'product' && !empty($data)) {
            $licence = Licence::first();
            $companyType = $licence ? $licence->company_type : null;
            $lang = Language::where('status', true)->first();
            $langCode = $lang->code ?? 'id';
            $mappingData = $this->loadAkunMapping($langCode);

            foreach ($data as $item) {
                $akunFrom = $item->relationLoaded('from') ? $item->getRelation('from') : null;
                $akunTo = $item->relationLoaded('to') ? $item->getRelation('to') : null;
                $this->setAkunRename($akunFrom, $companyType, $mappingData);
                $this->setAkunRename($akunTo, $companyType, $mappingData);
                if (isset($item->subcashtransaction) && $item->subcashtransaction) {
                    foreach ($item->subcashtransaction as $sub) {
                        $this->setAkunRename($sub->akun ?? null, $companyType, $mappingData);
                    }
                }
            }
        }

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

        return response($response, 200);
    }

    public function createBeginningBalance(Request $request)
    {
        $request->validate([
            'staff' => 'nullable',
            'date' => 'nullable',

            // cash
            'akun_id_aset.*'  => 'nullable',
            'akun_id_hutang.*'  => 'nullable',
            'akun_id_piutang.*'  => 'nullable',
            'akun_id_cash.*'  => 'nullable',

            'total_aset.*'  => 'nullable|numeric',
            'total_hutang.*'  => 'nullable|numeric',
            'total_piutang.*'  => 'nullable|numeric',
            'total_cash.*'  => 'nullable|numeric',
            'total_modal_awal'  => 'nullable|numeric',
            'total_simpanan_wajib'  => 'nullable|numeric',
            'total_laba_ditahan'  => 'nullable|numeric',

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

        DB::beginTransaction();

        try {
            $desc = 'SALDO AWAL';
            $date = date("Y-m-d", strtotime($request->date));

            // create stock
            if (!empty($request->product_id)) {
                $stock = new Stocktransaction;
                $stock->staff = $request->staff;
                $stock->date = $date;
                $stock->type = $request->type;
                $stock->description = $desc;
                $stock->beginning_balance = true;
                $stock->save();

                $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];
                    $sub->purchase_price = $request->purchase_price[$key];
                    $sub->left = $request->qty[$key];
                    $sub->total = $request->total[$key];
                    $sub->save();

                    $substocktransaction[] = $sub;

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

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

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

            // ----------------------------------------------------  //

            // create cash

            // aset
            if (!empty($request->akun_id_aset)) {
                foreach ($request->akun_id_aset as $key => $value) {
                    $cash = new Cashtransaction;
                    $cash->to = $request->akun_id_aset[$key];
                    $cash->staff = $request->staff;
                    $cash->desc = $desc;
                    $cash->date = $date;
                    $cash->transaction_category = 'modal_aset';
                    $cash->beginning_balance = true;
                    $cash->cashin = $request->total_aset[$key];
                    $cash->cashout = 0;
                    $cash->transfer = 0;
                    $cash->save();

                    $sub = new Subcashtransaction;
                    $sub->cashtransaction_id = $cash->id;
                    $sub->akun_id = $request->akun_id_aset[$key];
                    $sub->total = $request->total_aset[$key];
                    $sub->desc = $desc;
                    $sub->save();
                }
            }

            // hutang
            if (!empty($request->akun_id_hutang)) {
                foreach ($request->akun_id_hutang as $key => $value) {
                    $cash = new Cashtransaction;
                    $cash->to = $request->akun_id_hutang[$key];
                    $cash->staff = $request->staff;
                    $cash->desc = $desc;
                    $cash->date = $date;
                    $cash->transaction_category = 'hutang';
                    $cash->beginning_balance = true;
                    $cash->cashin = $request->total_hutang[$key];
                    $cash->cashout = 0;
                    $cash->transfer = 0;
                    $cash->save();

                    $sub = new Subcashtransaction;
                    $sub->cashtransaction_id = $cash->id;
                    $sub->akun_id = $request->akun_id_hutang[$key];
                    $sub->total = $request->total_hutang[$key];
                    $sub->desc = $desc;
                    $sub->save();
                }
            }

            // piutang
            if (!empty($request->akun_id_piutang)) {
                foreach ($request->akun_id_piutang as $key => $value) {
                    $cash = new Cashtransaction;
                    $cash->from = $request->akun_id_piutang[$key];
                    $cash->staff = $request->staff;
                    $cash->desc = $desc;
                    $cash->date = $date;
                    $cash->transaction_category = 'catat_piutang';
                    $cash->beginning_balance = true;
                    $cash->cashin = 0;
                    $cash->cashout = $request->total_piutang[$key];
                    $cash->transfer = 0;
                    $cash->save();

                    $sub = new Subcashtransaction;
                    $sub->cashtransaction_id = $cash->id;
                    $sub->akun_id = $request->akun_id_piutang[$key];
                    $sub->total = $request->total_piutang[$key];
                    $sub->desc = $desc;
                    $sub->save();
                }
            }

            // cash
            if (!empty($request->akun_id_cash)) {
                foreach ($request->akun_id_cash as $key => $value) {
                    $cash = new Cashtransaction;
                    $cash->staff = $request->staff;
                    $cash->desc = $desc;
                    $cash->date = $date;
                    $cash->transaction_category = 'saldo_awal';
                    $cash->beginning_balance = true;
                    $cash->cashin = $request->total_cash[$key];
                    $cash->cashout = 0;
                    $cash->transfer = 0;
                    $cash->save();

                    $sub = new Subcashtransaction;
                    $sub->cashtransaction_id = $cash->id;
                    $sub->akun_id = $request->akun_id_cash[$key];
                    $sub->total = $request->total_cash[$key];
                    $sub->desc = $desc;
                    $sub->save();
                }
            }

            // modal awal
            if (!empty($request->total_modal_awal)) {
                $cash = new Cashtransaction;
                $cash->staff = $request->staff;
                $cash->desc = $desc;
                $cash->date = $date;
                $cash->transaction_category = 'saldo_awal';
                $cash->beginning_balance = true;
                $cash->cashin = 0;
                $cash->cashout = 0;
                $cash->transfer = 0;
                $cash->save();

                $akun = Akun::where('name', '=', 'Modal Awal')->first();

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

            // simpanan wajib
            if (!empty($request->total_simpanan_wajib)) {
                $cash = new Cashtransaction;
                $cash->staff = $request->staff;
                $cash->desc = $desc;
                $cash->date = $date;
                $cash->transaction_category = 'saldo_awal';
                $cash->beginning_balance = true;
                $cash->cashin = 0;
                $cash->cashout = 0;
                $cash->transfer = 0;
                $cash->save();

                $akun = Akun::where('name', '=', 'Simpanan Wajib')->first();
                if (!$akun) {
                    throw new \Exception('Akun Simpanan Wajib tidak ditemukan');
                }

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

            // laba ditahan
            if (!empty($request->total_laba_ditahan)) {
                $cash = new Cashtransaction;
                $cash->staff = $request->staff;
                $cash->desc = $desc;
                $cash->date = $date;
                $cash->transaction_category = 'saldo_awal';
                $cash->beginning_balance = true;
                $cash->cashin = 0;
                $cash->cashout = 0;
                $cash->transfer = 0;
                $cash->save();

                $akun = Akun::where('name', '=', 'Laba Ditahan')->first();

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

            DB::commit();

            $response = [
                'success' => true,
                'message' => 'Data berhasil disimpan'
            ];

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

            $response = [
                'success' => false,
                'message' => 'Terjadi kesalahan saat menyimpan saldo awal: ' . $e->getMessage(),
            ];

            return response($response, 500);
        }
    }
}
