<?php

class WriteOffController extends Controller
{
    public function index(Request $request): void
    {
        $this->view('write-offs/index', [
            'title' => lang('adv_finance.write_offs'),
            'breadcrumbs' => [['label' => lang('adv_finance.title'), 'url' => '/advanced-finance/installments'], ['label' => lang('adv_finance.write_offs')]],
        ], '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 (w.write_off_number LIKE ? OR m.full_name_en LIKE ?)'; $like = "%{$search}%"; $params = [$like,$like]; }

        $total = (int)$db->fetchColumn("SELECT COUNT(*) FROM write_offs w JOIN members m ON w.member_id=m.id");
        $filtered = (int)$db->fetchColumn("SELECT COUNT(*) FROM write_offs w JOIN members m ON w.member_id=m.id WHERE {$where}", $params);
        $rows = $db->fetchAll(
            "SELECT w.*, m.full_name_en AS member_name, m.membership_number, i.invoice_number
             FROM write_offs w
             JOIN members m ON w.member_id = m.id
             LEFT JOIN invoices i ON w.invoice_id = i.id
             WHERE {$where} ORDER BY w.id DESC LIMIT {$length} OFFSET {$start}",
            $params
        );
        $data = [];
        foreach ($rows as $r) {
            $data[] = [
                'id' => $r['id'], 'write_off_number' => $r['write_off_number'],
                'member_name' => $r['member_name'], 'invoice_number' => $r['invoice_number'] ?? '—',
                'amount' => format_money($r['amount']), '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
    {
        $this->view('write-offs/create', [
            'title' => lang('adv_finance.create_write_off'),
            'breadcrumbs' => [['label' => lang('adv_finance.write_offs'), 'url' => '/advanced-finance/write-offs'], ['label' => lang('common.create')]],
        ], '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',
            'invoice_id'=> 'nullable|integer',
            'amount'    => 'required|decimal|min:0.01',
            'reason'    => 'required|string|max:2000',
            'notes'     => 'nullable|string|max:2000',
        ]);
        if ($validator->fails()) { $this->json(['success' => false, 'errors' => $validator->errors()], 422); return; }
        $d = $validator->validated();
        $woNumber = SequenceGenerator::next('write_off_number');
        $id = $this->db()->insert('write_offs', [
            'write_off_number' => $woNumber, 'member_id' => $d['member_id'],
            'invoice_id' => $d['invoice_id'] ?: null, 'amount' => $d['amount'],
            'reason' => $d['reason'], 'status' => 'pending', 'notes' => $d['notes'] ?? null,
            'created_by' => Auth::id(),
        ]);
        $this->audit('create', 'write_offs', $id, 'Created write-off ' . $woNumber);
        $this->json(['success' => true, 'message' => lang('adv_finance.saved'), 'redirect' => '/advanced-finance/write-offs/' . $id]);
    }

    public function show(Request $request): void
    {
        $id = (int)$request->routeParam('id');
        $wo = $this->db()->fetchOne(
            "SELECT w.*, m.full_name_en AS member_name, m.membership_number, i.invoice_number
             FROM write_offs w JOIN members m ON w.member_id=m.id LEFT JOIN invoices i ON w.invoice_id=i.id WHERE w.id = ?",
            [$id]
        );
        if (!$wo) { $this->abort(404, 'Not found'); return; }
        $this->view('write-offs/show', [
            'title' => $wo['write_off_number'],
            'breadcrumbs' => [['label' => lang('adv_finance.write_offs'), 'url' => '/advanced-finance/write-offs'], ['label' => $wo['write_off_number']]],
            'wo' => $wo,
        ], '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();
        $wo = $db->fetchOne("SELECT * FROM write_offs WHERE id = ? AND status = 'pending'", [$id]);
        if (!$wo) { $this->json(['success' => false, 'message' => 'Not pending'], 422); return; }
        $db->update('write_offs', ['status' => 'approved', 'approved_by' => Auth::id(), 'approved_at' => date('Y-m-d H:i:s')], 'id = ?', [$id]);
        $this->audit('approve', 'write_offs', $id, 'Approved write-off');
        $this->json(['success' => true, 'message' => lang('adv_finance.status_updated'), 'redirect' => '/advanced-finance/write-offs/' . $id]);
    }

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

        $db->update('write_offs', ['status' => 'posted', 'posted_by' => Auth::id(), 'posted_at' => date('Y-m-d H:i:s')], 'id = ?', [$id]);

        if ($wo['invoice_id']) {
            $inv = $db->fetchOne("SELECT * FROM invoices WHERE id = ?", [$wo['invoice_id']]);
            if ($inv) {
                $db->update('invoices', [
                    'status' => 'written_off',
                    'status_changed_at' => date('Y-m-d H:i:s'),
                ], 'id = ?', [$wo['invoice_id']]);
            }
        }

        $db->execute("CALL sp_recalculate_member_balance(?)", [$wo['member_id']]);
        $this->audit('update', 'write_offs', $id, 'Posted write-off');
        $this->json(['success' => true, 'message' => lang('adv_finance.posted'), 'redirect' => '/advanced-finance/write-offs/' . $id]);
    }
}