<?php

namespace Modules\Payroll\Controllers;

use App\Controllers\BaseController;
use App\Models\PayrollItemModel;
use App\Models\PayrollRunModel;
use App\Traits\ExportsReport;

class PayrollReportController extends BaseController
{
    use ExportsReport;

    protected PayrollRunModel $runs;
    protected PayrollItemModel $items;

    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        $this->runs  = new PayrollRunModel();
        $this->items = new PayrollItemModel();
    }

    public function summary()
    {
        $year  = (int) ($this->request->getGet('year') ?: date('Y'));
        $month = (int) ($this->request->getGet('month') ?: date('n'));

        $run = $this->runs->findByPeriod($year, $month);
        $items = $run ? $this->items->getForRun((int) $run['id']) : [];
        $totals = $run ? $this->items->getRunTotals((int) $run['id']) : null;

        $periodLabel = $run
            ? date('F Y', mktime(0, 0, 0, (int) $run['period_month'], 1, (int) $run['period_year']))
            : sprintf('%04d-%02d', $year, $month);

        if ($export = $this->exportTable(
            'payroll_summary_' . $year . '_' . $month,
            'Payroll Summary',
            ['Employee', 'Gross', 'Deductions', 'Net', 'Employer Cost'],
            array_map(static fn ($item) => [
                $item['full_name'] ?? '',
                number_format((float) ($item['gross_earnings'] ?? 0), 3),
                number_format((float) ($item['total_deductions'] ?? 0), 3),
                number_format((float) ($item['net_pay'] ?? 0), 3),
                number_format((float) ($item['employer_total_cost'] ?? 0), 3),
            ], $items),
            $periodLabel
        )) {
            return $export;
        }

        return view('Modules\Payroll\Views\reports\summary', array_merge($this->baseViewData(), [
            'title'   => 'Payroll Summary',
            'run'     => $run,
            'items'   => $items,
            'totals'  => $totals,
            'filters' => compact('year', 'month'),
        ]));
    }

    public function sio()
    {
        $year  = (int) ($this->request->getGet('year') ?: date('Y'));
        $month = (int) ($this->request->getGet('month') ?: date('n'));

        $run = $this->runs->findByPeriod($year, $month);
        $items = [];
        if ($run) {
            $lineModel = new \App\Models\PayrollItemLineModel();
            foreach ($this->items->getForRun((int) $run['id']) as $item) {
                $eeSio = 0.0;
                foreach ($lineModel->getForItem((int) $item['id']) as $line) {
                    if ($line['code'] === 'SIO_EE') {
                        $eeSio = (float) $line['amount'];
                    }
                }
                $item['employee_sio'] = $eeSio;
                $items[] = $item;
            }
        }

        $periodLabel = sprintf('%04d-%02d', $year, $month);
        if ($export = $this->exportTable(
            'sio_report_' . $year . '_' . $month,
            'SIO Report',
            ['Employee', 'Nationality', 'Type', 'Employer SIO', 'Employee Deduction'],
            array_map(static function ($item) {
                $n = strtolower(trim((string) ($item['nationality'] ?? '')));
                $isBh = in_array($n, ['bahrain', 'bahraini', 'bh', 'kingdom of bahrain'], true) || str_contains($n, 'bahrain');

                return [
                    $item['full_name'] ?? '',
                    $item['nationality'] ?? '',
                    $isBh ? 'Bahraini' : 'Expat',
                    number_format((float) ($item['employer_sio'] ?? 0), 3),
                    number_format((float) ($item['employee_sio'] ?? 0), 3),
                ];
            }, $items),
            $periodLabel
        )) {
            return $export;
        }

        return view('Modules\Payroll\Views\reports\sio', array_merge($this->baseViewData(), [
            'title'   => 'SIO Report',
            'run'     => $run,
            'items'   => $items,
            'filters' => compact('year', 'month'),
        ]));
    }

    public function eosb()
    {
        $year  = (int) ($this->request->getGet('year') ?: date('Y'));
        $month = (int) ($this->request->getGet('month') ?: date('n'));

        $run = $this->runs->findByPeriod($year, $month);
        $items = $run ? $this->items->getForRun((int) $run['id']) : [];

        $expatItems = array_values(array_filter($items, static function ($item) {
            $n = strtolower(trim((string) ($item['nationality'] ?? '')));

            return ! in_array($n, ['bahrain', 'bahraini', 'bh', 'kingdom of bahrain'], true)
                && ! str_contains($n, 'bahrain');
        }));

        if ($export = $this->exportTable(
            'eosb_report_' . $year . '_' . $month,
            'EOSB Report',
            ['Employee', 'Nationality', 'Monthly EOSB'],
            array_map(static fn ($item) => [
                $item['full_name'] ?? '',
                $item['nationality'] ?? '',
                number_format((float) ($item['employer_eosb'] ?? 0), 3),
            ], $expatItems),
            sprintf('%04d-%02d', $year, $month)
        )) {
            return $export;
        }

        return view('Modules\Payroll\Views\reports\eosb', array_merge($this->baseViewData(), [
            'title'   => 'EOSB Report',
            'run'     => $run,
            'items'   => $expatItems,
            'filters' => compact('year', 'month'),
        ]));
    }
}
