<?php

namespace App\Controllers;

use App\Models\TransaksiKasModel;

class Kas extends BaseController
{
    private TransaksiKasModel $transaksiKas;

    public function __construct()
    {
        $this->transaksiKas = new TransaksiKasModel();
    }

    public function index(): string
    {
        $filters = $this->ambilFilter();

        return view('kas/index', [
            'title'      => 'Buku Kas Umum',
            'transaksi'  => $this->transaksiKas->findFiltered($filters),
            'ringkasan'  => $this->transaksiKas->ringkasan($filters),
            'filters'    => $filters,
            'hasFilter'  => array_filter($filters) !== [],
        ]);
    }

    public function create(): string
    {
        return view('kas/form', [
            'title'       => 'Tambah Transaksi',
            'action'      => site_url('kas'),
            'transaksi'   => $this->dataKosong(),
            'kodeOptions' => $this->kodeOptions(),
            'validation'  => session('validation'),
        ]);
    }

    public function laporan(): string
    {
        $filters = $this->ambilFilter();

        return view('kas/laporan', [
            'title'      => 'Laporan Buku Kas Umum',
            'transaksi'  => $this->transaksiKas->findFiltered($filters),
            'ringkasan'  => $this->transaksiKas->ringkasan($filters),
            'filters'    => $filters,
            'hasFilter'  => array_filter($filters) !== [],
        ]);
    }

    public function store()
    {
        $data = $this->ambilInput();
        $data['kode'] = $this->transaksiKas->buatKodeOtomatis($data['jenis']);

        if (! $this->transaksiKas->save($data)) {
            return redirect()->back()->withInput()->with('validation', $this->transaksiKas->errors());
        }

        return redirect()->to('/kas')->with('success', 'Transaksi berhasil ditambahkan.');
    }

    public function edit(int $id): string
    {
        $transaksi = $this->transaksiKas->find($id);

        if (! $transaksi) {
            throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound('Transaksi tidak ditemukan.');
        }

        return view('kas/form', [
            'title'       => 'Edit Transaksi',
            'action'      => site_url('kas/' . $id),
            'transaksi'   => $transaksi,
            'kodeOptions' => $this->kodeOptions(),
            'validation'  => session('validation'),
        ]);
    }

    public function update(int $id)
    {
        $transaksi = $this->transaksiKas->find($id);

        if (! $transaksi) {
            throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound('Transaksi tidak ditemukan.');
        }

        $data       = $this->ambilInput();
        $data['id'] = $id;
        $data['kode'] = $transaksi['jenis'] === $data['jenis']
            ? $transaksi['kode']
            : $this->transaksiKas->buatKodeOtomatis($data['jenis']);

        if (! $this->transaksiKas->save($data)) {
            return redirect()->back()->withInput()->with('validation', $this->transaksiKas->errors());
        }

        return redirect()->to('/kas')->with('success', 'Transaksi berhasil diperbarui.');
    }

    public function delete(int $id)
    {
        $this->transaksiKas->delete($id);

        return redirect()->to('/kas')->with('success', 'Transaksi berhasil dihapus.');
    }

    private function ambilInput(): array
    {
        $jumlah = (string) $this->request->getPost('jumlah');
        $jumlah = str_replace(',', '.', $jumlah);

        return [
            'tanggal' => $this->request->getPost('tanggal'),
            'uraian'  => trim((string) $this->request->getPost('uraian')),
            'jenis'   => $this->request->getPost('jenis'),
            'jumlah'  => $jumlah,
        ];
    }

    private function ambilFilter(): array
    {
        $jenis = (string) $this->request->getGet('jenis');

        return [
            'q'               => trim((string) $this->request->getGet('q')),
            'tanggal_mulai'   => trim((string) $this->request->getGet('tanggal_mulai')),
            'tanggal_sampai'  => trim((string) $this->request->getGet('tanggal_sampai')),
            'jenis'           => in_array($jenis, ['masuk', 'keluar'], true) ? $jenis : '',
        ];
    }

    private function dataKosong(): array
    {
        return [
            'tanggal' => date('Y-m-d'),
            'kode'    => $this->transaksiKas->buatKodeOtomatis('masuk'),
            'uraian'  => '',
            'jenis'   => 'masuk',
            'jumlah'  => '',
        ];
    }

    private function kodeOptions(): array
    {
        return [
            'masuk'  => $this->transaksiKas->buatKodeOtomatis('masuk'),
            'keluar' => $this->transaksiKas->buatKodeOtomatis('keluar'),
        ];
    }
}
