<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Imports\AccountImportAsset;
use App\Models\Akun;
use App\Models\Cashtransaction;
use App\Models\Language;
use App\Models\Licence;
use App\Models\Product;
use App\Models\Subcashtransaction;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use LengthException;
use Maatwebsite\Excel\Facades\Excel;

class AkunController extends Controller
{
    private $total;

    public function importSpecificAccounts(Request $request)
    {
        $request->validate([
            'file' => 'required|file|mimes:xlsx,xls|max:10240',
            'perent_id' => 'required|integer',
        ]);

        try {
            $import = new \App\Imports\AccountSpecificImport($request->perent_id);
            \Maatwebsite\Excel\Facades\Excel::import($import, $request->file('file'));

            $results = $import->getResults();

            if (empty($results['successfulRows']) && empty($results['failedRows'])) {
                return response()->json([
                    'success' => false,
                    'message' => 'Tidak ada data yang diproses. Pastikan file memiliki kolom yang benar.',
                ], 400);
            }

            return response()->json([
                'success' => true,
                'message' => 'Proses import selesai.',
                'successfulRows' => $results['successfulRows'],
                'failedRows' => $results['failedRows'],
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Gagal mengimport akun: ' . $e->getMessage(),
            ], 500);
        }
    }

    public function importAccountsAset(Request $request)
    {
        $request->validate([
            'file' => 'required|file|mimes:xlsx,xls|max:10240',
            'category_ids' => 'required|array',
        ]);

        try {
            $import = new AccountImportAsset($request->category_ids);
            Excel::import($import, $request->file('file'));

            $results = $import->getResults();

            if (empty($results['successfulRows']) && empty($results['failedRows'])) {
                return response()->json([
                    'success' => false,
                    'message' => 'Tidak ada data yang diproses. Pastikan file memiliki kolom yang benar (name, category_id, desc, production_asset).',
                ], 400);
            }

            return response()->json([
                'success' => true,
                'message' => 'Proses import selesai.',
                'successfulRows' => $results['successfulRows'],
                'failedRows' => $results['failedRows'],
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Gagal mengimport akun: ' . $e->getMessage(),
            ], 500);
        }
    }

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

    private function loadAkunMapping($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)
    {
        // Prioritaskan translasi berdasarkan tipe perusahaan
        if (isset($mappingData[$companyType][$accountName])) {
            return $mappingData[$companyType][$accountName];
        }

        // Fallback ke translasi umum
        if (isset($mappingData['akun_umum'][$accountName])) {
            return $mappingData['akun_umum'][$accountName];
        }

        // Jika tidak ditemukan, kembalikan nama asli
        return $accountName;
    }

    // Ubah nama akun sesuai company_type dengan multi-bahasa
    private function ubahNamaAkunSesuaiTipe(&$items, $companyType, $mappingData)
    {
        foreach ($items as $item) {
            $item->name = $this->translateAccountName($item->name, $companyType, $mappingData);

            if ($item->children && $item->children->count() > 0) {
                $this->ubahNamaAkunSesuaiTipe($item->children, $companyType, $mappingData);
            }
        }
    }

    // Tambah nama akun (rename) sesuai company_type dengan multi-bahasa
    private function tambahNamaAkunSesuaiTipe(&$items, $companyType, $mappingData)
    {
        foreach ($items as $item) {
            $item->rename = $this->translateAccountName($item->name, $companyType, $mappingData);

            if ($item->children && $item->children->count() > 0) {
                $this->tambahNamaAkunSesuaiTipe($item->children, $companyType, $mappingData);
            }
        }
    }

    private function hapusAkun(&$data, $namesToExclude)
    {
        foreach ($data as $key => &$value) {
            if (in_array($value->name, $namesToExclude)) {
                unset($data[$key]);
                continue;
            }

            if (!empty($value->children)) {
                $this->hapusAkun($value->children, $namesToExclude);
            }
        }
    }

