<?php

class RefundController extends Controller
{
    public function index(Request $request): void
    {
        $this->view('refunds/index', [
            'title' => lang('adv_finance.refunds'),
            'breadcrumbs' => [['label' => lang('adv_finance.title'), 'url' => '/advanced-finance/installments'], ['label' => lang('adv_finance.refunds')]],
        ], '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'] ?? '';

        $where = '1=1';
        $params = [];
        if ($search) {
            $where .= ' AND (r.refund_number LIKE ? OR m.full_name_en LIKE ?)';
            $like = "%{$search}%";
            $params = [$like, $like];
        }
        $sf = $request->get('status_filter', '');
        if ($sf) { $where .= ' AND r.status = ?'; $params[] = $sf; }

        $total = (int)$db->fetchColumn("SELECT COUNT(*) FROM refunds r JOIN members m ON r.member_id=m.id");
        $filtered = (int)$db->fetchColumn("SELECT COUNT(*) FROM refunds r JOIN members m ON r.member_id=m.id WHERE {$where}", $params);
        $rows = $db->fetchAll(
            "SELECT r.*, m.full_name_en AS member_name, m.membership_number, pm.name_en AS method_name
             FROM refunds r
             JOIN members m ON r.member_id = m.id
             JOIN payment_methods pm ON r.refund_method_id = pm.id
             WHERE {$where}
             ORDER BY r.id DESC LIMIT {$length} OFFSET {$start}",
            $params
        );

        $data = [];
        foreach ($rows as $r) {
            $data[] = [
                'id'            => $r['id'],
                'refund_number' => $r['refund_number'],
                'member_name'   => $r['member_name'],
                'refund_amount' => format_money($r['refund_amount']),
                'refund_date'   => format_date($r['refund_date']),
                'method_name'   => $r['method_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
    {
        $methods = $this->db()->fetchAll("SELECT * FROM payment_methods WHERE is_active = 1 ORDER BY sort_order");
        $this->view('refunds/create', [
            'title' => lang('adv_finance.create_refund'),
            'breadcrumbs' => [['label' => lang('adv_finance.refunds'), 'url' => '/advanced-finance/refunds'], ['label' => lang('common.create')]],
            'methods' => $methods,
        ], '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(), [
            'member_id'        => 'required|integer|exists:members,id',
            'refund_amount'    => 'required|decimal|min:0.01',
            'refund_method_id' => 'required|integer|exists:payment_methods,id',
            'reason'           => 'required|string|max:2000',
            'original_payment_id' => 'nullable|integer',
            'original_invoice_id' => 'nullable|integer',
            'notes'            => 'nullable|string|max:2000',
        ]);
        if ($validator->fails()) { $this->json(['success' => false, 'errors' => $validator->errors()], 422); return; }
        $d = $validator->validated();
        $db = $this->db();

        $currency = $db->fetchOne("SELECT id FROM sys_currencies WHERE is_default = 1 LIMIT 1");
        $refundNumber = SequenceGenerator::next('refund_number');

        $id = $db->insert('refunds', [
            'refund_number'       => $refundNumber,
            'member_id'           => $d['member_id'],
            'original_payment_id' => $d['original_payment_id'] ?: null,
            'original_invoice_id' => $d['original_invoice_id'] ?: null,
            'refund_amount'       => $d['refund_amount'],
            'currency_id'         => $currency['id'] ?? 1,
            'refund_method_id'    => $d['refund_method_id'],
            'refund_date'         => date('Y-m-d'),
            'reason'              => $d['reason'],
            'status'              => 'pending',
            'notes'               => $d['notes'] ?? null,
            'created_by'          => Auth::id(),
        ]);

        $this->audit('create', 'refunds', $id, 'Created refund request ' . $refundNumber);
        $this->json(['success' => true, 'message' => lang('adv_finance.saved'), 'redirect' => '/advanced-finance/refunds/' . $id]);
    }

    public function show(Request $request): void
    {
        $id = (int)$request->routeParam('id');
        $db = $this->db();
        $refund = $db->fetchOne(
            "SELECT r.*, m.full_name_en AS member_name, m.membership_number, pm.name_en AS method_name,
                    p.payment_number AS original_payment_number,
                    i.invoice_number AS original_invoice_number
             FROM refunds r
             JOIN members m ON r.member_id = m.id
             JOIN payment_methods pm ON r.refund_method_id = pm.id
             LEFT JOIN payments p ON r.original_payment_id = p.id
             LEFT JOIN invoices i ON r.original_invoice_id = i.id
             WHERE r.id = ?",
            [$id]
        );
        if (!$refund) { $this->abort(404, 'Not found'); return; }

        $this->view('refunds/show', [
            'title' => $refund['refund_number'],
            'breadcrumbs' => [['label' => lang('adv_finance.refunds'), 'url' => '/advanced-finance/refunds'], ['label' => $refund['refund_number']]],
            'refund' => $refund,
        ], 'app');
    }

    public function approve(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();
        $r = $db->fetchOne("SELECT * FROM refunds WHERE id = ? AND status = 'pending'", [$id]);
        if (!$r) { $this->json(['success' => false, 'message' => 'Not pending'], 422); return; }
        $db->update('refunds', ['status' => 'approved', 'approved_by' => Auth::id(), 'approved_at' => date('Y-m-d H:i:s')], 'id = ?', [$id]);
        $this->audit('approve', 'refunds', $id, 'Approved refund');
        $this->json(['success' => true, 'message' => lang('adv_finance.status_updated'), 'redirect' => '/advanced-finance/refunds/' . $id]);
    }

    public function process(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();
        $r = $db->fetchOne("SELECT * FROM refunds WHERE id = ? AND status = 'approved'", [$id]);
        if (!$r) { $this->json(['success' => false, 'message' => 'Not approved'], 422); return; }

        $refNum = $request->post('reference_number', '');
        $db->update('refunds', [
            'status' => 'processed',
            'processed_by' => Auth::id(),
            'processed_at' => date('Y-m-d H:i:s'),
            'reference_number' => $refNum ?: null,
        ], 'id = ?', [$id]);

        $db->execute("CALL sp_recalculate_member_balance(?)", [$r['member_id']]);

        $this->audit('update', 'refunds', $id, 'Processed refund');
        $this->json(['success' => true, 'message' => lang('adv_finance.status_updated'), 'redirect' => '/advanced-finance/refunds/' . $id]);
    }

    public function reject(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();
        $r = $db->fetchOne("SELECT * FROM refunds WHERE id = ? AND status = 'pending'", [$id]);
        if (!$r) { $this->json(['success' => false, 'message' => 'Not pending'], 422); return; }
        $db->update('refunds', [
            'status' => 'rejected',
            'rejection_reason' => $request->post('rejection_reason', ''),
        ], 'id = ?', [$id]);
        $this->audit('reject', 'refunds', $id, 'Rejected refund');
        $this->json(['success' => true, 'message' => lang('adv_finance.status_updated'), 'redirect' => '/advanced-finance/refunds/' . $id]);
    }
}