<?php

class CheckController extends Controller
{
    public function index(Request $request): void
    {
        $db = $this->db();
        $stats = $db->fetchOne(
            "SELECT
                COUNT(*) AS total,
                SUM(CASE WHEN status='received' THEN 1 ELSE 0 END) AS received,
                SUM(CASE WHEN status='deposited' THEN 1 ELSE 0 END) AS deposited,
                SUM(CASE WHEN status='cleared' THEN 1 ELSE 0 END) AS cleared,
                SUM(CASE WHEN status='bounced' THEN 1 ELSE 0 END) AS bounced
             FROM checks"
        );

        $this->view('checks/index', [
            'title' => lang('adv_finance.checks'),
            'breadcrumbs' => [['label' => lang('adv_finance.title'), 'url' => '/advanced-finance/installments'], ['label' => lang('adv_finance.checks')]],
            'stats' => $stats,
        ], 'app');
    }

    public function datatable(Request $request): void
    {
        $db = $this->db();
        $draw = (int) $request->get('draw', 1);
        $start = (int) $request->get('start', 0);
        $length = (int) $request->get('length', 25);
        $search = $request->get('search')['value'] ?? '';
        $statusFilter = $request->get('status_filter', '');

        $where = '1=1';
        $params = [];
        if ($statusFilter) { $where .= ' AND c.status = ?'; $params[] = $statusFilter; }
        if ($search) {
            $where .= ' AND (c.check_number LIKE ? OR c.drawer_name LIKE ? OR c.bank_name LIKE ? OR m.full_name_en LIKE ?)';
            $like = "%{$search}%";
            $params = array_merge($params, [$like,$like,$like,$like]);
        }

        $total = (int) $db->fetchColumn("SELECT COUNT(*) FROM checks c LEFT JOIN members m ON c.member_id=m.id");
        $filtered = (int) $db->fetchColumn("SELECT COUNT(*) FROM checks c LEFT JOIN members m ON c.member_id=m.id WHERE {$where}", $params);

        $rows = $db->fetchAll(
            "SELECT c.*, m.full_name_en AS member_name, m.membership_number,
                    cur.currency_code
             FROM checks c
             LEFT JOIN members m ON c.member_id = m.id
             LEFT JOIN sys_currencies cur ON c.currency_id = cur.id
             WHERE {$where}
             ORDER BY c.id DESC
             LIMIT {$length} OFFSET {$start}",
            $params
        );

        $data = [];
        foreach ($rows as $r) {
            $data[] = [
                'id'            => $r['id'],
                'check_number'  => $r['check_number'],
                'bank_name'     => $r['bank_name'],
                'drawer_name'   => $r['drawer_name'],
                'amount'        => format_money($r['amount']),
                'check_date'    => format_date($r['check_date']),
                'receive_date'  => format_date($r['receive_date']),
                'member_name'   => $r['member_name'] ?? '—',
                'status'        => $r['status'],
                'status_badge'  => status_badge($r['status']),
            ];
        }
        $this->json(['draw' => $draw, 'recordsTotal' => $total, 'recordsFiltered' => $filtered, 'data' => $data]);
    }

    public function create(Request $request): void
    {
        $db = $this->db();
        $currencies = $db->fetchAll("SELECT * FROM sys_currencies WHERE is_active = 1");
        $bankAccounts = $db->fetchAll("SELECT * FROM bank_accounts WHERE is_active = 1");

        $this->view('checks/create', [
            'title' => lang('adv_finance.register_check'),
            'breadcrumbs' => [['label' => lang('adv_finance.checks'), 'url' => '/advanced-finance/checks'], ['label' => lang('adv_finance.register_check')]],
            'currencies' => $currencies,
            'bankAccounts' => $bankAccounts,
        ], 'app');
    }

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

        $validator = new Validator($request->all(), [
            'check_number'  => 'required|string|max:50',
            'bank_name'     => 'required|string|max:200',
            'branch'        => 'nullable|string|max:200',
            'account_number'=> 'nullable|string|max:50',
            'drawer_name'   => 'required|string|max:300',
            'amount'        => 'required|decimal|min:0.01',
            'currency_id'   => 'required|integer|exists:sys_currencies,id',
            'check_date'    => 'required|date',
            'receive_date'  => 'required|date',
            'member_id'     => 'nullable|integer',
            'bank_account_id' => 'nullable|integer',
            'notes'         => 'nullable|string|max:500',
        ]);

