<?php

class PayrollController extends Controller
{
    public function index(): void
    {
        Auth::requirePermission('payroll', 'view');

        $runModel = new PayrollRun();
        $db = Database::getConnection();

        $this->view('payroll.index', [
            'pageTitle' => 'Payroll',
            'runs'      => $runModel->listRuns(),
            'csrf'      => $this->csrfField(),
            'currentMonth' => (int) date('n'),
            'currentYear'  => (int) date('Y'),
        ]);
    }

    public function generate(): void
    {
        Auth::requirePermission('payroll', 'add');
        $this->verifyCsrf();

        $month = (int) $this->input('period_month', date('n'));
        $year = (int) $this->input('period_year', date('Y'));

        $runModel = new PayrollRun();
        if ($runModel->existsForPeriod($month, $year)) {
            $this->redirect('payroll');
            return;
        }

        $runId = $runModel->generate($month, $year, Auth::id());
        AuditLogger::log(Auth::id(), 'PAYROLL_GENERATE', 'payroll', "Generated payroll run for {$month}/{$year}");
        $this->redirect('payroll/show?id=' . $runId);
    }

    public function show(): void
    {
        Auth::requirePermission('payroll', 'view');
        $id = (int) $this->input('id');

        $runModel = new PayrollRun();
        $run = $runModel->findWithItems($id);
        if (!$run) {
            $this->redirect('payroll');
            return;
        }

        $db = Database::getConnection();
        $this->view('payroll.show', [
            'pageTitle'       => 'Payroll Run',
            'run'             => $run,
            'financeAccounts' => $db->query("SELECT * FROM finance_accounts WHERE is_active = 1")->fetchAll(),
            'csrf'            => $this->csrfField(),
        ]);
    }

    public function updateItem(): void
    {
        Auth::requirePermission('payroll', 'edit');
        $this->verifyCsrf();

        $itemId = (int) $this->input('item_id');
        $runId = (int) $this->input('run_id');
        $additions = (float) $this->input('additions', 0);
        $deductions = (float) $this->input('deductions', 0);

        (new PayrollRun())->updateItem($itemId, $additions, $deductions);
        AuditLogger::log(Auth::id(), 'PAYROLL_ITEM_UPDATE', 'payroll', "Updated payroll item #{$itemId}");
        $this->redirect('payroll/show?id=' . $runId);
    }

    public function finalize(): void
    {
        Auth::requirePermission('payroll', 'edit');
        $this->verifyCsrf();

        $runId = (int) $this->input('id');
        (new PayrollRun())->finalize($runId);
        AuditLogger::log(Auth::id(), 'PAYROLL_FINALIZE', 'payroll', "Finalized payroll run #{$runId}");
        $this->redirect('payroll/show?id=' . $runId);
    }

    public function payItem(): void
    {
        Auth::requirePermission('payroll', 'edit');
        $this->verifyCsrf();

        $itemId = (int) $this->input('item_id');
        $runId = (int) $this->input('run_id');
        $accountId = (int) $this->input('finance_account_id', 0);

        if ($accountId > 0) {
            (new PayrollRun())->payItem($itemId, $accountId, Auth::id());
            AuditLogger::log(Auth::id(), 'PAYROLL_PAY_ITEM', 'payroll', "Paid payroll item #{$itemId}");
        }
        $this->redirect('payroll/show?id=' . $runId);
    }

    public function payAll(): void
    {
        Auth::requirePermission('payroll', 'edit');
        $this->verifyCsrf();

        $runId = (int) $this->input('id');
        $accountId = (int) $this->input('finance_account_id', 0);

        if ($accountId > 0) {
            (new PayrollRun())->payAllUnpaid($runId, $accountId, Auth::id());
            AuditLogger::log(Auth::id(), 'PAYROLL_PAY_ALL', 'payroll', "Paid all unpaid items in run #{$runId}");
        }
        $this->redirect('payroll/show?id=' . $runId);
    }
}
