<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Contracts\Validation\Validator;

use App\Models\Cashtransaction;
use App\Models\Subcashtransaction;
use App\Models\Akun;
use App\Models\Credit;
use App\Models\CreditCashTransaction;
use App\Models\Language;
use App\Models\Licence;
use App\Models\Stocktransaction;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Symfony\Contracts\Service\Attribute\Required;

class CashController extends Controller
{
    public static function getActiveLanguage()
    {
        return Language::where('status', true)->first();
    }

    private function loadDataMapping($langCode = 'id')
    {
        $jsonPath = config_path("lang/{$langCode}/cashflow.json");

        // Fallback ke bahasa Indonesia jika file tidak ditemukan
        if (!file_exists($jsonPath)) {
            $jsonPath = config_path('lang/id/cashflow.json');
        }

        if (!file_exists($jsonPath)) {
            return [];
        }

        return json_decode(file_get_contents($jsonPath), true) ?? [];
    }

    private function translateCashFlowItem($itemName, $companyType, $mappingData)
    {
        // Handle company-specific mappings first
        if ($companyType && isset($mappingData['company_specific'][$companyType][$itemName])) {
            $itemName = $mappingData['company_specific'][$companyType][$itemName];
        }

        // Return translated item name
        return $mappingData['items'][$itemName] ?? $itemName;
    }

    private function translateCashFlowCategory($category, $mappingData)
    {
        return $mappingData['categories'][$category] ?? $category;
    }

    private function translateCashCategoryLabel($label, $mappingData)
    {
        return $mappingData['cash_categories'][$label] ?? $label;
    }

    private function applyCashFlowTranslations(&$cashFlowData, $companyType, $mappingData)
    {
        foreach ($cashFlowData as $categoryKey => &$categoryData) {
            // Tambahkan translated_name untuk kategori (tanpa mengubah key asli)
            $categoryData['translated_name'] = $this->translateCashFlowCategory($categoryKey, $mappingData);

            // Untuk setiap item, tambahkan field rename tanpa mengubah name
            foreach ($categoryData['data'] as &$item) {
                $item['rename'] = $this->translateCashFlowItem($item['name'], $companyType, $mappingData);
                // Field 'name' tetap dipertahankan dengan nilai asli
            }
        }
    }

    private function loadAccountMapping($langCode = 'id')
    {
        $jsonPath = config_path("lang/{$langCode}/akun.json");

        // Fallback ke bahasa Indonesia jika file tidak ditemukan
        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)
    {
        // Handle company-specific mappings first
        if ($companyType && isset($mappingData[$companyType][$accountName])) {
            return $mappingData[$companyType][$accountName];
        }

        // Handle general mappings
        if (isset($mappingData['akun_umum'][$accountName])) {
            return $mappingData['akun_umum'][$accountName];
        }

        return $accountName;
    }

    public function checkTarikLaba()
    {
        $exists = Cashtransaction::where('transaction_category', 'tarik_laba')->exists();

        return response()->json([
            'success' => true,
            'exists' => $exists
        ]);
    }

    public function getCash(Request $request)
    {

        $data = Cashtransaction::with('from', 'to');

        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->get();

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

        ];