        if ($validator->fails()) { $this->json(['success' => false, 'errors' => $validator->errors()], 422); return; }
        $d = $validator->validated();
        $d['status'] = 'received';
        $d['created_by'] = Auth::id();

        $id = $this->db()->insert('checks', $d);
        $this->audit('create', 'checks', $id, 'Registered check #' . $d['check_number']);
        $this->json(['success' => true, 'message' => lang('adv_finance.saved'), 'redirect' => '/advanced-finance/checks/' . $id]);
    }

    public function show(Request $request): void
    {
        $id = (int)$request->routeParam('id');
        $db = $this->db();
        $check = $db->fetchOne(
            "SELECT c.*, m.full_name_en AS member_name, m.membership_number, cur.currency_code,
                    ba.bank_name_en AS deposit_bank_name
             FROM checks c
             LEFT JOIN members m ON c.member_id = m.id
             LEFT JOIN sys_currencies cur ON c.currency_id = cur.id
             LEFT JOIN bank_accounts ba ON c.bank_account_id = ba.id
             WHERE c.id = ?",
            [$id]
        );
        if (!$check) { $this->abort(404, 'Not found'); return; }

        $history = $db->fetchAll("SELECT * FROM check_status_history WHERE check_id = ? ORDER BY changed_at DESC", [$id]);
        $bankAccounts = $db->fetchAll("SELECT * FROM bank_accounts WHERE is_active = 1");

        $this->view('checks/show', [
            'title' => lang('adv_finance.checks') . ' — ' . $check['check_number'],
            'breadcrumbs' => [['label' => lang('adv_finance.checks'), 'url' => '/advanced-finance/checks'], ['label' => $check['check_number']]],
            'check' => $check,
            'history' => $history,
            'bankAccounts' => $bankAccounts,
        ], 'app');
    }

    public function updateStatus(Request $request): void
    {
        if (!CSRF::validate($request->csrfToken())) { $this->json(['success' => false, 'message' => 'Invalid CSRF'], 403); return; }
        $id = (int)$request->routeParam('id');
        $db = $this->db();
        $check = $db->fetchOne("SELECT * FROM checks WHERE id = ?", [$id]);
        if (!$check) { $this->json(['success' => false, 'message' => 'Not found'], 404); return; }

        $newStatus = $request->post('new_status', '');
        $allowed = [
            'received'  => ['deposited','cancelled','returned'],
            'deposited' => ['cleared','bounced'],
            'bounced'   => ['replaced','received'],
        ];

        $currentAllowed = $allowed[$check['status']] ?? [];
        if (!in_array($newStatus, $currentAllowed)) {
            $this->json(['success' => false, 'message' => 'Invalid status transition from ' . $check['status'] . ' to ' . $newStatus], 422);
            return;
        }

        $updates = ['status' => $newStatus, 'updated_at' => date('Y-m-d H:i:s')];

        if ($newStatus === 'deposited') {
            $updates['deposit_date'] = $request->post('deposit_date', date('Y-m-d'));
            if ($request->post('bank_account_id')) {
                $updates['bank_account_id'] = (int)$request->post('bank_account_id');
            }
        } elseif ($newStatus === 'cleared') {
            $updates['clearance_date'] = $request->post('clearance_date', date('Y-m-d'));
        } elseif ($newStatus === 'bounced') {
            $updates['bounce_date'] = date('Y-m-d');
            $updates['bounce_reason'] = $request->post('bounce_reason', '');
            $updates['bounce_fee'] = (float)$request->post('bounce_fee', 0);
        }

        $notes = $request->post('notes', '');
        if ($notes) { $updates['notes'] = $notes; }

        $db->update('checks', $updates, 'id = ?', [$id]);
        $this->audit('update', 'checks', $id, "Check status changed from {$check['status']} to {$newStatus}");
        $this->json(['success' => true, 'message' => lang('adv_finance.status_updated'), 'redirect' => '/advanced-finance/checks/' . $id]);
    }
}