<?php

namespace App\Services;

use App\Models\Kas;
use App\Models\ProdukTabungan;
use App\Models\TransaksiTabungan;
use App\Repositories\TabunganRepository;
use App\Repositories\TransaksiTabunganRepository;
use Carbon\Carbon;
use Exception;
use Illuminate\Support\Facades\DB;
use Nette\NotImplementedException;

class TransaksiTabunganService
{
    protected $transaksiTabunganRepository;
    protected $tabunganRepository;
    protected $jurnalService;

    public function __construct(TransaksiTabunganRepository $transaksiTabunganRepository, JurnalService $jurnalService, TabunganRepository $tabunganRepository)
    {
        $this->transaksiTabunganRepository = $transaksiTabunganRepository;
        $this->jurnalService = $jurnalService;
        $this->tabunganRepository = $tabunganRepository;
    }

    public function getAll($tgl_awal, $tgl_akhir, $rekening = null)
    {
        return $this->transaksiTabunganRepository->getAllTransaksi($tgl_awal, $tgl_akhir, $rekening);
    }

    public function findById($id)
    {
        return $this->transaksiTabunganRepository->findTransaksiById($id);
    }

    public function createTransaksi(array $data)
    {
        try {
            return DB::transaction(function () use ($data) {
                $rekening = $data['rekening'];

                // Dapatkan saldo saat ini dari tabungan
                $tabungan = $this->tabunganRepository->findByRekening($rekening);
                if (!$tabungan) {
                    throw new Exception('Tabungan tidak ditemukan.');
                }
                $saldoSaatIni = $tabungan->saldo;


                $dataTrans = [];
                $dataTrans['trans_kode'] = $data['trans_kode'];
                $dataTrans['trans_date'] = Carbon::now();
                $dataTrans['trans_tglbuku'] = $data['trans_tglbuku'];
                $dataTrans['rekening'] = $data['rekening'];
                $dataTrans['keterangan'] = $data['keterangan'] ?? "Setoran Tabungan " . $tabungan->anggota->nama_lengkap . " (" . $tabungan->rekening . ") Tunai";

                $saldoBaru = 0;

                $trans_tglbuku = Carbon::parse($data['trans_tglbuku']);

                $jumlah_transaksi = TransaksiTabungan::whereYear('trans_tglbuku', $trans_tglbuku->format('Y'))->whereMonth('trans_tglbuku', $trans_tglbuku->format('m'))->count();
                $trans_id = $data['trans_kode'] . "." . $trans_tglbuku->format('Ymd') . "." . str_pad($jumlah_transaksi + 1, 5, "0", STR_PAD_LEFT);

                $data['trans_id'] = $trans_id;
                $dataTrans['trans_id'] = $trans_id;

                $produk = ProdukTabungan::where('id', $tabungan->produk_id)->first();

                $kas = Kas::where('is_default', 1)->first();

                $akun_kas = $kas->akun_kas;
                $akun_simpanan = $produk->akun_simpanan_id;

                // Hitung saldo baru
                if ($data['trans_kode'] === '31') {
                    $saldoBaru = $saldoSaatIni + $data['nominal'];
                    $dataTrans['setor'] = $data['nominal'];
                    $dataTrans['tarik'] = 0;

                    $this->jurnalService->createJurnal([
                        'trans_id' => $dataTrans['trans_id'],
                        'trans_kode' => $dataTrans['trans_kode'],
                        'akun_jurnal' => $akun_simpanan,
                        'debet' => 0,
                        'kredit' => $data['nominal'],
                        'rekening' => $dataTrans['rekening'],
                        'keterangan' => $dataTrans['keterangan'],
                        'trans_tglbuku' => $dataTrans['trans_tglbuku'],
                        'trans_date' => $dataTrans['trans_date']
                    ]);

                    $this->jurnalService->createJurnal([
                        'trans_id' => $dataTrans['trans_id'],
                        'trans_kode' => $dataTrans['trans_kode'],
                        'akun_jurnal' => $akun_kas,
                        'debet' => $data['nominal'],
                        'kredit' => 0,
                        'rekening' => $dataTrans['rekening'],
                        'keterangan' => $dataTrans['keterangan'],
                        'trans_tglbuku' => $dataTrans['trans_tglbuku'],
                        'trans_date' => $dataTrans['trans_date']
                    ]);
                } else
                if ($data['trans_kode'] === '32') { // 'tarik'
                    $dataTrans['keterangan'] = "Penarikan Tabungan " . $tabungan->anggota->nama_lengkap . " (" . $tabungan->rekening . ") Tunai";
                    if ($saldoSaatIni < $data['nominal']) {
                        throw new Exception('Saldo tidak mencukupi untuk melakukan penarikan.');
                    }
                    $saldoBaru = $saldoSaatIni - $data['nominal'];
                    $dataTrans['setor'] = 0;
                    $dataTrans['tarik'] = $data['nominal'];

                    $this->jurnalService->createJurnal([
                        'trans_id' => $dataTrans['trans_id'],
                        'trans_kode' => $dataTrans['trans_kode'],
                        'akun_jurnal' => $akun_kas,
                        'debet' => 0,
                        'kredit' => $data['nominal'],
                        'rekening' => $dataTrans['rekening'],
                        'keterangan' => $dataTrans['keterangan'],
                        'trans_tglbuku' => $dataTrans['trans_tglbuku'],
                        'trans_date' => $dataTrans['trans_date']
                    ]);
                    $this->jurnalService->createJurnal([
                        'trans_id' => $dataTrans['trans_id'],
                        'trans_kode' => $dataTrans['trans_kode'],
                        'akun_jurnal' => $akun_simpanan,
                        'debet' => $data['nominal'],
                        'kredit' => 0,
                        'rekening' => $dataTrans['rekening'],
                        'keterangan' => $dataTrans['keterangan'],
                        'trans_tglbuku' => $dataTrans['trans_tglbuku'],
                        'trans_date' => $dataTrans['trans_date']
                    ]);
                } else {
                    throw new Exception('Kode transaksi tidak valid.');
                }

                $tabungan->saldo = $saldoBaru;
                $tabungan->save();

                $transaksi = $this->transaksiTabunganRepository->createTransaksi($dataTrans);

                return $transaksi;
            });
        } catch (Exception $error) {
            throw new Exception($error->getMessage());
        }
    }

    public function validasiTransaksi($id)
    {
        $transaksi = $this->transaksiTabunganRepository->findTransaksiById($id);
        if (!$transaksi) {
            throw new Exception('Transaksi tidak ditemukan');
        }

        return $this->transaksiTabunganRepository->validasiTransaksi($id);
    }

    public function deleteTransaksi(string $id)
    {
        $transaksi = $this->transaksiTabunganRepository->findTransaksiById($id);
        if (!$transaksi) {
            throw new Exception('Transaksi tidak ditemukan');
        }
        return $this->transaksiTabunganRepository->deleteTransaksi($id);
    }
}
