<?php
class CashRegisterController extends Controller
{
    public function index(Request $request): void
    {
        $db = $this->db();
        $registers = $db->fetchAll(
            "SELECT cr.*, crs.id AS session_id, crs.status AS session_status,
                    crs.opening_balance, crs.opened_at, crs.total_cash_in, crs.total_transactions,
                    u.full_name_en AS operator_name
             FROM cash_registers cr
             LEFT JOIN cash_register_sessions crs ON cr.id=crs.register_id AND crs.status='open'
             LEFT JOIN auth_users u ON crs.user_id=u.id
             WHERE cr.is_active=1
             ORDER BY cr.id"
        );

        // Current user's active session
        $mySession = $db->fetchOne(
            "SELECT crs.*, cr.name_en AS register_name
             FROM cash_register_sessions crs
             JOIN cash_registers cr ON crs.register_id=cr.id
             WHERE crs.user_id=? AND crs.status='open'",
            [Auth::id()]
        );

        $sessionTransactions = [];
        if ($mySession) {
            $sessionTransactions = $db->fetchAll(
                "SELECT crt.*, p.payment_number
                 FROM cash_register_transactions crt
                 LEFT JOIN payments p ON crt.reference_type='payment' AND crt.reference_id=p.id
                 WHERE crt.session_id=?
                 ORDER BY crt.created_at DESC
                 LIMIT 50",
                [$mySession['id']]
            );
        }

        $this->view('cashier/index', [
            'title' => lang('finance.cash_register'),
            'breadcrumbs' => [
                ['label' => lang('finance.title'), 'url' => '/finance/invoices'],
                ['label' => lang('finance.cash_register')],
            ],
            'registers'    => $registers,
            'mySession'    => $mySession,
            'transactions' => $sessionTransactions,
        ]);
    }

    public function open(Request $request): void
    {
        if (!CSRF::validate($request->csrfToken())) {
            $this->json(['success' => false, 'message' => 'Invalid security token'], 403);
            return;
        }

        $registerId     = (int)$request->post('register_id');
        $openingBalance = round((float)$request->post('opening_balance', 0), 4);

        $db = $this->db();
        $db->execute("CALL sp_open_cash_register_session(?, ?, ?, @sess_id, @result)", [
            $registerId, Auth::id(), $openingBalance
        ]);
        $result = $db->fetchOne("SELECT @sess_id AS session_id, @result AS msg");

        if (!$result['session_id']) {
            $this->json(['success' => false, 'message' => $result['msg']], 422);
            return;
        }

        AuditLog::log('create', 'finance', 'cash_register_session', (int)$result['session_id'], 'Opened cash register session');
        $this->json(['success' => true, 'message' => $result['msg'], 'redirect' => '/finance/cashier']);
    }

    public function close(Request $request): void
    {
        if (!CSRF::validate($request->csrfToken())) {
            $this->json(['success' => false, 'message' => 'Invalid security token'], 403);
            return;
        }

        $sessionId      = (int)$request->post('session_id');
        $closingBalance = round((float)$request->post('closing_balance', 0), 4);

        $db = $this->db();
        $db->execute("CALL sp_close_cash_register_session(?, ?, ?, @close_result)", [
            $sessionId, $closingBalance, Auth::id()
        ]);
        $result = $db->fetchOne("SELECT @close_result AS msg");

        AuditLog::log('update', 'finance', 'cash_register_session', $sessionId, 'Closed cash register session');
        $this->json(['success' => true, 'message' => $result['msg'], 'redirect' => '/finance/cashier']);
    }

    public function sessions(Request $request): void
    {
        $this->view('cashier/sessions', [
            'title' => lang('finance.session_history'),
            'breadcrumbs' => [
                ['label' => lang('finance.title'), 'url' => '/finance/invoices'],
                ['label' => lang('finance.cash_register'), 'url' => '/finance/cashier'],
                ['label' => lang('finance.session_history')],
            ],
        ]);
    }

    public function sessionsDatatable(Request $request): void
    {
        $db = $this->db();
        $draw   = (int)$request->get('draw', 1);
        $start  = (int)$request->get('start', 0);
        $length = (int)$request->get('length', 25);

        $totalRecords = (int)$db->fetchColumn("SELECT COUNT(*) FROM cash_register_sessions");

        $rows = $db->fetchAll(
            "SELECT crs.*, cr.name_en AS register_name, u.full_name_en AS operator_name
             FROM cash_register_sessions crs
             JOIN cash_registers cr ON crs.register_id=cr.id
             JOIN auth_users u ON crs.user_id=u.id
             ORDER BY crs.id DESC
             LIMIT {$length} OFFSET {$start}"
        );

        $data = [];
        foreach ($rows as $row) {
            $data[] = [
                'id'              => $row['id'],
                'register_name'   => e($row['register_name']),
                'operator_name'   => e($row['operator_name']),
                'session_date'    => format_date($row['session_date']),
                'opening_balance' => money($row['opening_balance']),
                'closing_balance' => $row['closing_balance'] !== null ? money($row['closing_balance']) : '-',
                'variance'        => $row['variance'] !== null ? money($row['variance']) : '-',
                'total_transactions' => $row['total_transactions'],
                'status'          => status_badge($row['status']),
            ];
        }

        $this->json([
            'draw'            => $draw,
            'recordsTotal'    => $totalRecords,
            'recordsFiltered' => $totalRecords,
            'data'            => $data,
        ]);
    }
}