<?php
namespace App\Controllers;

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

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

    public function index(): void
    {
        $this->adminView('reports.index', ['title' => 'Reports']);
    }

    public function rentCollection(): void
    {
        $from  = $_GET['from']  ?? date('Y-m-01');
        $to    = $_GET['to']    ?? date('Y-m-d');
        $propId = $_GET['property_id'] ?? '';
        $conditions = ['p.payment_date BETWEEN ? AND ?', 'p.status=?'];
        $params = [$from, $to, 'completed'];
        if ($propId) { $conditions[] = 'u.property_id=?'; $params[] = $propId; }
        $where = implode(' AND ', $conditions);
        $data = $this->db->fetchAll(
            "SELECT p.*, CONCAT(t.first_name,' ',t.last_name) AS tenant_name, u.unit_number,
                    pr.name AS property_name, 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 properties pr ON pr.id=u.property_id
             LEFT JOIN payment_methods pm ON pm.id=p.payment_method_id
             WHERE $where ORDER BY p.payment_date DESC", $params
        );
        $total = array_sum(array_column($data,'amount'));
        $properties = $this->db->fetchAll("SELECT id,name FROM properties ORDER BY name");
        $this->adminView('reports.rent-collection', compact('data','total','from','to','propId','properties') + ['title'=>'Rent Collection Report']);
    }

    public function occupancy(): void
    {
        $propId = $_GET['property_id'] ?? '';
        $conditions = ['1=1']; $params = [];
        if ($propId) { $conditions[]='u.property_id=?'; $params[]=$propId; }
        $where = implode(' AND ',$conditions);
        $units = $this->db->fetchAll(
            "SELECT u.*, p.name AS property_name, b.name AS building_name,
                    CONCAT(t.first_name,' ',t.last_name) AS current_tenant
             FROM units u
             JOIN properties p ON p.id=u.property_id
             JOIN buildings b ON b.id=u.building_id
             LEFT JOIN leases l ON l.unit_id=u.id AND l.status='active'
             LEFT JOIN tenants t ON t.id=l.tenant_id
             WHERE $where ORDER BY p.name, b.name, u.unit_number", $params
        );
        $summary = [
            'total'       => count($units),
            'occupied'    => count(array_filter($units, fn($u)=>$u['status']==='occupied')),
            'available'   => count(array_filter($units, fn($u)=>$u['status']==='available')),
            'maintenance' => count(array_filter($units, fn($u)=>$u['status']==='maintenance')),
        ];
        $summary['rate'] = $summary['total'] > 0 ? round(($summary['occupied']/$summary['total'])*100,1) : 0;
        $properties = $this->db->fetchAll("SELECT id,name FROM properties ORDER BY name");
        $this->adminView('reports.occupancy', compact('units','summary','propId','properties') + ['title'=>'Occupancy Report']);
    }

    public function incomeExpense(): void
    {
        $year  = (int)($_GET['year'] ?? date('Y'));
        $income = $this->db->fetchAll(
            "SELECT MONTH(payment_date) AS month, SUM(amount) AS total
             FROM payments WHERE status='completed' AND YEAR(payment_date)=?
             GROUP BY MONTH(payment_date) ORDER BY month", [$year]
        );
        $expenses = $this->db->fetchAll(
            "SELECT MONTH(expense_date) AS month, SUM(amount) AS total
             FROM expenses WHERE status='approved' AND YEAR(expense_date)=?
             GROUP BY MONTH(expense_date) ORDER BY month", [$year]
        );
        $months = range(1,12);
        $incomeMap   = array_column($income,  'total','month');
        $expenseMap  = array_column($expenses,'total','month');
        $chartData = [];
        foreach ($months as $m) {
            $chartData[] = ['month'=>date('M',mktime(0,0,0,$m,1)), 'income'=>(float)($incomeMap[$m]??0), 'expense'=>(float)($expenseMap[$m]??0)];
        }
        $totals = [
            'income'  => array_sum(array_column($income,'total')),
            'expense' => array_sum(array_column($expenses,'total')),
        ];
        $totals['profit'] = $totals['income'] - $totals['expense'];
        $this->adminView('reports.income-expense', compact('chartData','totals','year') + ['title'=>'Income & Expense Report']);
    }

    public function tenantList(): void
    {
        $status = $_GET['status'] ?? 'active';
        $tenants = $this->db->fetchAll(
            "SELECT t.*, r.name AS region_name,
                    l.lease_number, l.start_date, l.end_date, l.monthly_rent,
                    u.unit_number, p.name AS property_name
             FROM tenants t
             LEFT JOIN regions r ON r.id=t.region_id
             LEFT JOIN leases l ON l.tenant_id=t.id AND l.status='active'
             LEFT JOIN units u ON u.id=l.unit_id
             LEFT JOIN properties p ON p.id=l.property_id
             WHERE t.status=?
             ORDER BY t.first_name", [$status]
        );
        $this->adminView('reports.tenant-list', compact('tenants','status') + ['title'=>'Tenant List Report']);
    }

    public function maintenance(): void
    {
        $from = $_GET['from'] ?? date('Y-m-01');
        $to   = $_GET['to']   ?? date('Y-m-d');
        $data = $this->db->fetchAll(
            "SELECT mr.*, u.unit_number, p.name AS property_name,
                    CONCAT(t.first_name,' ',t.last_name) AS tenant_name
             FROM maintenance_requests mr
             JOIN units u ON u.id=mr.unit_id
             JOIN properties p ON p.id=mr.property_id
             LEFT JOIN tenants t ON t.id=mr.tenant_id
             WHERE DATE(mr.created_at) BETWEEN ? AND ?
             ORDER BY FIELD(mr.priority,'emergency','high','medium','low')", [$from,$to]
        );
        $summary = [
            'total'      => count($data),
            'completed'  => count(array_filter($data,fn($r)=>$r['status']==='completed')),
            'total_cost' => array_sum(array_column($data,'actual_cost')),
        ];
        $this->adminView('reports.maintenance', compact('data','summary','from','to') + ['title'=>'Maintenance Report']);
    }

    public function exportPdf(): void
    {
        $this->verifyCsrf();
        $type = $this->input('report_type','');
        // Simple HTML print export - redirects to report page with print=1
        Helper::setFlash('info', 'Use browser Print (Ctrl+P) to save as PDF.');
        $this->back();
    }

    public function exportExcel(): void
    {
        $this->verifyCsrf();
        $type = $this->input('report_type','rent-collection');
        $from = $this->input('from', date('Y-m-01'));
        $to   = $this->input('to', date('Y-m-d'));
        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename="zabibu-report-'.$type.'-'.date('Ymd').'.csv"');
        $out = fopen('php://output', 'w');
        fprintf($out, chr(0xEF).chr(0xBB).chr(0xBF)); // UTF-8 BOM
        if ($type === 'rent-collection') {
            fputcsv($out, ['Receipt No','Tenant','Unit','Amount (TZS)','Method','Date','Status']);
            $rows = $this->db->fetchAll(
                "SELECT p.receipt_number, CONCAT(t.first_name,' ',t.last_name), u.unit_number, p.amount, pm.name, p.payment_date, p.status
                 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 p.payment_date BETWEEN ? AND ? ORDER BY p.payment_date DESC", [$from,$to]
            );
            foreach ($rows as $r) fputcsv($out, array_values($r));
        }
        fclose($out);
        exit;
    }
}
