<?php
require_once __DIR__ . '/BaseModel.php';

/**
 * Lease Management Class
 * Handles lease creation, updates, and lease-related operations
 */
class Lease extends BaseModel {
    protected $tableName = 'leases';
    protected $tenantColumn = null; // Leases are isolated by unit_id/property ownership
    
    public function __construct() {
        parent::__construct();
    }
    
    /**
     * Create a new lease
     */
    public function createLease($data) {
        // Validate required fields
        $required = ['unit_id', 'tenant_id', 'start_date', 'end_date', 'rent_amount', 'deposit_amount'];
        foreach ($required as $field) {
            if (empty($data[$field])) {
                throw new Exception("Field {$field} is required");
            }
        }
        
        // Check if unit is available
        $unitModel = new Unit();
        $unit = $unitModel->getById($data['unit_id']);
        
        if (!$unit) {
            throw new Exception("Unit not found");
        }
        
        if ($unit['status'] !== 'vacant') {
            throw new Exception("Unit is not available for lease");
        }
        
        // Check for overlapping leases
        $this->checkLeaseOverlap($data['unit_id'], $data['start_date'], $data['end_date']);
        
        $leaseData = [
            'unit_id' => $data['unit_id'],
            'tenant_id' => $data['tenant_id'],
            'start_date' => $data['start_date'],
            'end_date' => $data['end_date'],
            'move_in_date' => $data['move_in_date'] ?? null,
            'rent_amount' => $data['rent_amount'],
            'deposit_amount' => $data['deposit_amount'],
            'service_charge' => $data['service_charge'] ?? 0.00,
            'water_deposit' => $data['water_deposit'] ?? 0.00,
            'electricity_deposit' => $data['electricity_deposit'] ?? 0.00,
            'payment_frequency' => $data['payment_frequency'] ?? 'monthly',
            'due_day' => $data['due_day'] ?? 5,
            'grace_period_days' => $data['grace_period_days'] ?? 5,
            'late_fee_type' => $data['late_fee_type'] ?? 'Fixed',
            'late_fee_value' => $data['late_fee_value'] ?? 0.00,
            'escalation_rate_percent' => $data['escalation_rate_percent'] ?? 0.00,
            'status' => 'active',
            'agreement_doc_url' => $data['agreement_doc_url'] ?? null
        ];
        
        $leaseId = $this->create($leaseData);
        
        // Update unit status to occupied
        $unitModel->updateUnit($data['unit_id'], ['status' => 'occupied']);
        
        // Generate initial invoices (deposit, first month rent if applicable)
        $this->generateInitialInvoices($leaseId, $leaseData);
        
        return $leaseId;
    }
    
    /**
     * Update lease
     */
    public function updateLease($id, $data) {
        return $this->update($id, $data);
    }
    
    /**
     * Terminate lease
     */
    public function terminateLease($id, $terminationDate, $reason = null) {
        $lease = $this->getById($id);
        
        if (!$lease) {
            throw new Exception("Lease not found");
        }
        
        // Update lease
        $this->update($id, [
            'status' => 'terminated',
            'termination_date' => $terminationDate
        ]);
        
        // Update unit status to vacant
        $unitModel = new Unit();
        $unitModel->updateUnit($lease['unit_id'], ['status' => 'vacant']);
        
        return true;
    }
    
    /**
     * Get lease with tenant and unit details
     */
    public function getLeaseDetails($id) {
        $lease = $this->getById($id);
        
        if (!$lease) {
            return null;
        }
        
        // Get tenant details
        $sql = "SELECT id, first_name, last_name, email, phone FROM users WHERE id = ?";
        $result = $this->db->query($sql, [$lease['tenant_id']]);
        $lease['tenant'] = $result->fetch_assoc();
        
        // Get unit details
        $unitModel = new Unit();
        $lease['unit'] = $unitModel->getUnitDetails($lease['unit_id']);
        
        // Get invoices for this lease
        $invoiceModel = new Invoice();
        $lease['invoices'] = $invoiceModel->getInvoicesByLease($id);
        
        return $lease;
    }
    
