<?php
namespace App\Controllers;

use Core\Controller;
use App\Helpers\Helper;

class PaymentController extends Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->requireRole(['super_admin','property_owner','accountant','receptionist']);
    }

    public function index(): void
    {
        $page   = max(1,(int)($_GET['page']??1));
        $status = $_GET['status'] ?? '';
        $from   = $_GET['from'] ?? '';
        $to     = $_GET['to'] ?? '';
        $tenantSearch = Helper::sanitize($_GET['tenant'] ?? '');

        $conditions = ['1=1']; $params = [];
        if ($status) { $conditions[]='p.status=?'; $params[]=$status; }
        if ($from)   { $conditions[]='p.payment_date >= ?'; $params[]=$from; }
        if ($to)     { $conditions[]='p.payment_date <= ?'; $params[]=$to; }
        if ($tenantSearch) {
            $conditions[]='(t.first_name LIKE ? OR t.last_name LIKE ? OR t.phone LIKE ?)';
            $params = array_merge($params,["%$tenantSearch%","%$tenantSearch%","%$tenantSearch%"]);
        }
        $where = implode(' AND ',$conditions);

        $total = (int)$this->db->fetchColumn("SELECT COUNT(*) FROM payments p JOIN tenants t ON t.id=p.tenant_id WHERE $where", $params);
        $pagination = $this->paginate($total);
        $payments = $this->db->fetchAll(
            "SELECT p.*, CONCAT(t.first_name,' ',t.last_name) AS tenant_name, t.phone AS tenant_phone,
                    u.unit_number, pm.name AS method_name
             FROM payments p
             JOIN tenants t ON t.id=p.tenant_id
             LEFT JOIN units u ON u.id=p.unit_id
             LEFT JOIN payment_methods pm ON pm.id=p.payment_method_id
             WHERE $where
             ORDER BY p.created_at DESC
             LIMIT ? OFFSET ?",
            array_merge($params, [$pagination['perPage'],$pagination['offset']])
        );
        $totalAmount = (float)$this->db->fetchColumn("SELECT COALESCE(SUM(p.amount),0) FROM payments p JOIN tenants t ON t.id=p.tenant_id WHERE $where AND p.status='completed'", $params);
        $this->adminView('payment.index', compact('payments','pagination','status','from','to','tenantSearch','totalAmount') + ['title'=>'Payments']);
    }

    public function create(): void
    {
        $tenants = $this->db->fetchAll("SELECT id, CONCAT(tenant_code,' - ',first_name,' ',last_name) AS name, phone FROM tenants WHERE status='active' ORDER BY first_name");
        $units   = $this->db->fetchAll("SELECT u.id, CONCAT(p.name,' - Unit ',u.unit_number) AS name FROM units u JOIN properties p ON p.id=u.property_id WHERE u.status='occupied' ORDER BY p.name, u.unit_number");
        $methods = $this->db->fetchAll("SELECT * FROM payment_methods WHERE is_active=1 ORDER BY sort_order");
        $invoices = $this->db->fetchAll("SELECT i.id, CONCAT(i.invoice_number,' - ',CONCAT(t.first_name,' ',t.last_name),' - TZS ',FORMAT(i.balance,0)) AS label FROM invoices i JOIN tenants t ON t.id=i.tenant_id WHERE i.status IN ('sent','overdue','partial') ORDER BY i.due_date");
        $this->adminView('payment.form', compact('tenants','units','methods','invoices') + ['title'=>'Record Payment']);
    }

    public function store(): void
    {
        $this->verifyCsrf();
        $receiptNumber = 'RCP-' . date('Y') . '-' . str_pad((int)$this->db->fetchColumn("SELECT COUNT(*)+1 FROM payments"), 5, '0', STR_PAD_LEFT);

        $data = [
            'payment_ref'      => Helper::generateRef('PAY'),
            'invoice_id'       => $this->input('invoice_id') ?: null,
            'lease_id'         => $this->input('lease_id') ?: null,
            'tenant_id'        => (int)$this->input('tenant_id'),
            'unit_id'          => $this->input('unit_id') ?: null,
            'payment_method_id'=> $this->input('payment_method_id') ?: null,
            'amount'           => (float)$this->input('amount',0),
            'currency'         => 'TZS',
            'transaction_id'   => Helper::sanitize($this->input('transaction_id','')) ?: null,
            'payment_date'     => $this->input('payment_date', date('Y-m-d')),
            'payment_for'      => $this->input('payment_for','rent'),
            'billing_period'   => $this->input('billing_period','monthly'),
            'period_from'      => $this->input('period_from') ?: null,
            'period_to'        => $this->input('period_to') ?: null,
            'notes'            => $this->input('notes','') ?: null,
            'receipt_number'   => $receiptNumber,
            'status'           => 'completed',
            'received_by'      => (int)$_SESSION['user_id'],
            'created_at'       => date('Y-m-d H:i:s'),
            'updated_at'       => date('Y-m-d H:i:s'),
        ];

        try {
            $id = $this->db->insert('payments', $data);
            Helper::setFlash('success', 'Payment recorded. Receipt: ' . $receiptNumber);
            $this->redirect(APP_URL . '/admin/payments/' . $id);
        } catch (\Exception $e) {
            Helper::setFlash('danger', 'Error: ' . $e->getMessage());
            $this->back();
        }
    }

    public function show(string $id): void
    {
        $payment = $this->db->fetch(
            "SELECT p.*, CONCAT(t.first_name,' ',t.last_name) AS tenant_name, t.phone AS tenant_phone,
                    u.unit_number, pr.name AS property_name, pm.name AS method_name,
                    CONCAT(u2.first_name,' ',u2.last_name) AS received_by_name
             FROM payments p
             JOIN tenants t ON t.id=p.tenant_id
             LEFT JOIN units u ON u.id=p.unit_id
             LEFT JOIN properties pr ON pr.id = (SELECT property_id FROM units WHERE id=p.unit_id LIMIT 1)
             LEFT JOIN payment_methods pm ON pm.id=p.payment_method_id
             LEFT JOIN users u2 ON u2.id=p.received_by
             WHERE p.id=?", [$id]
        );
        if (!$payment) { $this->abort(404); return; }
        $settings = $this->db->fetchAll("SELECT `key`, `value` FROM settings WHERE `group`='general'");
        $settingsMap = array_column($settings, 'value', 'key');
        $this->adminView('payment.show', compact('payment','settingsMap') + ['title'=>'Payment Receipt']);
    }

    public function receipt(string $id): void
    {
        $this->show($id);
    }
}