    private function pindahAkunPerent(&$data, $targetParentNames, $childNames)
    {
        $targetParent = null;

        $findTarget = function (&$items) use (&$findTarget, $targetParentNames, &$targetParent) {
            foreach ($items as &$item) {
                if (in_array($item->name, $targetParentNames)) {
                    $targetParent = $item;
                    return true;
                }
                if (!empty($item->children)) {
                    if ($findTarget($item->children)) {
                        return true;
                    }
                }
            }
            return false;
        };

        $findTarget($data);
        if (!$targetParent) {
            return;
        }

        if (!($targetParent->children instanceof Collection)) {
            $targetParent->children = collect($targetParent->children ?? []);
        }

        $moveFromContainers = function (&$items) use (&$moveFromContainers, $childNames, &$targetParent) {
            if (is_array($items)) {
                $items = collect($items);
            }
            foreach ($items as $index => $item) {
                if (in_array($item->name, $childNames)) {
                    $already = $targetParent->children->firstWhere('name', $item->name);
                    if (!$already) {
                        $moved = $items->pull($index);
                        $targetParent->children->push($moved);
                    }
                } else {
                    if (!empty($item->children)) {
                        $moveFromContainers($item->children);
                    }
                }
            }
        };

        $moveFromContainers($data);
    }

    // Fungsi bantu untuk membuat array nested 'children.children...'
    private function generateChildrenWith($depth)
    {
        $relations = [];

        // Add direct children
        $relations[] = 'children';
        $relations[] = 'children.contact';

        // Add nested children
        $currentRelation = 'children';
        for ($i = 0; $i < $depth; $i++) {
            $currentRelation .= '.children';
            $relations[] = $currentRelation;
            $relations[] = $currentRelation . '.contact';
        }

        return $relations;
    }

    private function setIsPlay(&$items, $usedIds)
    {
        foreach ($items as $item) {
            $itemId = isset($item->id) ? (int)$item->id : null;
            $item->is_play = $itemId !== null && in_array($itemId, $usedIds, true);
            if ($item->children && $item->children->count() > 0) {
                $this->setIsPlay($item->children, $usedIds);
            }
        }
    }

    // Proses khusus untuk yayasan dengan multi-bahasa
    private function processYayasanDanaConfig(&$data, $mappingData)
    {
        foreach ($data as &$akunModal) {
            $modalTranslated = $this->translateAccountName('Modal', 'yayasan', $mappingData);

            if ($akunModal->name === 'Modal' || $akunModal->name === $modalTranslated) {
                if (!($akunModal->children instanceof Collection)) {
                    $akunModal->children = collect($akunModal->children);
                }

                $danaConfig = $mappingData['yayasan']['dana_config'] ?? null;

                if ($danaConfig) {
                    $danaTidakTerikatConfig = $danaConfig['dana_tidak_terikat'] ?? null;
                    $danaTerikatConfig = $danaConfig['dana_terikat'] ?? null;

                    // Gunakan translasi untuk nama dana
                    $danaTidakTerikatName = $danaTidakTerikatConfig['name'] ?? 'Dana Tidak Terikat';
                    $danaTidakTerikatRename = $this->translateAccountName(
                        $danaTidakTerikatConfig['rename'] ?? $danaTidakTerikatName,
                        'yayasan',
                        $mappingData
                    );

                    $danaTerikatName = $danaTerikatConfig['name'] ?? 'Dana Terikat';
                    $danaTerikatRename = $this->translateAccountName(
                        $danaTerikatConfig['rename'] ?? $danaTerikatName,
                        'yayasan',
                        $mappingData
                    );

                    $akunToTidakTerikat = $danaTidakTerikatConfig['akun_items'] ?? ['Modal Awal', 'Laba Ditahan', 'Laba Tahun Berjalan'];

                    $danaTidakTerikat = $akunModal->children->firstWhere('name', $danaTidakTerikatName);
                    if (!$danaTidakTerikat) {
                        $danaTidakTerikat = (object)[
                            'name' => $danaTidakTerikatName,
                            'rename' => $danaTidakTerikatRename,
                            'total' => 0,
                            'children' => collect()
                        ];
                        $akunModal->children->push($danaTidakTerikat);
                    }

                    $danaTerkait = $akunModal->children->firstWhere('name', $danaTerikatName);
                    if (!$danaTerkait) {
                        $danaTerkait = (object)[
                            'name' => $danaTerikatName,
                            'rename' => $danaTerikatRename,
                            'total' => 0,
                            'children' => collect()
                        ];
                        $akunModal->children->push($danaTerkait);
                    }

                    $originalChildren = $akunModal->children->whereNotIn('name', [$danaTidakTerikatName, $danaTerikatName])->values();

                    foreach ($originalChildren as $child) {
                        $index = $akunModal->children->search(function ($c) use ($child) {
                            return $c->name === $child->name;
                        });

                        if ($index !== false) {
                            $akunPindah = $akunModal->children->pull($index);

                            // Translate nama akun yang dipindahkan
                            $akunPindah->rename = $this->translateAccountName($akunPindah->name, 'yayasan', $mappingData);

                            if (in_array($akunPindah->name, $akunToTidakTerikat)) {
                                $danaTidakTerikat->children->push($akunPindah);
                            } else {
                                $danaTerkait->children->push($akunPindah);
                            }
                        }
                    }

                    // Recalculate totals if needed
                    // rekursifTotal([$danaTidakTerikat]);
                    // rekursifTotal([$danaTerkait]);
                }

                break;
            }
        }
    }