    /**
     * Get active leases for a tenant
     */
    public function getActiveLeasesByTenant($tenantId) {
        $sql = "SELECT l.*, u.unit_number, u.floor_level, p.name as property_name, p.location_area 
                FROM leases l 
                INNER JOIN units u ON l.unit_id = u.id 
                INNER JOIN properties p ON u.property_id = p.id 
                WHERE l.tenant_id = ? AND l.status = 'active' 
                ORDER BY l.start_date DESC";
        
        $result = $this->db->query($sql, [$tenantId]);
        $leases = [];
        
        while ($row = $result->fetch_assoc()) {
            $leases[] = $row;
        }
        
        return $leases;
    }
    
    /**
     * Get active leases for a property
     */
    public function getActiveLeasesByProperty($propertyId) {
        $sql = "SELECT l.*, u.unit_number, u.floor_level, 
                       t.first_name, t.last_name, t.email, t.phone 
                FROM leases l 
                INNER JOIN units u ON l.unit_id = u.id 
                INNER JOIN users t ON l.tenant_id = t.id 
                WHERE u.property_id = ? AND l.status = 'active' 
                ORDER BY u.unit_number";
        
        $result = $this->db->query($sql, [$propertyId]);
        $leases = [];
        
        while ($row = $result->fetch_assoc()) {
            $leases[] = $row;
        }
        
        return $leases;
    }
    
    /**
     * Check for overlapping leases
     */
    private function checkLeaseOverlap($unitId, $startDate, $endDate) {
        $sql = "SELECT id FROM leases 
                WHERE unit_id = ? AND status = 'active' 
                AND (
                    (start_date <= ? AND end_date >= ?) OR
                    (start_date <= ? AND end_date >= ?) OR
                    (start_date >= ? AND end_date <= ?)
                )";
        
        $result = $this->db->query($sql, [$unitId, $startDate, $startDate, $endDate, $endDate, $startDate, $endDate]);
        
        if ($result->num_rows > 0) {
            throw new Exception("Unit already has an active lease for this period");
        }
    }
    
    /**
     * Generate initial invoices (deposit, first month rent)
     */
    private function generateInitialInvoices($leaseId, $leaseData) {
        $invoiceModel = new Invoice();
        
        // Generate deposit invoice
        if ($leaseData['deposit_amount'] > 0) {
            $invoiceModel->createInvoice([
                'lease_id' => $leaseId,
                'tenant_id' => $leaseData['tenant_id'],
                'type' => 'Deposit',
                'description' => 'Security Deposit',
                'amount' => $leaseData['deposit_amount'],
                'total_amount' => $leaseData['deposit_amount'],
                'balance' => $leaseData['deposit_amount'],
                'due_date' => $leaseData['start_date'],
                'status' => 'unpaid'
            ]);
        }
        
        // Generate first month rent if start date is in current or past month
        $startDate = new DateTime($leaseData['start_date']);
        $today = new DateTime();
        
        if ($startDate <= $today) {
            $dueDate = new DateTime($leaseData['start_date']);
            $dueDay = $leaseData['due_day'] ?? 5;
            $dueDate->setDate($dueDate->format('Y'), $dueDate->format('m'), $dueDay);
            
            $invoiceModel->createInvoice([
                'lease_id' => $leaseId,
                'tenant_id' => $leaseData['tenant_id'],
                'type' => 'Rent',
                'description' => 'Rent - ' . $startDate->format('F Y'),
                'amount' => $leaseData['rent_amount'],
                'total_amount' => $leaseData['rent_amount'],
                'balance' => $leaseData['rent_amount'],
                'due_date' => $dueDate->format('Y-m-d'),
                'status' => 'unpaid'
            ]);
        }
    }
    
    /**
     * Get leases expiring soon
     */
    public function getExpiringLeases($days = 30) {
        $sql = "SELECT l.*, u.unit_number, p.name as property_name, 
                       t.first_name, t.last_name, t.email, t.phone 
                FROM leases l 
                INNER JOIN units u ON l.unit_id = u.id 
                INNER JOIN properties p ON u.property_id = p.id 
                INNER JOIN users t ON l.tenant_id = t.id 
                WHERE l.status = 'active' 
                AND l.end_date BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL ? DAY)
                ORDER BY l.end_date ASC";
        
        $result = $this->db->query($sql, [$days]);
        $leases = [];
        
        while ($row = $result->fetch_assoc()) {
            $leases[] = $row;
        }
        
        return $leases;
    }
}
?>