        return response($response, 200);
    }

    public function getCashIn(Request $request)
    {
        $data = Cashtransaction::whereNotNull('cashin')->whereNull('from');

        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())]);
        // }

        if ($request->type) {
            // mengambil data berdasarkan filter
            $data = $data->where('transaction_category', $request->type)->with('to', 'subcashtransaction.akun', 'contact')->orderBy('id', 'desc')->get();
        } else {
            // mengambil semua data
            $data = $data->with('to', 'subcashtransaction.akun', 'contact')->orderBy('id', 'desc')->get();
        }

        // map data and return transaction_type
        $data = $data->map(function ($item) {
            // Map untuk transaction_name
            $transactionName = $item->subcashtransaction->isNotEmpty()
                ? $item->subcashtransaction->filter(function ($subItem) use ($item) {
                    return $item->id == $subItem->cashtransaction_id;
                })->map(function ($subItem) {
                    return $subItem->akun->name;
                })->first()
                : 'No Name';

            $childrenTotal = Cashtransaction::where('pay_debt_to', $item->id)->sum('cashout');

            $item->transaction_name = $transactionName;
            $item->paid = $childrenTotal;

            return $item;
        });

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

        return response($response, 200);
    }

    public function getCashOut(Request $request)
    {

        $data = Cashtransaction::whereNotNull('cashout')->whereNull('to');
        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())]);
        // }

        if ($request->type) {
            // mengambil data berdasarkan filter
            $data = $data->where('transaction_category', $request->type)->with('from', 'contact', 'subcashtransaction.akun')->orderBy('id', 'desc')->get();
        } else {
            // mengambil semua data
            $data = $data->with('from', 'contact', 'subcashtransaction.akun')->orderBy('id', 'desc')->get();
        }

        // Get language and mapping
        $licence = Licence::first();
        $companyType = $licence->company_type ?? null;
        $lang = self::getActiveLanguage();
        $langCode = $lang->code ?? 'id';
        $accountMapping = $this->loadAccountMapping($langCode);

        // map data and return transaction_type
        $data = $data->map(function ($item) use ($companyType, $accountMapping) {
            // Translate subcashtransaction akun names
            if ($item->subcashtransaction->isNotEmpty()) {
                $item->subcashtransaction->each(function ($subItem) use ($companyType, $accountMapping) {
                    if ($subItem->akun) {
                        $subItem->akun->rename = $this->translateAccountName($subItem->akun->name, $companyType, $accountMapping);
                    }
                });
            }

            // Map untuk transaction_name
            $transactionName = $item->subcashtransaction->isNotEmpty()
                ? $item->subcashtransaction->filter(function ($subItem) use ($item) {
                    return $item->id == $subItem->cashtransaction_id;
                })->map(function ($subItem) {
                    return $subItem->akun->rename ?? $subItem->akun->name;
                })->first()
                : 'No Name';

            $childrenTotal = Cashtransaction::where('receivable_id', $item->id)->sum('cashin');

            $item->transaction_name = $transactionName;
            $item->paid = $childrenTotal;

            return $item;
        });

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

        ];

        return response($response, 200);
    }

    public function getCashOutPerPage(Request $request)
    {
        $query = Cashtransaction::whereNotNull('cashout')->whereNull('to');

        // Filter by date range
        if (!empty($request->start_date) && !empty($request->end_date)) {
            $startDate = date('Y-m-d', strtotime($request->start_date));
            $endDate = date('Y-m-d', strtotime($request->end_date));
            $query = $query->whereBetween('date', [$startDate, $endDate]);
        }

        // Filter by type
        if ($request->type) {
            $query = $query->where('transaction_category', $request->type);
        }

        // Search functionality - sesuai dengan kriteria frontend
        if (!empty($request->search)) {
            $search = strtolower($request->search);
            $query = $query->where(function ($q) use ($search) {
                // Search by desc (description)
                $q->where('desc', 'like', "%{$search}%")
                    // Search by id
                    ->orWhere('id', 'like', "%{$search}%")
                    // Search by transaction_name (via subcashtransaction.akun.name)
                    ->orWhereHas('subcashtransaction.akun', function ($q) use ($search) {
                        $q->where('name', 'like', "%{$search}%");
                    })
                    // Search by subcashtransaction.desc
                    ->orWhereHas('subcashtransaction', function ($q) use ($search) {
                        $q->where('desc', 'like', "%{$search}%");
                    })
                    // Search by contact name
                    ->orWhereHas('contact', function ($q) use ($search) {
                        $q->where('name', 'like', "%{$search}%");
                    });
            });
        }

        // Eager load relationships dengan subcashtransaction yang lengkap
        $query = $query->with(['from', 'contact', 'subcashtransaction.akun'])
            ->orderBy('id', 'desc');

        // Paginate results
        $perPage = $request->limit ?: 10; // default 10 items per page
        $data = $query->paginate($perPage);

        // Transform data dengan menambahkan field debt dan transaction_name
        $transformedData = $data->getCollection()->map(function ($item) {
            // Map untuk transaction_name
            $transactionName = $item->subcashtransaction->isNotEmpty()
                ? $item->subcashtransaction->filter(function ($subItem) use ($item) {
                    return $item->id == $subItem->cashtransaction_id;
                })->map(function ($subItem) {
                    return $subItem->akun->name;
                })->first()
                : 'No Name';

            $childrenTotal = Cashtransaction::where('receivable_id', $item->id)->sum('cashin');

            // Calculate debt
            $debt = $item->cashout - $childrenTotal;

            $item->transaction_name = $transactionName;
            $item->paid = $childrenTotal;
            $item->debt = $debt < 0 ? 0 : $debt;

            // Untuk konsistensi dengan frontend, tambahkan field desc jika belum ada
            if (!isset($item->desc)) {
                $item->desc = $item->description;
            }

            return $item;
        });

        $customPagination = [
            'current_page' => $data->currentPage(),
            'data' => $transformedData,
            'from' => $data->firstItem(),
            'to' => $data->lastItem(),
            'per_page' => $data->perPage(),
            'total' => $data->total(),
            'last_page' => $data->lastPage(),
        ];

        $response = [
            'success' => true,
            'cashtransaction' => $customPagination,
            'message' => 'Data retrieved successfully'
        ];

        return response($response, 200);
    }

    public function getCashType(Request $request)
    {
        $data = Cashtransaction::where('transaction_category', $request->type)
            ->with('subcashtransaction', 'from', 'to', 'subcashtransaction.akun')
            ->get();

        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]);
        }

        $filteredData = $data->filter(function ($value) {
            $total = $value->to ? $value->cashin : $value->cashout;

            $childrenout = Cashtransaction::where('pay_debt_to', $value->id)
                ->with('subcashtransaction', 'from', 'to', 'subcashtransaction.akun')
                ->get();

            $childrenin = Cashtransaction::where('receivable_id', $value->id)
                ->with('subcashtransaction', 'from', 'to', 'subcashtransaction.akun')
                ->get();

            $children = $childrenout->isNotEmpty() ? $childrenout : $childrenin;

            $childrenTotal = 0;
            foreach ($children as $child) {
                $child["total"] = $child->to ? $child->cashin : $child->cashout;
                $childrenTotal += $child["total"];
            }

            $remainingTotal = $total - $childrenTotal;

            $value['total'] = $remainingTotal;
            $value['children'] = $children;

            return $remainingTotal >= 1;
        })->values();

        $response = [
            'success' => true,
            'cashtransaction' => $filteredData,
        ];

        return response($response, 200);
    }

    public function getCashSaldoAwal(Request $request)
    {

        $akun = Akun::where('name', 'Kas dan Bank')->first();
        $cash = Akun::where('perent_id', $akun->id)->get();
        $data = Cashtransaction::where('transaction_category', 'saldo_awal')
            ->whereHas('subcashtransaction', function ($query) use ($cash) {
                $query->whereIn('akun_id', $cash->pluck('id'));
            })
            ->orderBy('id', 'desc');

        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]);
        }

        $data = $data->with('subcashtransaction.akun')->get();

        $response = [
            'success' => true,
            'cashtransaction' => $data,
            'total' => $data->sum('cashin') ? $data->sum('cashin') : 0
        ];

        return response($response, 200);
    }

    public function getListCashIn(Request $request)
    {

        $data = Cashtransaction::whereNotNull('transaction_category');

        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]);
        }

        $data = $data->whereIn('transaction_category', [
            'pendapatan',
            'pendapatan_jasa',
            'pendapatan_penjualan',
            'pendapatan_item_masuk',
            'pendapatan_retur_out',
            'pendapatan_retur_in',
            'potongan_pembelian',
            'apresiasi_aset',
        ])
            ->orWhere(function ($query) {
                $query->where('transaction_category', 'jual_aset')
                    ->where('sell_asets', 'laba');
            })
            ->orderBy('id', 'desc')
            ->with('subcashtransaction.akun', 'stocktransaction')
            ->get();

        // Map data and return transaction_type
        $data = $data->map(function ($item, $key) {
            $newData = [
                'transaction_name' => $item->subcashtransaction->map(function ($item2) use ($item) {
                    if ($item->id == $item2->cashtransaction_id) {
                        return $item2->akun->name;
                    }
                })[0]
            ];

            if ($item->transaction_category === 'pendapatan_retur_in' && $item->stocktransaction) {
                $item->stocktransaction->total = -abs($item->stocktransaction->total);
            }

            // Merge with existing data
            return array_merge(
                json_decode($item, true),
                $newData
            );
        });

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

        return response($response, 200);
    }

    public function getListCashOut(Request $request)
    {

        $data = Cashtransaction::whereNotNull('transaction_category');

        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]);
        }

        $data = $data->whereIn('transaction_category', [
            'biaya',
            'biaya_item_keluar',
            'penyusutan_aset',
            'biaya_retur_out',
        ])
            ->orWhere(function ($query) {
                $query->where('transaction_category', 'jual_aset')
                    ->where('sell_asets', 'rugi');
            })
            ->orderBy('id', 'desc')
            ->with('subcashtransaction.akun', 'stocktransaction', 'contact')
            ->get();

        // Map data and return transaction_type
        $data = $data->map(function ($item, $key) {
            $newData = [
                'transaction_name' => $item->subcashtransaction->map(function ($item2) use ($item) {
                    if ($item->id == $item2->cashtransaction_id) {
                        return $item2->akun->name;
                    }
                })[0]
            ];

            // Merge with existing data
            return array_merge(
                json_decode($item, true),
                $newData
            );
        });

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

        return response($response, 200);
    }

    public function getListCashCash(Request $request)
    {
        $licence = Licence::first();
        $type = $licence->company_type ?? null;

        $lang = self::getActiveLanguage();
        $langCode = $lang->code ?? 'id';
        $mappingData = $this->loadDataMapping($langCode);

        $cashtransaction = Cashtransaction::where(function ($q) {
            $q->whereNotNull('from')
                ->orWhereNotNull('to');
        })->whereNotIn('transaction_category', ['biaya', 'bayar_pajak_final', 'beli_aset', 'pendapatan', 'jual_aset', 'biaya_produksi_aktual', 'bayar_hutang_pph', 'bayar_hutang_pph21', 'cicil_pph25', 'deposit_coretax']);

        $credit = Credit::where(function ($query) {
            $query->where('cashout_id', '!=', '20')
                ->orWhere('cashin_id', '!=', '51');
        });

        $creditcash = CreditCashTransaction::whereNotNull('id');

        $akun = Akun::where('name', 'Kas dan Bank')->first();
        $cash = Akun::where('perent_id', $akun->id)->get();

        $saldoawal = Cashtransaction::where('transaction_category', 'saldo_awal')
            ->whereHas('subcashtransaction', function ($query) use ($cash) {
                $query->whereIn('akun_id', $cash->pluck('id'));
            });

        if (!empty($request->start_date) && !empty($request->end_date)) {
            $start_date = date('Y-m-d', strtotime($request->start_date));
            $end_date = date('Y-m-d', strtotime($request->end_date));
            $cashtransaction->whereBetween('date', [$start_date, $end_date]);
            $credit->whereBetween('date', [$start_date, $end_date]);
            $creditcash->whereBetween('date', [$start_date, $end_date]);
            $saldoawal->whereBetween('date', [$start_date, $end_date]);
        }

        $cashTransactions = $cashtransaction->with('froms', 'tos', 'subcashtransaction')->get();
        $credits = $credit->with('cashin', 'cashout', 'stocktransaction')->get();
        $creditcashs = $creditcash->with('isfrom', 'isto', 'cashtransaction', 'cashtransaction.froms', 'cashtransaction.tos', 'cashtransaction.subcashtransaction')->get();
        $saldoawal = $saldoawal->with('subcashtransaction.akun')->get();

        // Proses data cashTransactions dengan map
        $cashTransactionsResults = $cashTransactions->map(function ($data) use ($type, $mappingData) {

            $category = 'Unknown';
            if ($data->transaction_category == 'tambah_modal') {
                if ($type === 'koperasi') {
                    $category = 'Simpanan Pokok';
                } else {
                    $category = 'Tambah Modal';
                }
            } elseif ($data->transaction_category == 'pendapatan') {
                $category = 'Catat Pendapatan';
            } elseif ($data->transaction_category == 'hutang') {
                $category = 'Catat Hutang';
            } elseif ($data->transaction_category == 'pembayaran_piutang') {
                $category = 'Pembayaran Piutang';
            } elseif ($data->transaction_category == 'jual_aset') {
                $category = 'Jual Aset';
            } elseif ($data->transaction_category == 'biaya') {
                $category = 'Biaya';
            } elseif ($data->transaction_category == 'bayar_hutang') {
                $category = 'Bayar Hutang';
            } elseif ($data->transaction_category == 'catat_piutang') {
                $category = 'Catat Piutang';
            } elseif ($data->transaction_category == 'tarik_laba') {
                $category = 'Tarik Laba';
            } elseif ($data->transaction_category == 'tarik_modal') {
                $category = 'Tarik Modal';
            } elseif ($data->transaction_category == 'beli_aset') {
                $category = 'Beli Aset';
            } elseif ($data->transaction_category == 'transfer_masuk') {
                $category = 'Transfer Kas';
            } elseif ($data->transaction_category == 'refund_pesanan_pembelian') {
                $category = 'Refund Pesanan Pembelian';
            } elseif ($data->transaction_category == 'refund_pesanan_penjualan') {
                $category = 'Refund Pesanan Penjualan';
            } elseif ($data->transaction_category == 'simpanan_wajib') {
                $category = 'Simpanan Wajib';
            } elseif ($data->transaction_category == 'prive') {
                $category = 'Prive';
            } elseif ($data->transaction_category == 'pengembalian_uang_muka') {
                $category = 'Pengambalian Uang Muka';
            } elseif ($data->transaction_category == 'pengembalian_hutang_pesanan_penjualan') {
                $category = 'Pengembalian Hutang Pesanan Penjualan';
            } elseif ($data->transaction_category == 'restitusi') {
                $category = 'Restitusi';
            }

            $category = $this->translateCashCategoryLabel($category, $mappingData);

            $cash_id = [];
            if ($data->froms) $cash_id[] = $data->froms;
            if ($data->tos) $cash_id[] = $data->tos;
            $cash_id = count($cash_id) === 1 ? $cash_id[0] : (count($cash_id) > 1 ? $cash_id : null);

            $desc_sub = $data->subcashtransaction->pluck('desc')->implode(', ');

            return [
                'id' => $data->id,
                'from' => $data->from,
                'to' => $data->to,
                'cash_id' => $cash_id,
                'category' => $category,
                'date' => $data->date,
                'staff' => $data->staff,
                'desc' => $data->desc ?? $desc_sub,
                'cashout' => $data->cashout ?: 0,
                'cashin' => $data->cashin ?: 0,
                'transfer' => $data->transfer ?: 0,
            ];
        });

        $creditcashResults = $creditcashs->map(function ($data) use ($mappingData) {
            $category = 'Unknown';
            $cashtransaction = $data->cashtransaction;

            if (!$cashtransaction) {
                return null;
            }

            if ($cashtransaction->transaction_category == 'biaya') {
                $category = 'Biaya';
            } elseif ($cashtransaction->transaction_category == 'beli_aset') {
                $category = 'Beli Aset';
            } elseif ($cashtransaction->transaction_category == 'pendapatan') {
                $category = 'Catat Pendapatan';
            } elseif ($cashtransaction->transaction_category == 'jual_aset') {
                $category = 'Jual Aset';
            } elseif ($cashtransaction->transaction_category == 'biaya_produksi_aktual') {
                $category = 'Biaya Produksi';
            } elseif ($cashtransaction->transaction_category == 'bayar_hutang_pph') {
                $category = 'Bayar PPh';
            } elseif ($cashtransaction->transaction_category == 'bayar_hutang_pph21') {
                $category = 'Bayar PPh 21';
            } elseif ($cashtransaction->transaction_category == 'cicil_pph25') {
                $category = 'Cicil PPh 25';
            } elseif ($cashtransaction->transaction_category == 'deposit_coretax') {
                $category = 'Deposit Coretax';
            } elseif ($cashtransaction->transaction_category == 'restitusi') {
                $category = 'Restitusi';
            }

            $category = $this->translateCashCategoryLabel($category, $mappingData);

            $desc_sub = $cashtransaction->subcashtransaction->pluck('desc')->implode(', ');

            return [
                'id' => $cashtransaction->id,
                'from' => $data->from_id,
                'to' => $data->to_id,
                'cash_id' => $data->isfrom ?: $data->isto,
                'category' => $category,
                'date' => $data->date,
                'staff' => $data->staff,
                'desc' => $desc_sub,
                'cashout' => $data->from_id ? $data->total : 0,
                'cashin' => $data->to_id ? $data->total : 0,
                'transfer' => 0,
            ];
        })->filter();

        // Proses data credits dengan map
        $creditsResults = $credits->map(function ($data) use ($mappingData) {
            $category = 'Unknown';
            $stockTransaction = $data->stocktransaction;

            if ($stockTransaction->cashin_id && $stockTransaction->pending && is_null($stockTransaction->return)) {
                $category = 'Pesanan Penjualan';
            } elseif ($stockTransaction->cashout_id && $stockTransaction->pending && is_null($stockTransaction->return)) {
                $category = 'Pesanan Pembelian';
            } elseif ($stockTransaction->cashin_id && $stockTransaction->return && is_null($stockTransaction->pending)) {
                $category = 'Return Penjualan';
            } elseif ($stockTransaction->cashout_id && $stockTransaction->return && is_null($stockTransaction->pending)) {
                $category = 'Return Pembelian';
            } elseif ($stockTransaction->cashin_id && is_null($stockTransaction->return) && is_null($stockTransaction->pending)) {
                $category = 'Penjualan';
            } elseif ($stockTransaction->cashout_id && is_null($stockTransaction->return) && is_null($stockTransaction->pending)) {
                $category = 'Pembelian';
            }

            $category = $this->translateCashCategoryLabel($category, $mappingData);

            return [
                'id' => $data->stockTransaction->id,
                'from' => $data->from,
                'to' => $data->to,
                'cash_id' => $data->cashin ?: $data->cashout,
                'category' => $category,
                'date' => $data->date,
                'staff' => $data->staff,
                'desc' => $data->stocktransaction->description,
                'cashout' => $data->cashout_id ? $data->total : 0,
                'cashin' => $data->cashin_id ? $data->total : 0,
                'transfer' => 0,
            ];
        });

        // Get initial balance transactions
        $saldoawal = $saldoawal->map(function ($data) use ($mappingData) {
            $category = 'Saldo Awal';
            $category = $this->translateCashCategoryLabel($category, $mappingData);
            return [
                'id' => null,
                'from' => $data->from,
                'to' => $data->to,
                'cash_id' => $data->subcashtransaction->first()->akun,
                'category' => $category,
                'date' => $data->date,
                'staff' => $data->staff,
                'desc' => $data->desc,
                'cashout' => $data->cashout ?: 0,
                'cashin' => $data->cashin ?: 0,
                'transfer' => $data->transfer ?: 0,
            ];
        });

        // Gabungkan hasil map
        $results = collect($cashTransactionsResults)
            ->merge(collect($creditsResults))
            ->merge(collect($creditcashResults))
            ->merge(collect($saldoawal));

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

        return response($response, 200);
    }

    public function getCashTransfer(Request $request)
    {
        // Load language settings
        $activeLang = self::getActiveLanguage();
        $langCode = $activeLang ? $activeLang->code : 'id';
        $accountMapping = $this->loadAccountMapping($langCode);

        // Get company type
        $licence = Licence::first();
        $companyType = $licence ? $licence->company_type : null;

        $data = Cashtransaction::whereNotNull('transfer')->whereNotNull('from')->whereNotNull('to');
        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]);
        }
        if ($request->filled('type')) {
            $data->where('transaction_category', $request->type);
        }
        // else{
        //     $data = $data->whereBetween('date',[date('Y-m-01',time()),date('Y-m-d',time())]);
        // }
        $data = $data->with('from', 'to')->orderBy('id', 'desc')->get();

        // Translate account names
        foreach ($data as $item) {
            if ($item->relationLoaded('from') && $item->getRelation('from')) {
                $fromAccount = $item->getRelation('from');
                $fromAccount->name = $this->translateAccountName($fromAccount->name, $companyType, $accountMapping);
            }
            if ($item->relationLoaded('to') && $item->getRelation('to')) {
                $toAccount = $item->getRelation('to');
                $toAccount->name = $this->translateAccountName($toAccount->name, $companyType, $accountMapping);
            }
        }

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

        ];

        return response($response, 200);
    }

    public function getCashTransactionDetail(Request $request)
    {
        // Load language settings
        $activeLang = self::getActiveLanguage();
        $langCode = $activeLang ? $activeLang->code : 'id';
        $accountMapping = $this->loadAccountMapping($langCode);

        // Get company type for specific translations
        $licence = Licence::first();
        $companyType = $licence->company_type ?? null;

        $data = Cashtransaction::where('id', $request->id)
            ->with('from', 'to', 'contact', 'subcashtransaction.akun', 'credit', 'credit.isfrom', 'credit.isto')
            ->get();

        $data = $data->map(function ($item) use ($accountMapping, $companyType) {
            // Translate credit isfrom and isto
            if ($item->credit) {
                foreach ($item->credit as $credit) {
                    if ($credit->isfrom) {
                        $originalName = $credit->isfrom->name;
                        $translatedName = $this->translateAccountName($originalName, $companyType, $accountMapping);
                        $credit->isfrom->rename = $translatedName;
                    }
                    if ($credit->isto) {
                        $originalName = $credit->isto->name;
                        $translatedName = $this->translateAccountName($originalName, $companyType, $accountMapping);
                        $credit->isto->rename = $translatedName;
                    }
                }
            }
            return $item;
        });

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

        ];

        return response($response, 200);
    }

    // Dalam proses pembuatan untuk menu laporan kas
    public function getCashAndCredit(Request $request)
    {
        // Mengambil data dari tabel cashtransaction dan melakukan filter
        $cash = Cashtransaction::where(function ($query) {
            $query->whereNotNull('to')
                ->orWhereNotNull('from');
        })->with('from', 'to', 'subcashtransaction.akun')->get();

        // Mengambil data dari tabel credit dan melakukan filter
        $credit = Credit::where(function ($query) {
            $query->whereNotNull('cashin_id')
                ->orWhereNotNull('cashout_id');
        })->with('stocktransaction', 'cashin', 'cashout')->get();

        $data = [];

        foreach ($cash as $cashItem) {
            $cashItem->type_transaction = $cashItem->transaction_category;
            $data[] = $cashItem;
        }

        foreach ($credit as $creditItem) {
            if (!is_null($creditItem->stocktransaction->return)) {
                $creditItem->type_transaction = $creditItem->stocktransaction->type == 'out' ? 'retur_pembelian' : 'retur_penjualan';
            } elseif (!is_null($creditItem->stocktransaction->pending)) {
                if (!is_null($creditItem->cashout_id)) {
                    $creditItem->type_transaction = 'pesanan_pembelian';
                } elseif (!is_null($creditItem->cashin_id)) {
                    $creditItem->type_transaction = 'pesanan_penjualan';
                }
            } elseif (is_null($creditItem->stocktransaction->return) && is_null($creditItem->stocktransaction->pending)) {
                if (!is_null($creditItem->cashout_id)) {
                    $creditItem->type_transaction = 'pembelian';
                } elseif (!is_null($creditItem->cashin_id)) {
                    $creditItem->type_transaction = 'penjualan';
                }
            }

            $data[] = $creditItem;
        }

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

        return response($response, 200);
    }

    public function getCashStockTo(Request $request)
    {

        $data = Cashtransaction::with('to', 'subcashtransaction.akun', 'stocktransaction')->where('stocktransaction_id', $request->id)->where('transaction_category', '=', 'pengembalian_uang_muka');

        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]);
        }

        $data = $data->get();

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

        return response($response, 200);
    }

    public function getCashStockFrom(Request $request)
    {

        $data = Cashtransaction::with('from', 'subcashtransaction.akun', 'stocktransaction')->where('stocktransaction_id', $request->id)->where('transaction_category', '=', 'pengembalian_hutang_pesanan_penjualan');

        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]);
        }

        $data = $data->get();

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

        return response($response, 200);
    }

    public function getCashFlow(Request $request)
    {
        $licence = Licence::first();
        $type = $licence->company_type ?? null;

        // Get active language
        $lang = self::getActiveLanguage();
        $langCode = $lang->code ?? 'id';

        // Load mapping data based on language
        $mappingData = $this->loadDataMapping($langCode);

        $year = !empty($request->year) ? $request->year : date('Y');
        $previousYear = $year - 1;

        $start_date = date('Y-m-d', strtotime("{$year}-01-01"));
        $end_date = date('Y-m-d', strtotime("{$year}-12-31"));
        $prev_start_date = date('Y-m-d', strtotime("{$previousYear}-01-01"));
        $prev_end_date = date('Y-m-d', strtotime("{$previousYear}-12-31"));

        $cashAccountIds = Akun::where('iscash', true)->pluck('id');

        // Helper function to calculate sums
        $calculateSums = function ($start_date, $end_date) use ($type, $mappingData, $cashAccountIds) {
            $pembelian = Credit::whereNotNull('cashout_id')
                ->where('cashout_id', '!=', '20')
                ->whereHas('stocktransaction', function ($stock) {
                    $stock->whereNotNull('cashout_id')->whereNull('nonmoney')->whereNull('return');
                })->whereBetween('date', [$start_date, $end_date])->sum('total');

            $penjualan = Credit::whereNotNull('cashin_id')
                ->where('cashin_id', '!=', '51')
                ->whereHas('stocktransaction', function ($stock) {
                    $stock->whereNotNull('cashin_id')->whereNull('nonmoney')->whereNull('return');
                })->whereBetween('date', [$start_date, $end_date])->sum('total');

            $returnpembelian = Credit::whereNotNull('cashin_id')
                ->whereHas('stocktransaction', function ($stock) {
                    $stock->whereNotNull('cashin_id')->whereNotNull('return');
                })->whereBetween('date', [$start_date, $end_date])->sum('total');

            $returnpenjualan = Credit::whereNotNull('cashout_id')
                ->whereHas('stocktransaction', function ($stock) {
                    $stock->whereNotNull('cashout_id')->whereNotNull('return');
                })->whereBetween('date', [$start_date, $end_date])->sum('total');

            $refundpesananpembelian = Cashtransaction::where('transaction_category', '=', 'refund_pesanan_pembelian')
                ->whereBetween('date', [$start_date, $end_date])->sum('cashin');

            $refundpesananpenjualan = Cashtransaction::where('transaction_category', '=', 'refund_pesanan_penjualan')
                ->whereBetween('date', [$start_date, $end_date])->sum('cashout');

            $pemngembalianuangmuka = Cashtransaction::where('transaction_category', '=', 'pengembalian_uang_muka')
                ->whereBetween('date', [$start_date, $end_date])->sum('cashin');

            $pengembalianhutangpesananpenjualan = Cashtransaction::where('transaction_category', '=', 'pengembalian_hutang_pesanan_penjualan')
                ->whereBetween('date', [$start_date, $end_date])->sum('cashout');

            $pendapatanCash = Cashtransaction::where('transaction_category', '=', 'pendapatan')
                ->whereDoesntHave('credit')
                ->whereBetween('date', [$start_date, $end_date])->sum('cashin');
            $pendapatanCreditCash = CreditCashTransaction::whereIn('to_id', $cashAccountIds)
                ->whereHas('cashtransaction', function ($q) {
                    $q->where('transaction_category', 'pendapatan');
                })->whereBetween('date', [$start_date, $end_date])->sum('total');
            $pendapatan = $pendapatanCash + $pendapatanCreditCash;

            $biayaCash = Cashtransaction::whereIn('transaction_category', ['biaya', 'bayar_pajak_final'])
                ->whereDoesntHave('credit')
                ->whereBetween('date', [$start_date, $end_date])->sum('cashout');
            $biayaCreditCash = CreditCashTransaction::whereIn('from_id', $cashAccountIds)
                ->whereHas('cashtransaction', function ($q) {
                    $q->whereIn('transaction_category', ['biaya', 'bayar_pajak_final']);
                })->whereBetween('date', [$start_date, $end_date])->sum('total');
            $biaya = $biayaCash + $biayaCreditCash;

            $biayaproduksiCash = Cashtransaction::where('transaction_category', '=', 'biaya_produksi_aktual')
                ->whereDoesntHave('credit')
                ->whereBetween('date', [$start_date, $end_date])->sum('cashout');
            $biayaproduksiCreditCash = CreditCashTransaction::whereIn('from_id', $cashAccountIds)
                ->whereHas('cashtransaction', function ($q) {
                    $q->where('transaction_category', 'biaya_produksi_aktual');
                })->whereBetween('date', [$start_date, $end_date])->sum('total');
            $biayaproduksi = $biayaproduksiCash + $biayaproduksiCreditCash;

            $jualasetCash = Cashtransaction::where('transaction_category', '=', 'jual_aset')
                ->whereDoesntHave('credit')
                ->whereBetween('date', [$start_date, $end_date])->sum('cashin');
            $jualasetCreditCash = CreditCashTransaction::whereIn('to_id', $cashAccountIds)
                ->whereHas('cashtransaction', function ($q) {
                    $q->where('transaction_category', 'jual_aset');
                })->whereBetween('date', [$start_date, $end_date])->sum('total');
            $jualaset = $jualasetCash + $jualasetCreditCash;

            $beliasetCash = Cashtransaction::where('transaction_category', '=', 'beli_aset')
                ->whereDoesntHave('credit')
                ->whereBetween('date', [$start_date, $end_date])->sum('cashout');
            $beliasetCreditCash = CreditCashTransaction::whereIn('from_id', $cashAccountIds)
                ->whereHas('cashtransaction', function ($q) {
                    $q->where('transaction_category', 'beli_aset');
                })->whereBetween('date', [$start_date, $end_date])->sum('total');
            $beliaset = $beliasetCash + $beliasetCreditCash;

            $tambahmodal = Cashtransaction::where('transaction_category', '=', 'tambah_modal')
                ->whereBetween('date', [$start_date, $end_date])->sum('cashin');

            $tarikmodal = Cashtransaction::where('transaction_category', '=', 'tarik_modal')
                ->whereBetween('date', [$start_date, $end_date])->sum('cashout');

            $tariklaba = Cashtransaction::where('transaction_category', '=', 'tarik_laba')
                ->whereBetween('date', [$start_date, $end_date])->sum('cashout');

            $hutang = Cashtransaction::where('transaction_category', '=', 'hutang')
                ->whereBetween('date', [$start_date, $end_date])->sum('cashin');

            $bayarhutang = Cashtransaction::where('transaction_category', '=', 'bayar_hutang')
                ->whereBetween('date', [$start_date, $end_date])->sum('cashout');

            $piutang = Cashtransaction::where('transaction_category', '=', 'catat_piutang')
                ->whereBetween('date', [$start_date, $end_date])->sum('cashout');

            $pembayaranpiutang = Cashtransaction::where('transaction_category', '=', 'pembayaran_piutang')
                ->whereBetween('date', [$start_date, $end_date])->sum('cashin');

            $simpananwajib = Cashtransaction::where('transaction_category', '=', 'simpanan_wajib')
                ->whereBetween('date', [$start_date, $end_date])->sum('cashin');

            $prive = Cashtransaction::where('transaction_category', '=', 'prive')
                ->whereBetween('date', [$start_date, $end_date])->sum('cashout');

            $bayarhutangpph = CreditCashTransaction::whereIn('from_id', $cashAccountIds)
                ->whereHas('cashtransaction', function ($q) {
                    $q->where('transaction_category', 'bayar_hutang_pph');
                })->whereBetween('date', [$start_date, $end_date])->sum('total');

            $bayarhutangpph21 = CreditCashTransaction::whereIn('from_id', $cashAccountIds)
                ->whereHas('cashtransaction', function ($q) {
                    $q->where('transaction_category', 'bayar_hutang_pph21');
                })->whereBetween('date', [$start_date, $end_date])->sum('total');
            $totalbayarhutangpph = $bayarhutangpph + $bayarhutangpph21;

            $cicilpph25 = CreditCashTransaction::whereIn('from_id', $cashAccountIds)
                ->whereHas('cashtransaction', function ($q) {
                    $q->where('transaction_category', 'cicil_pph25');
                })->whereBetween('date', [$start_date, $end_date])->sum('total');

            $depositcoretax = CreditCashTransaction::whereIn('from_id', $cashAccountIds)
                ->whereHas('cashtransaction', function ($q) {
                    $q->where('transaction_category', 'deposit_coretax');
                })->whereBetween('date', [$start_date, $end_date])->sum('total');

            $restitusi = Cashtransaction::where('transaction_category', '=', 'restitusi')
                ->whereBetween('date', [$start_date, $end_date])->sum('transfer');

            // Build data structure with original names (will be translated later)
            $data = [
                'operasi' => [
                    'data' => [
                        ['name' => 'Penerimaan Kas Dari Pelanggan', 'total' => $penjualan],
                        ['name' => 'Pendapatan Lain', 'total' => $pendapatan],
                        ['name' => 'Penerimaan Kas dari Retur Pembelian', 'total' => $returnpembelian],
                        ['name' => 'Penerimaan Kas dari Pembatalan Pesanan', 'total' => $refundpesananpembelian],
                        ['name' => 'Penerimaan Kas dari Pengembalian Dana Supplier', 'total' => $pemngembalianuangmuka],
                        ['name' => 'Penerimaan Restitusi Pajak', 'total' => $restitusi],
                        ['name' => 'Pembayaran Kepada Supplier', 'total' => $pembelian],
                        ['name' => 'Biaya', 'total' => $biaya],
                        ['name' => 'Biaya Produksi', 'total' => $biayaproduksi],
                        ['name' => 'Pengeluaran Kas untuk Retur Penjualan', 'total' => $returnpenjualan],
                        ['name' => 'Pengeluaran Kas atas Pesanan Yang Tidak Dapat Dipenuhi', 'total' => $refundpesananpenjualan],
                        ['name' => 'Pengeluaran Kas untuk Penyesuaian Harga Penjualan', 'total' => $pengembalianhutangpesananpenjualan],
                        ['name' => 'Pembayaran Pajak Penghasilan', 'total' => $totalbayarhutangpph],
                        ['name' => 'Pembayaran Uang Muka PPh Pasal 25', 'total' => $cicilpph25],
                        ['name' => 'Penyetoran Deposit Pajak Ke Coretax', 'total' => $depositcoretax],
                    ],
                    'total' => $penjualan + $pendapatan + $returnpembelian + $refundpesananpembelian + $pemngembalianuangmuka + $restitusi - $pembelian - $biaya - $biayaproduksi - $returnpenjualan - $refundpesananpenjualan - $pengembalianhutangpesananpenjualan - $totalbayarhutangpph - $cicilpph25 - $depositcoretax,
                ],
                'investasi' => [
                    'data' => [
                        ['name' => 'Jual Aset', 'total' => $jualaset],
                        ['name' => 'Pembayaran Piutang Oleh Debitur', 'total' => $pembayaranpiutang],
                        ['name' => 'Beli Aset', 'total' => $beliaset],
                        ['name' => 'Pemberian Pinjaman Kepada Debitur', 'total' => $piutang],
                    ],
                    'total' => $jualaset + $pembayaranpiutang - $beliaset - $piutang,
                ],
                'pendanaan' => [
                    'data' => [
                        ['name' => ($type === 'koperasi') ? 'Penerimaan Simpanan Pokok Anggota' : 'Penerimaan Modal', 'total' => $tambahmodal],
                        ['name' => 'Penerimaan Simpanan Wajib Anggota', 'total' => $simpananwajib],
                        ['name' => 'Penerimaan Pinjaman', 'total' => $hutang],
                        ['name' => ($type === 'koperasi') ? 'Distribusi SHU Kepada Anggota' : 'Distribusi Laba Kepada Investor', 'total' => $tariklaba],
                        ['name' => ($type === 'koperasi') ? 'Pengembalian Simpanan Anggota' : 'Penarikan Modal Oleh Investor', 'total' => $tarikmodal],
                        ['name' => 'Pengambilan Prive oleh Pemilik', 'total' => $prive],
                        ['name' => 'Pembayaran Utang', 'total' => $bayarhutang],
                    ],
                    'total' => $tambahmodal + $simpananwajib + $hutang - $tariklaba - $tarikmodal - $prive - $bayarhutang,
                ],
            ];

            return $data;
        };

        $currentYearData = $calculateSums($start_date, $end_date);
        $previousYearData = $calculateSums($prev_start_date, $prev_end_date);

        // Apply translations to both current and previous year data
        $this->applyCashFlowTranslations($currentYearData, $type, $mappingData);
        $this->applyCashFlowTranslations($previousYearData, $type, $mappingData);

        return response([
            'success' => true,
            'currentYear' => $currentYearData,
            'previousYear' => $previousYearData,
            'language' => $langCode,
            'company_type' => $type
        ], 200);
    }

    public function createCashIn(Request $request)
    {
        $request->validate([
            'to' => [
                Rule::requiredIf(!in_array($request->type, ['pendapatan', 'jual_aset'])),
                'nullable'
            ],
            'contact_id' => 'nullable',
            'keterangan' => 'nullable',
            'desc' => 'nullable',
            'staff' => 'nullable',
            'pph23_amount' => 'nullable',
            'pph22_amount' => 'nullable',
            'pph4_2_amount' => 'nullable',
            'pph4_2_amount_v2' => 'nullable',
            'pph21_amount' => 'nullable',
            'transaction_id' => 'nullable',
            'jumlah_bayar' => 'nullable',
            'date' => 'required',
            'type' => 'required',
            'akun_id.*' => 'required',
            'total.*'  => 'required|numeric',
        ]);

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

        try {
            if (empty($request->to) && in_array($request->type, ['pendapatan', 'jual_aset'])) {
                $defaultCashAccount = Akun::where('iscash', true)->first();
                if (!$defaultCashAccount) {
                    DB::rollback();
                    return response()->json([
                        'status' => 'error',
                        'message' => 'Tidak ditemukan akun kas default'
                    ], 400);
                }
                $request->merge(['to' => $defaultCashAccount->id]);
            }

            // Pengecekan tambahan untuk memastikan request lengkap
            if (!$request->has(['to', 'keterangan', 'desc', 'staff', 'date', 'type', 'akun_id', 'total'])) {
                DB::rollback();
                return response()->json(['message' => $request->all()], 400);
            }

            $uang = $request->uang;
            $cash = new Cashtransaction;
            $cash->to = $request->to;
            $cash->staff = $request->staff;
            $cash->desc = $request->keterangan;
            $cash->contact_id = $request->contact_id;
            $cash->date = date("Y-m-d", strtotime($request->date));
            $cash->transaction_category = $request->type;
            $cash->receivable_id = $request->transaction_id;
            $cash->pph23_amount = $request->pph23_amount;
            $cash->pph22_amount = $request->pph22_amount;
            $cash->pph4_2_amount = $request->pph4_2_amount;
            $cash->pph4_2_amount_v2 = $request->pph4_2_amount_v2;
            $cash->pph21_amount = $request->pph21_amount;

            // add trx id if jual aset
            if ($request->type === 'jual_aset' || $request->type === 'penyusutan_aset' || $request->type === 'apresiasi_aset' || $request->type === 'penyusutan_aset_produksi') {
                $akId = $request->akun_id[0];
                $cId = Subcashtransaction::where('akun_id', $akId)->first();
                $cash->transaction_ref = $cId->cashtransaction_id;
            }
            $cash->cashin = 0;
            $cash->save();

            // switch case berdasarkan type
            switch ($request->type) {
                case 'modal_aset':
                    $sub = new Subcashtransaction;
                    $sub->cashtransaction_id = $cash->id;
                    $sub->akun_id = $request->to;
                    $sub->desc = null;
                    $sub->total = $request->total[0];
                    $sub->save();
                    break;

                case 'penyusutan_aset':
                case 'apresiasi_aset':
                case 'penyusutan_aset_produksi':
                    $sub = new Subcashtransaction;
                    $sub->cashtransaction_id = $cash->id;
                    $sub->akun_id = $request->to;
                    $sub->desc = null;
                    $sub->total = $request->uang;
                    $sub->save();
                    break;

                default:
                    break;
            }

            $data = $request->akun_id;
            $total = 0;
            $subtransaction = [];

            function rekursif($akun, $sub, $name)
            {
                foreach ($akun as $key => $value) {
                    if (!empty($value->children)) {
                        rekursif($value->children, $sub, $name);
                    }
                    if ($value->name == $name->name) {
                        $sub->total = -1 * $sub->total;
                    }
                }
            }

            foreach ($data as $key => $value) {
                $sub = new Subcashtransaction;
                $sub->cashtransaction_id = $cash->id;
                $sub->akun_id = $request->akun_id[$key];
                if ($request->type === 'jual_aset' || $request->type === 'penyusutan_aset' || $request->type === 'apresiasi_aset' || $request->type === 'penyusutan_aset_produksi') {
                    $sub->desc = $request->desc;
                } else {
                    $sub->desc = $request->desc[$key];
                }

                $sub->total = $request->total[$key];
                $akun = Akun::where('name', 'Harta')->with(str_repeat('children.', 10))->get();
                $nama = Akun::find($sub->akun_id);

                rekursif($akun, $sub, $nama);
                $sub->save();

                $subtransaction[] = $sub;
                $akun = Akun::find($sub->akun_id);
                $akun->total = $akun->total + $request->total[$key];
                $akun->save();

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

                if ($request->type === 'jual_aset') {
                    $cash = Cashtransaction::find($cash->id);
                    $cash->sell_asets = $akun->id === 115 ? 'rugi' : 'laba';
                    $cash->save();
                }
            }

            $cash = Cashtransaction::find($cash->id);
            $cash->cashin = in_array($request->type, ['pendapatan', 'jual_aset']) ? $request->jumlah_bayar : ($uang ? $uang : $cash->cashin + $total);
            $cash->cashout = 0;
            $cash->transfer = 0;
            $cash->save();

            $akun = Akun::find($request->to);
            $akun->total = $akun->total + $total;
            $akun->save();

            if (in_array($request->type, ['pendapatan', 'jual_aset'])) {
                $cash = Cashtransaction::find($cash->id);
                $cash->total += $request->type === 'jual_aset' ? $uang : $total;
                $cash->save();

                $creditcash = new CreditCashTransaction;
                $creditcash->cashtransaction_id = $cash->id;
                $creditcash->to_id = $request->to;
                $creditcash->total = $cash->cashin;
                $creditcash->staff = $request->staff;
                $creditcash->date = date("Y-m-d", strtotime($request->date));
                $creditcash->save();
            }

            if ($cash->pph23_amount > 0) {
                $akun = Akun::where('name', 'Piutang_PPh_Pasal_23')->first();
                $creditcash = new CreditCashTransaction;
                $creditcash->cashtransaction_id = $cash->id;
                $creditcash->to_id = $akun->id;
                $creditcash->total = $cash->pph23_amount;
                $creditcash->staff = $request->staff;
                $creditcash->date = date("Y-m-d", strtotime($request->date));
                $creditcash->save();
            }

            if ($cash->pph22_amount > 0) {
                $akun = Akun::where('name', 'Uang_Muka_PPh_22')->first();
                $creditcash = new CreditCashTransaction;
                $creditcash->cashtransaction_id = $cash->id;
                $creditcash->to_id = $akun->id;
                $creditcash->total = $cash->pph22_amount;
                $creditcash->staff = $request->staff;
                $creditcash->date = date("Y-m-d", strtotime($request->date));
                $creditcash->save();
            }

            if ($cash->pph4_2_amount > 0) {
                $akun = Akun::where('name', 'Biaya_PPh_4_2')->first();
                $creditcash = new CreditCashTransaction;
                $creditcash->cashtransaction_id = $cash->id;
                $creditcash->to_id = $akun->id;
                $creditcash->total = $cash->pph4_2_amount;
                $creditcash->staff = $request->staff;
                $creditcash->date = date("Y-m-d", strtotime($request->date));
                $creditcash->save();
            }

            if ($cash->pph4_2_amount_v2 > 0) {
                $akunv1 = Akun::where('name', 'Biaya_PPh_4_2')->first();
                $akunv2 = Akun::where('name', 'Utang_PPh_Pasal_4_ayat_2')->first();

                $creditcash = new CreditCashTransaction;
                $creditcash->cashtransaction_id = $cash->id;
                $creditcash->to_id = $akunv1->id;
                $creditcash->total = $cash->pph4_2_amount_v2;
                $creditcash->staff = $request->staff;
                $creditcash->date = date("Y-m-d", strtotime($request->date));
                $creditcash->save();

                $creditcash = new CreditCashTransaction;
                $creditcash->cashtransaction_id = $cash->id;
                $creditcash->to_id = $akunv2->id;
                $creditcash->total = $cash->pph4_2_amount_v2;
                $creditcash->staff = $request->staff;
                $creditcash->date = date("Y-m-d", strtotime($request->date));
                $creditcash->save();
            }

            if ($cash->pph21_amount > 0) {
                $akun = Akun::where('name', 'Piutang_PPh_21')->first();
                $creditcash = new CreditCashTransaction;
                $creditcash->cashtransaction_id = $cash->id;
                $creditcash->to_id = $akun->id;
                $creditcash->total = $cash->pph21_amount;
                $creditcash->staff = $request->staff;
                $creditcash->date = date("Y-m-d", strtotime($request->date));
                $creditcash->save();
            }

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

            $response = [
                'success' => true,
                'cashtransaction'  => $cash,
                'subcashtransaction'  => $subtransaction,
            ];

            return response($response, 200);
        } catch (\Exception $e) {
            // Rollback transaction jika terjadi error
            DB::rollback();

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

    public function createCashOut(Request $request)
    {
        $request->validate([
            'from' => [
                Rule::requiredIf(!in_array($request->type, ['biaya', 'bayar_pajak_final', 'bayar_hutang_pph21', 'bayar_hutang_pph', 'beli_aset', 'tarik_dividen', 'biaya_produksi_aktual', 'deposit_coretax'])),
                'nullable'
            ],
            'keterangan' => 'nullable',
            'desc' => 'nullable',
            'staff' => 'nullable',
            'transaction_id' => 'nullable',
            'contact_id' => 'nullable',
            'jumlah_bayar' => 'nullable',
            'pph23_amount' => 'nullable',
            'pph22_amount' => 'nullable',
            'pph22_amount_v2' => 'nullable',
            'pph4_2_amount' => 'nullable',
            'pph21_amount' => 'nullable',
            'pph26_amount' => 'nullable',
            'date' => 'required',
            'type' => 'required',
            'akun_id.*' => 'required',
            'total.*'  => 'required|numeric',
        ]);

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

        try {
            if (empty($request->from) && in_array($request->type, ['biaya', 'bayar_pajak_final', 'bayar_hutang_pph', 'bayar_hutang_pph21', 'beli_aset', 'tarik_dividen', 'biaya_produksi_aktual', 'cicil_pph25', 'deposit_coretax'])) {
                $defaultCashAccount = Akun::where('iscash', true)->first();
                if (!$defaultCashAccount) {
                    DB::rollback();
                    return response()->json([
                        'status' => 'error',
                        'message' => 'Tidak ditemukan akun kas default'
                    ], 400);
                }
                $request->merge(['from' => $defaultCashAccount->id]);
            }

            $cash = new Cashtransaction;
            $cash->from = $request->from;
            $cash->staff = $request->staff;
            $cash->contact_id = $request->contact_id;
            $cash->desc = $request->keterangan;
            $cash->date = date("Y-m-d", strtotime($request->date));
            $cash->transaction_category = $request->type;
            $cash->pay_debt_to = $request->transaction_id;
            $cash->pph23_amount = $request->pph23_amount;
            $cash->pph22_amount = $request->pph22_amount;
            $cash->pph22_amount_v2 = $request->pph22_amount_v2;
            $cash->pph4_2_amount = $request->pph4_2_amount;
            $cash->pph21_amount = $request->pph21_amount;
            $cash->pph26_amount = $request->pph26_amount;
            $cash->cashout = 0;
            $cash->save();

            $data = $request->akun_id;
            $total = 0;
            $subtransaction = [];

            function rekursif($akun, $sub, $name)
            {
                foreach ($akun as $key => $value) {
                    if (!empty($value->children)) {
                        rekursif($value->children, $sub, $name);
                    }
                    if ($value->name == $name->name) {
                        $sub->total = -1 * $sub->total;
                    }
                }
            }

            foreach ($data as $key => $value) {
                $sub = new Subcashtransaction;
                $sub->cashtransaction_id = $cash->id;
                $sub->akun_id = $request->akun_id[$key];
                $sub->total = $request->total[$key];
                $sub->desc = $request->desc[$key];

                $akun = Akun::where('name', 'Modal')->with(str_repeat('children.', 10))->get();
                $akun2 = Akun::where('name', 'Kewajiban')->with(str_repeat('children.', 10))->get();
                $nama = Akun::find($sub->akun_id);

                rekursif($akun, $sub, $nama);
                rekursif($akun2, $sub, $nama);
                $sub->save();

                $subtransaction[] = $sub;
                $akun = Akun::find($sub->akun_id);
                $akun->total = $akun->total + $request->total[$key];
                $akun->save();

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

            $cash = Cashtransaction::find($cash->id);
            $cash->cashout = in_array($request->type, ['biaya', 'bayar_pajak_final', 'beli_aset', 'tarik_dividen', 'biaya_produksi_aktual', 'cicil_pph25', 'deposit_coretax']) ? $request->jumlah_bayar : $cash->cashout + $total;
            $cash->cashin = 0;
            $cash->transfer = 0;
            $cash->total = 0;
            $cash->save();

            if (in_array($request->type, ['biaya', 'bayar_pajak_final', 'beli_aset', 'tarik_dividen', 'biaya_produksi_aktual', 'cicil_pph25', 'deposit_coretax'])) {
                $cash = Cashtransaction::find($cash->id);
                $cash->total = $cash->total + $total;
                $cash->save();

                $creditcash = new CreditCashTransaction;
                $creditcash->cashtransaction_id = $cash->id;
                $creditcash->from_id = $request->from;
                $creditcash->total = $cash->cashout;
                $creditcash->staff = $request->staff;
                $creditcash->date = date("Y-m-d", strtotime($request->date));
                $creditcash->save();
            }

            if (in_array($request->type, ['bayar_hutang_pph', 'bayar_hutang_pph21'])) {
                $creditcash = new CreditCashTransaction;
                $creditcash->cashtransaction_id = $cash->id;
                $creditcash->from_id = $request->from;
                $creditcash->total = $cash->cashout;
                $creditcash->staff = $request->staff;
                $creditcash->date = date("Y-m-d", strtotime($request->date));
                $creditcash->save();
            }

            if ($cash->pph23_amount > 0) {
                $akun = Akun::where('name', 'Utang_PPh_23')->first();
                $creditcash = new CreditCashTransaction;
                $creditcash->cashtransaction_id = $cash->id;
                $creditcash->from_id = $akun->id;
                $creditcash->total = $cash->pph23_amount;
                $creditcash->staff = $request->staff;
                $creditcash->date = date("Y-m-d", strtotime($request->date));
                $creditcash->save();
            }

            if ($cash->pph21_amount > 0) {
                $akun = Akun::where('name', 'Utang_PPh_21')->first();
                $creditcash = new CreditCashTransaction;
                $creditcash->cashtransaction_id = $cash->id;
                $creditcash->from_id = $akun->id;
                $creditcash->total = $cash->pph21_amount;
                $creditcash->staff = $request->staff;
                $creditcash->date = date("Y-m-d", strtotime($request->date));
                $creditcash->save();
            }

            if ($cash->pph4_2_amount > 0) {
                $akun = Akun::where('name', 'Utang_PPh_Pasal_4_ayat_2')->first();
                $creditcash = new CreditCashTransaction;
                $creditcash->cashtransaction_id = $cash->id;
                $creditcash->from_id = $akun->id;
                $creditcash->total = $cash->pph4_2_amount;
                $creditcash->staff = $request->staff;
                $creditcash->date = date("Y-m-d", strtotime($request->date));
                $creditcash->save();
            }

            if ($cash->pph22_amount > 0) {
                $akun = Akun::where('name', 'Utang_PPh_22')->first();
                $creditcash = new CreditCashTransaction;
                $creditcash->cashtransaction_id = $cash->id;
                $creditcash->from_id = $akun->id;
                $creditcash->total = $cash->pph22_amount;
                $creditcash->staff = $request->staff;
                $creditcash->date = date("Y-m-d", strtotime($request->date));
                $creditcash->save();
            }

            if ($cash->pph22_amount_v2 > 0) {
                $cash = Cashtransaction::find($cash->id);
                $cash->total += $cash->pph22_amount_v2;
                $cash->save();

                $akun = Akun::where('name', 'Uang_Muka_PPh_22')->first();
                $creditcash = new CreditCashTransaction;
                $creditcash->cashtransaction_id = $cash->id;
                $creditcash->from_id = $akun->id;
                $creditcash->total = $cash->pph22_amount_v2;
                $creditcash->staff = $request->staff;
                $creditcash->date = date("Y-m-d", strtotime($request->date));
                $creditcash->save();
            }

            if ($cash->pph26_amount > 0) {
                $akun = Akun::where('name', 'Utang_PPh_26')->first();
                $creditcash = new CreditCashTransaction;
                $creditcash->cashtransaction_id = $cash->id;
                $creditcash->from_id = $akun->id;
                $creditcash->total = $cash->pph26_amount;
                $creditcash->staff = $request->staff;
                $creditcash->date = date("Y-m-d", strtotime($request->date));
                $creditcash->save();
            }

            $akun = Akun::find($request->from);
            if (!$akun) {
                DB::rollback();
                return response()->json([
                    'status' => 'error',
                    'message' => 'Akun sumber tidak ditemukan'
                ], 404);
            }

            $akun->total = $akun->total - $total;
            $akun->save();

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

            $response = [
                'success' => true,
                'cashtransaction'  => $cash,
                'subcashtransaction'  => $subtransaction,
            ];

            return response($response, 200);
        } catch (\Exception $e) {
            // Rollback transaction jika terjadi error
            DB::rollback();

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

    public function createCashTransfer(Request $request)
    {
        $request->validate([
            'to' => 'required',
            'from' => 'required',
            'date' => 'required',
            'type' => 'required',
            'desc' => 'nullable',
            'staff' => 'required',
            'total'  => 'required|numeric',
        ]);

        DB::beginTransaction();

        try {
            $cash = new Cashtransaction;
            $cash->from = $request->from;
            $cash->to = $request->to;
            $cash->staff = $request->staff;
            $cash->desc = $request->desc;
            $cash->transaction_category = $request->type;
            $cash->date = date("Y-m-d", strtotime($request->date));
            $cash->transfer = $request->total;
            $cash->cashout = 0;
            $cash->cashin = 0;
            $cash->save();

            $akun = Akun::find($request->from);
            $akun->total = $akun->total - $request->total;
            $akun->save();

            $akun = Akun::find($request->to);
            $akun->total = $akun->total + $request->total;
            $akun->save();

            DB::commit();

            $response = [
                'success' => true,
                'cashtransaction'  => $cash,
            ];

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

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

            return response($response, 500);
        }
    }

    public function createCashNoCash(Request $request)
    {
        $request->validate([
            'to' => 'nullable',
            'from' => 'nullable',
            'desc' => 'nullable',
            'staff' => 'nullable',
            'date' => 'required',
            'type' => 'required',
            'akun_id.*' => 'required',
            'total.*'  => 'required|numeric',
        ]);

        DB::beginTransaction();

        try {
            $cash = new Cashtransaction;
            $cash->to = $request->to;
            $cash->staff = $request->staff;
            $cash->desc = $request->desc;
            $cash->date = date("Y-m-d", strtotime($request->date));
            $cash->transaction_category = $request->type;
            $cash->cashin = 0;
            $cash->cashout = 0;
            $cash->transfer = 0;
            $cash->save();

            $data = $request->akun_id;
            $total = 0;
            $subcashtransactions = [];

            foreach ($data as $key => $value) {
                $sub = new Subcashtransaction;
                $sub->cashtransaction_id = $cash->id;
                $sub->akun_id = $value;
                $sub->total = $request->total[$key];
                $sub->desc = $request->desc;
                $sub->save();

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

            $cash = Cashtransaction::find($cash->id);
            $cash->total = $total;
            $cash->cashin = $request->to ? $total : 0;
            $cash->cashout = $request->from ? $total : 0;
            $cash->save();

            DB::commit();

            $response = [
                'success' => true,
                'cashtransaction'  => $cash,
                'subcashtransaction'  => $subcashtransactions,
            ];

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

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

            return response($response, 500);
        }
    }

    public function editDescriptionCash(Request $request)
    {
        $request->validate([
            'id' => 'required|exists:cashtransactions,id',
            'desc' => 'required|string',
        ]);

        try {
            $transaction = Cashtransaction::findOrFail($request->id);
            $transaction->desc = $request->desc;
            $transaction->save();

            // Juga update deskripsi di subcashtransaction jika ada
            $subTransactions = Subcashtransaction::where('cashtransaction_id', $transaction->id)->get();
            foreach ($subTransactions as $sub) {
                $sub->desc = $request->desc;
                $sub->save();
            }

            return response()->json([
                'success' => true,
                'message' => 'Description updated successfully',
                'cashtransaction' => $transaction
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to update description: ' . $e->getMessage()
            ], 500);
        }
    }

    public function deleteCashTransaction(Request $request)
    {
        $ch = Cashtransaction::where("transaction_ref", $request->id)->first();
        if ($ch) {
            $response = [
                'success' => false,
                'message'  => "Untuk menghapus transaksi ini, Anda harus menghapus transaksi no." . $ch->id . ", yang dapat Anda temukan di JUAL ASET, APRESIASI ASET, atau PENYUSUTAN ASET.",
            ];
            return response($response, 400);
        }
        $checkcashout = Cashtransaction::where("pay_debt_to", $request->id)->first();
        if ($checkcashout) {
            $namecash = '';
            if ($checkcashout->transaction_category == 'bayar_hutang') $namecash = 'BAYAR HUTANG';
            $response = [
                'success' => false,
                'message'  => "Untuk menghapus transaksi ini, Anda harus menghapus transaksi no." . $checkcashout->id . ", yang dapat Anda temukan di " . $namecash . ".",
            ];
            return response($response, 400);
        }
        $checkcashin = Cashtransaction::where("receivable_id", $request->id)->first();
        if ($checkcashin) {
            $namecash = '';
            if ($checkcashin->transaction_category == 'pembayaran_piutang') $namecash = 'PEMBAYARAN PIUTANG';
            $response = [
                'success' => false,
                'message'  => "Untuk menghapus transaksi ini, Anda harus menghapus transaksi no." . $checkcashin->id . ", yang dapat Anda temukan di " . $namecash . ".",
            ];
            return response($response, 400);
        }
        $data = Cashtransaction::find($request->id);
        if ($data->cashin > 0) {
            $sub = Subcashtransaction::where('cashtransaction_id', $request->id)->get();

            $akun = Akun::find($data->to);
            $akun->total = $akun->total - $data->cashin;
            $akun->save();

            foreach ($sub as $key => $value) {
                $akun = Akun::find($value->akun_id);
                $akun->total = $akun->total - $value->total;
                $akun->save();
            }
            Subcashtransaction::where('cashtransaction_id', $request->id)->delete();
        } elseif ($data->cashout > 0) {
            $sub = Subcashtransaction::where('cashtransaction_id', $request->id)->get();

            $akun = Akun::find($data->from);
            $akun->total = $akun->total + $data->cashout;
            $akun->save();
            foreach ($sub as $key => $value) {
                $akun = Akun::find($value->akun_id);
                $akun->total = $akun->total - $value->total;
                $akun->save();
            }
            Subcashtransaction::where('cashtransaction_id', $request->id)->delete();
        } elseif ($data->transfer > 0) {
            $akun = Akun::find($data->from);
            $akun->total = $akun->total + $data->transfer;
            $akun->save();

            $akun = Akun::find($data->to);
            $akun->total = $akun->total - $data->transfer;
            $akun->save();
        }

        // Hapus credit_cashtransaction
        CreditCashTransaction::where('cashtransaction_id', $request->id)->delete();

        $data->delete();
        $response = [
            'success' => true,
            'cashtransaction'  => $data,
        ];

        return response($response, 200);
    }
}