    public function getAkun()
    {
        $licence = Licence::first();
        $companyType = $licence ? $licence->company_type : null;

        $isKoperasi = $companyType === 'koperasi';
        $isYayasan = $companyType === 'yayasan';
        $isCV = $companyType === 'cv';
        $isFirma = $companyType === 'firma';
        $isPerorangan = $companyType === 'perorangan';

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

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

        // Ambil semua data akun dengan relasi children rekursif
        $data = Akun::where('perent_id', null)
            ->with($this->generateChildrenWith(10))
            ->with('contact')
            ->get();

        // Filter "Simpanan Wajib" jika bukan koperasi
        if (!$isKoperasi) {
            $this->hapusAkun($data, ['Simpanan Wajib']);
        }

        if (!$isCV && !$isFirma && !$isPerorangan) {
            $this->hapusAkun($data, ['Prive']);
        }

        if ($isYayasan) {
            $this->hapusAkun($data, ['Utang_Dividen', 'Cadangan Wajib']);
        }

        if (!$isYayasan) {
            $this->hapusAkun($data, [
                'untuk_program_pendidikan',
                'untuk_program_kesehatan',
                'dana_abadi_endowment_fund',
                'pembatasan_waktu_temporer',
            ]);
        }

        // Proses khusus untuk yayasan
        if ($isYayasan) {
            $this->processYayasanDanaConfig($data, $mappingData);
        }

        $this->pindahAkunPerent(
            $data,
            ['Persediaan'],
            ['Persediaan Barang', 'Persediaan Bahan Baku', 'Persediaan Barang Dalam Proses', 'Persediaan Barang Jadi']
        );

        $usedIds = Subcashtransaction::whereNotNull('akun_id')
            ->whereHas('cashtransaction', function ($query) {
                $query->whereIn('transaction_category', [
                    'apresiasi_aset',
                    'penyusutan_aset',
                    'penyusutan_aset_produksi',
                    'biaya_produksi_dibebankan',
                ]);
            })
            ->distinct()
            ->pluck('akun_id')
            ->filter()
            ->map(function ($id) {
                return (int)$id;
            })
            ->toArray();
        $this->setIsPlay($data, $usedIds);

        // Ubah nama akun sesuai jenis perusahaan dengan multi-bahasa
        if ($companyType) {
            $this->tambahNamaAkunSesuaiTipe($data, $companyType, $mappingData);
        } else {
            // Fallback: apply general translation if no company type
            $this->tambahNamaAkunSesuaiTipe($data, 'general', $mappingData);
        }

        return response([
            'success' => true,
            'akun' => $data,
            'language' => $langCode,
            'company_type' => $companyType
        ], 200);
    }

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

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

        $data = Akun::whereRaw('LOWER(name) = ?', [strtolower($request->name)])->get();

        if ($companyType !== 'yayasan') {
            $this->hapusAkun($data, [
                'untuk_program_pendidikan',
                'untuk_program_kesehatan',
                'dana_abadi_endowment_fund',
                'pembatasan_waktu_temporer',
            ]);
        }

        if ($companyType === 'yayasan') {
            $this->hapusAkun($data, ['Utang_Dividen', 'Cadangan Wajib']);
        }

        if ($companyType) {
            $this->tambahNamaAkunSesuaiTipe($data, $companyType, $mappingData);
        } else {
            $this->tambahNamaAkunSesuaiTipe($data, 'general', $mappingData);
        }

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

        return response($response, 200);
    }

    public function getAkunByNames(Request $request)
    {
        $request->validate([
            'names' => 'required|array|min:1',
            'names.*' => 'required|string',
        ]);

        $names = collect($request->names)
            ->map(function ($name) {
                return trim((string)$name);
            })
            ->filter()
            ->unique()
            ->values()
            ->all();

        if (empty($names)) {
            return response([
                'success' => true,
                'akun' => [],
                'language' => (self::getActiveLanguage()->code ?? 'id'),
            ], 200);
        }

        $licence = Licence::first();
        $companyType = $licence ? $licence->company_type : null;

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

        $lowerNames = array_map('strtolower', $names);
        $data = Akun::whereIn(DB::raw('LOWER(name)'), $lowerNames)->get();

        if ($companyType !== 'yayasan') {
            $this->hapusAkun($data, [
                'untuk_program_pendidikan',
                'untuk_program_kesehatan',
                'dana_abadi_endowment_fund',
                'pembatasan_waktu_temporer',
            ]);
        }

        if ($companyType === 'yayasan') {
            $this->hapusAkun($data, ['Utang_Dividen', 'Cadangan Wajib']);
        }

        if ($companyType) {
            $this->tambahNamaAkunSesuaiTipe($data, $companyType, $mappingData);
        } else {
            $this->tambahNamaAkunSesuaiTipe($data, 'general', $mappingData);
        }

        return response([
            'success' => true,
            'akun' => $data,
            'language' => $langCode,
        ], 200);
    }

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

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

        $data = Akun::where('id', $request->id)->with('contact')->get();

        if ($companyType !== 'yayasan') {
            $this->hapusAkun($data, [
                'untuk_program_pendidikan',
                'untuk_program_kesehatan',
                'dana_abadi_endowment_fund',
                'pembatasan_waktu_temporer',
            ]);
        }

        if ($companyType === 'yayasan') {
            $this->hapusAkun($data, ['Utang_Dividen', 'Cadangan Wajib']);
        }

        if ($companyType) {
            $this->tambahNamaAkunSesuaiTipe($data, $companyType, $mappingData);
        } else {
            $this->tambahNamaAkunSesuaiTipe($data, 'general', $mappingData);
        }

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

        return response($response, 200);
    }

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

        $licence = Licence::first();
        $companyType = $licence ? $licence->company_type : null;

        $relations = $this->generateChildrenWith(10);

        $data = Akun::whereRaw('LOWER(name) = ?', [strtolower($request->name)])
            ->with($relations)
            ->get();

        if ($companyType !== 'yayasan') {
            $this->hapusAkun($data, [
                'untuk_program_pendidikan',
                'untuk_program_kesehatan',
                'dana_abadi_endowment_fund',
                'pembatasan_waktu_temporer',
            ]);
        }

        if ($companyType === 'yayasan') {
            $this->hapusAkun($data, ['Utang_Dividen', 'Cadangan Wajib']);
        }

        $usedIds = Subcashtransaction::whereNotNull('akun_id')
            ->distinct()
            ->pluck('akun_id')
            ->filter()
            ->map(function ($id) {
                return (int)$id;
            })
            ->toArray();
        $this->setIsPlay($data, $usedIds);

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

    public function setLabaDitahan(Request $request)
    {
        $request->validate([
            'total' => 'required',
        ]);
        $now = date('Y-m-d', time());
        $first = date('Y-1-1', time());
        $last = date('Y-12-31', time());
        $data = Cashtransaction::whereNotNull('transfer')->whereHas('from', function ($query) {
            $query->where('Laba Tahun Berjalan');
        })->whereHas('to', function ($query) {
            $query->where('Laba Ditahan');
        });
        $data = $data->whereBetween('date', [$first, $last]);
        $data = $data->get();
        if (empty($data) && date('Y-m-d', time())) {
        }
        $data = Akun::where('name', '=', 'Laba Ditahan')->first();
        $data = Akun::find($data->id);
        $data->total = $data->total + $request->total;
        $data->save();
        $response = [
            'success' => true,
            'akun' => $data,

        ];

        return response($response, 200);
    }

    public function getAkunList()
    {
        $licence = Licence::first();
        $companyType = $licence ? $licence->company_type : null;

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

        $data = Akun::all();

        if ($companyType !== 'yayasan') {
            $this->hapusAkun($data, [
                'untuk_program_pendidikan',
                'untuk_program_kesehatan',
                'dana_abadi_endowment_fund',
                'pembatasan_waktu_temporer',
            ]);
        }

        if ($companyType === 'yayasan') {
            $this->hapusAkun($data, ['Utang_Dividen', 'Cadangan Wajib']);
        }

        if ($companyType) {
            $this->tambahNamaAkunSesuaiTipe($data, $companyType, $mappingData);
        } else {
            $this->tambahNamaAkunSesuaiTipe($data, 'general', $mappingData);
        }

        $response = [
            'success' => true,
            'akun'  => $data,
            'language' => $langCode,
            'company_type' => $companyType
        ];

        return response($response, 200);
    }

    public function Report(Request $request)
    {
        $data = Akun::where('name', $request->name)->with(str_repeat('children.', 10))->get();
        $response = [
            'success' => true,
            'akun'  => $data,
        ];

        return response($response, 200);
    }

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

        $isKoperasi = $companyType === 'koperasi';
        $isYayasan = $companyType === 'yayasan';

        $data = Akun::where('name', $request->name)->with(str_repeat('children.', 10))->get();

        // Filter "Simpanan Wajib" jika bukan koperasi
        if (!$isKoperasi) {
            $this->hapusAkun($data, ['Simpanan Wajib']);
        }

        if (!$isYayasan) {
            $this->hapusAkun($data, [
                'untuk_program_pendidikan',
                'untuk_program_kesehatan',
                'dana_abadi_endowment_fund',
                'pembatasan_waktu_temporer',
            ]);
        }

        if ($isYayasan) {
            $this->hapusAkun($data, ['Utang_Dividen', 'Cadangan Wajib']);
        }

        if ($isYayasan) {
            foreach ($data as &$akunModal) {
                if ($akunModal->name === 'Modal') {
                    if (!($akunModal->children instanceof Collection)) {
                        $akunModal->children = collect($akunModal->children);
                    }

                    // Inisialisasi Dana Tidak Terikat
                    $danaTidakTerikat = $akunModal->children->firstWhere('name', 'Dana Tidak Terikat');
                    if (!$danaTidakTerikat) {
                        $danaTidakTerikat = (object)[
                            'name' => 'Dana Tidak Terikat',
                            'rename' => 'Dana Tidak Terikat',
                            'total' => 0,
                            'children' => collect()
                        ];
                        $akunModal->children->push($danaTidakTerikat);
                    }

                    // Inisialisasi Dana Terikat
                    $danaTerkait = $akunModal->children->firstWhere('name', 'Dana Terikat');
                    if (!$danaTerkait) {
                        $danaTerkait = (object)[
                            'name' => 'Dana Terikat',
                            'rename' => 'Dana Terikat',
                            'total' => 0,
                            'children' => collect()
                        ];
                        $akunModal->children->push($danaTerkait);
                    }

                    $akunToTidakTerikat = ['Modal Awal', 'Laba Ditahan', 'Laba Tahun Berjalan'];

                    // Duplikat daftar children agar bisa di-loop sambil di-pull
                    $originalChildren = $akunModal->children->whereNotIn('name', ['Dana Tidak Terikat', 'Dana Terikat'])->values();

                    foreach ($originalChildren as $child) {
                        $index = $akunModal->children->search(function ($c) use ($child) {
                            return $c->name === $child->name;
                        });

                        if ($index !== false) {
                            $akunPindah = $akunModal->children->pull($index);

                            if (in_array($akunPindah->name, $akunToTidakTerikat)) {
                                $danaTidakTerikat->children->push($akunPindah);
                            } else {
                                $danaTerkait->children->push($akunPindah);
                            }
                        }
                    }

                    break;
                }
            }
        }

        // Ubah nama akun sesuai jenis perusahaan
        if ($companyType) {
            $this->ubahNamaAkunSesuaiTipe($data, $companyType, []);
        }

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

        return response($response, 200);
    }

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

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

        $data = Akun::where('iscash', '<>', true)->where('iscashin', true)->get();

        if ($companyType) {
            $this->tambahNamaAkunSesuaiTipe($data, $companyType, $mappingData);
        } else {
            $this->tambahNamaAkunSesuaiTipe($data, 'general', $mappingData);
        }

        $response = [
            'success' => true,
            'akun'  => $data,
            'language' => $langCode,
            'company_type' => $companyType
        ];

        return response($response, 200);
    }

    public function getAkunIsCashOut()
    {
        $licence = Licence::first();
        $companyType = $licence ? $licence->company_type : null;

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

        $data = Akun::where('iscash', '<>', true)->where('iscashout', true)->get();

        if ($companyType) {
            $this->tambahNamaAkunSesuaiTipe($data, $companyType, $mappingData);
        } else {
            $this->tambahNamaAkunSesuaiTipe($data, 'general', $mappingData);
        }

        $response = [
            'success' => true,
            'akun'  => $data,
            'language' => $langCode,
            'company_type' => $companyType
        ];

        return response($response, 200);
    }

    public function getAkunIsCash()
    {
        $data = Akun::where('iscash', true)->get();

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

        return response($response, 200);
    }

    public function getAkunNotCash()
    {
        $data = Akun::where('iscash', false)->orWhere('iscash', 0)->get();

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

        return response($response, 200);
    }

    public function getAkunIsHeader()
    {
        $data = Akun::where('isheader', true)->orWhere('isheader', 1)->get();

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

        return response($response, 200);
    }

    public function createAkun(Request $request)
    {
        $request->validate([
            'perent_id' => 'nullable',
            'contact_id' => 'nullable',
            'name' => 'required',
            'isheader' => 'boolean',
            'iscash' => 'boolean',
            'iscashout' => 'boolean',
            'iscashin' => 'boolean',
            'is_productionasset' => 'boolean',
            'is_deductible' => 'nullable|boolean',
        ]);
        $check = Akun::whereRaw('LOWER(name) = ?', [strtolower($request->name)])->first();
        if ($check) {
            $checkMenu = Akun::where('id', $check->perent_id)->first();

            $response = [
                'success' => false,
                'message'  => "Nama tersebut sudah dipakai di {$checkMenu->name}, silakan gunakan nama lainnya.",
            ];

            return response($response, 400);
        }
        $data = new Akun;
        $data->perent_id = $request->perent_id;
        $data->contact_id = $request->contact_id;
        $data->name = $request->name;
        $data->akun_desc = $request->akun_desc;
        $data->isheader = $request->isheader;
        $data->iscash = $request->iscash;
        $data->iscashout = $request->iscashout;
        $data->iscashin = $request->iscashin;
        $data->is_productionasset = $request->is_productionasset;
        $data->is_deductible = $request->is_deductible;

        $data->save();

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

        return response($response, 200);
    }

    public function createAkunOverhead(Request $request)
    {
        $request->validate([
            'name' => 'required',
            'akun_desc' => 'nullable',
        ]);

        $akunDibebankan = Akun::where('name', 'biaya_overhead_pabrik_dibebankan')->first();
        $akunAktual = Akun::where('name', 'biaya_overhead_pabrik_aktual')->first();
        if (!$akunDibebankan || !$akunAktual) {
            return response([
                'success' => false,
                'message' => 'Akun overhead induk tidak ditemukan',
            ], 404);
        }

        $nameDibebankan = trim($request->name) . ' dibebankan';
        $nameAktual = trim($request->name) . ' aktual';

        $checkDibebankan = Akun::whereRaw('LOWER(name) = ?', [strtolower($nameDibebankan)])->first();
        if ($checkDibebankan) {
            $checkMenu = Akun::where('id', $checkDibebankan->perent_id)->first();
            return response([
                'success' => false,
                'message'  => "Nama tersebut sudah dipakai di {$checkMenu->name}, silakan gunakan nama lainnya.",
            ], 400);
        }

        $checkAktual = Akun::whereRaw('LOWER(name) = ?', [strtolower($nameAktual)])->first();
        if ($checkAktual) {
            $checkMenu = Akun::where('id', $checkAktual->perent_id)->first();
            return response([
                'success' => false,
                'message'  => "Nama tersebut sudah dipakai di {$checkMenu->name}, silakan gunakan nama lainnya.",
            ], 400);
        }

        DB::beginTransaction();
        try {
            $dibebankan = new Akun;
            $dibebankan->perent_id = $akunDibebankan->id;
            $dibebankan->name = $nameDibebankan;
            $dibebankan->akun_desc = $request->akun_desc;
            $dibebankan->isheader = false;
            $dibebankan->iscash = false;
            $dibebankan->iscashout = false;
            $dibebankan->iscashin = false;
            $dibebankan->is_productionasset = false;
            $dibebankan->save();

            $aktual = new Akun;
            $aktual->perent_id = $akunAktual->id;
            $aktual->name = $nameAktual;
            $aktual->akun_desc = $request->akun_desc;
            $aktual->isheader = false;
            $aktual->iscash = false;
            $aktual->iscashout = false;
            $aktual->iscashin = false;
            $aktual->is_productionasset = false;
            $aktual->save();

            DB::commit();
            return response([
                'success' => true,
                'akun_dibebankan' => $dibebankan,
                'akun_aktual' => $aktual,
            ], 200);
        } catch (\Throwable $e) {
            DB::rollBack();
            return response([
                'success' => false,
                'message' => $e->getMessage(),
            ], 500);
        }
    }

    public function editAkun(Request $request)
    {
        $request->validate([
            'perent_id' => 'nullable',
            'contact_id' => 'nullable',
            'name' => 'required',
            'isheader' => 'boolean',
            'iscash' => 'boolean',
            'iscashout' => 'boolean',
            'iscashin' => 'boolean',
            'is_productionasset' => 'boolean',
            'is_deductible' => 'nullable|boolean',
        ]);

        $check = Akun::whereRaw('LOWER(name) = ?', [strtolower($request->name)])
            ->where('id', '!=', $request->id)
            ->first();
        if ($check) {
            $checkMenu = Akun::where('id', $check->perent_id)->first();

            $response = [
                'success' => false,
                'message'  => "Nama tersebut sudah dipakai di {$checkMenu->name}, silakan gunakan nama lainnya.",
            ];

            return response($response, 400);
        }

        $data = Akun::find($request->id);
        $data->perent_id = $request->perent_id;
        $data->contact_id = $request->contact_id;
        $data->name = $request->name;
        $data->akun_desc = $request->akun_desc;
        $data->isheader = $request->isheader;
        $data->iscash = $request->iscash;
        $data->iscashin = $request->iscashin;
        $data->iscashout = $request->iscashout;
        $data->is_productionasset = $request->is_productionasset;
        $data->is_deductible = $request->is_deductible;

        $data->save();

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

        return response($response, 200);
    }

    public function deleteAkun(Request $request)
    {

        $data = Akun::find($request->id);

        $check = Subcashtransaction::where('akun_id', $request->id)->get();
        if (!$check->isEmpty()) {
            return response(['message' => $data->name . ' sudah pernah digunakan untuk transaksi.'], 400);
        }

        Akun::where('perent_id', '=', $data->id)->update(array('perent_id' => null));
        $data->delete();

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

        return response($response, 200);
    }

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

        $data = Akun::find($request->id);
        if (!$data) {
            return response()->json([
                'success' => false,
                'message' => 'Akun tidak ditemukan'
            ], 404);
        }


        $data->akun_translated = $request->akun_translated;
        $data->save();

        // Sync paired accounts: if one is updated, update its pair as well
        $pairedNames = [
            ['untuk_program_pendidikan', 'untuk_program_pendidikan_v2', 'untuk_program_pendidikan_v3'],
            ['untuk_program_kesehatan', 'untuk_program_kesehatan_v2', 'untuk_program_kesehatan_v3'],
            ['dana_abadi_endowment_fund', 'dana_abadi_endowment_fund_v2', 'dana_abadi_endowment_fund_v3'],
            ['pembatasan_waktu_temporer', 'pembatasan_waktu_temporer_v2', 'pembatasan_waktu_temporer_v3'],
        ];

        foreach ($pairedNames as $pair) {
            if (in_array($data->name, $pair)) {
                $otherNames = array_diff($pair, [$data->name]);
                Akun::whereIn('name', $otherNames)
                    ->update(['akun_translated' => $request->akun_translated]);
                break;
            }
        }

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

        return response($response, 200);
    }

    public function resetAkunTranslated(Request $request)
    {
        $data = Akun::find($request->id);
        if (!$data) {
            return response()->json([
                'success' => false,
                'message' => 'Akun tidak ditemukan'
            ], 404);
        }

        $data->akun_translated = null;
        $data->save();

        // Sync paired accounts: if one is reset, reset all others in the same group
        $pairedNames = [
            ['untuk_program_pendidikan', 'untuk_program_pendidikan_v2', 'untuk_program_pendidikan_v3', 'Pelepasan_Pembatasan'],
            ['untuk_program_kesehatan', 'untuk_program_kesehatan_v2', 'untuk_program_kesehatan_v3', 'Pelepasan_Pembatasan'],
            ['dana_abadi_endowment_fund', 'dana_abadi_endowment_fund_v2', 'dana_abadi_endowment_fund_v3', 'Pelepasan_Pembatasan'],
            ['pembatasan_waktu_temporer', 'pembatasan_waktu_temporer_v2', 'pembatasan_waktu_temporer_v3', 'Pelepasan_Pembatasan'],
        ];

        foreach ($pairedNames as $pair) {
            if (in_array($data->name, $pair)) {
                $otherNames = array_diff($pair, [$data->name]);
                Akun::whereIn('name', $otherNames)
                    ->update(['akun_translated' => null]);
            }
        }

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

        return response($response, 200);
    }
}
