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

/**
 * Unit Sale Management Class
 * Handles apartment/unit sales and installment management
 */
class UnitSale extends BaseModel {
    protected $tableName = 'unit_sales';
    protected $tenantColumn = null; // Sales are isolated by unit ownership
    
    public function __construct() {
        parent::__construct();
    }
    
    /**
     * Create a new unit sale
     */
    public function createSale($data) {
        // Validate required fields
        $required = ['unit_id', 'buyer_id', 'agreed_price', 'total_payable'];
        foreach ($required as $field) {
            if (empty($data[$field])) {
                throw new Exception("Field {$field} is required");
            }
        }
        
        // Check if unit is available for sale
        $unitModel = new Unit();
        $unit = $unitModel->getById($data['unit_id']);
        
        if (!$unit) {
            throw new Exception("Unit not found");
        }
        
        if (!$unit['is_for_sale'] || $unit['status'] === 'sold') {
            throw new Exception("Unit is not available for sale");
        }
        
        $saleData = [
            'unit_id' => $data['unit_id'],
            'buyer_id' => $data['buyer_id'],
            'agent_id' => $data['agent_id'] ?? null,
            'agreed_price' => $data['agreed_price'],
            'reservation_fee' => $data['reservation_fee'] ?? 0.00,
            'stamp_duty' => $data['stamp_duty'] ?? 0.00,
            'legal_fees' => $data['legal_fees'] ?? 0.00,
            'vat_amount' => $data['vat_amount'] ?? 0.00,
            'total_payable' => $data['total_payable'],
            'offer_letter_date' => $data['offer_letter_date'] ?? null,
            'sale_agreement_date' => $data['sale_agreement_date'] ?? null,
            'completion_date' => $data['completion_date'] ?? null,
            'lawyer_name' => $data['lawyer_name'] ?? null,
            'lawyer_contact' => $data['lawyer_contact'] ?? null,
            'status' => $data['status'] ?? 'draft',
            'documents_folder_id' => $data['documents_folder_id'] ?? null
        ];
        
        $saleId = $this->create($saleData);
        
        // Update unit status
        $unitModel->updateUnit($data['unit_id'], ['status' => 'reserved']);
        
        // Create installments if provided
        if (!empty($data['installments']) && is_array($data['installments'])) {
            $this->createInstallments($saleId, $data['installments']);
        }
        
        return $saleId;
    }
    
    /**
     * Update sale
     */
    public function updateSale($id, $data) {
        return $this->update($id, $data);
    }
    
    /**
     * Complete sale
     */
    public function completeSale($saleId) {
        $sale = $this->getById($saleId);
        
        if (!$sale) {
            throw new Exception("Sale not found");
        }
        
        // Update sale status
        $this->update($saleId, [
            'status' => 'completed',
            'completion_date' => date('Y-m-d')
        ]);
        
        // Mark unit as sold
        $unitModel = new Unit();
        $unitModel->markAsSold($sale['unit_id']);
        
        return true;
    }
    
    /**
     * Get sale with details
     */
    public function getSaleDetails($id) {
        $sale = $this->getById($id);
        
        if (!$sale) {
            return null;
        }
        
        // Get buyer details
        $sql = "SELECT id, first_name, last_name, email, phone FROM users WHERE id = ?";
        $result = $this->db->query($sql, [$sale['buyer_id']]);
        $sale['buyer'] = $result->fetch_assoc();
        
        // Get agent details if exists
        if ($sale['agent_id']) {
            $result = $this->db->query($sql, [$sale['agent_id']]);
            $sale['agent'] = $result->fetch_assoc();
        }
        
        // Get unit details
        $unitModel = new Unit();
        $sale['unit'] = $unitModel->getUnitDetails($sale['unit_id']);
        
        // Get installments
        $sale['installments'] = $this->getInstallments($id);
        
        // Calculate payment progress
        $sale['payment_progress'] = $this->calculatePaymentProgress($id);
        
        return $sale;
    }
    
    /**
     * Get sales by buyer
     */
    public function getSalesByBuyer($buyerId) {
        $sql = "SELECT s.*, u.unit_number, u.floor_level, p.name as property_name, p.location_area 
                FROM unit_sales s 
                INNER JOIN units u ON s.unit_id = u.id 
                INNER JOIN properties p ON u.property_id = p.id 
                WHERE s.buyer_id = ? 
                ORDER BY s.created_at DESC";
        
        $result = $this->db->query($sql, [$buyerId]);
        $sales = [];
        
        while ($row = $result->fetch_assoc()) {
            $sales[] = $row;
        }
        
        return $sales;
    }
    
    /**
     * Get sales by property
     */
    public function getSalesByProperty($propertyId) {
        $sql = "SELECT s.*, u.unit_number, u.floor_level, 
                       b.first_name, b.last_name, b.email, b.phone 
                FROM unit_sales s 
                INNER JOIN units u ON s.unit_id = u.id 
                INNER JOIN users b ON s.buyer_id = b.id 
                WHERE u.property_id = ? 
                ORDER BY s.created_at DESC";
        
        $result = $this->db->query($sql, [$propertyId]);
        $sales = [];
        
        while ($row = $result->fetch_assoc()) {
            $sales[] = $row;
        }
        
        return $sales;
    }
    
    /**
     * Create installments for a sale
     */
    public function createInstallments($saleId, $installments) {
        $installmentModel = new SaleInstallment();
        
        foreach ($installments as $installment) {
            $installmentModel->create([
                'sale_id' => $saleId,
                'milestone_name' => $installment['milestone_name'] ?? null,
                'due_date' => $installment['due_date'],
                'amount' => $installment['amount'],
                'penalty_rate' => $installment['penalty_rate'] ?? 0.00,
                'status' => 'pending'
            ]);
        }
    }
    
    /**
     * Get installments for a sale
     */
    public function getInstallments($saleId) {
        $sql = "SELECT * FROM sale_installments WHERE sale_id = ? ORDER BY due_date ASC";
        $result = $this->db->query($sql, [$saleId]);
        $installments = [];
        
        while ($row = $result->fetch_assoc()) {
            $installments[] = $row;
        }
        
        return $installments;
    }
    
    /**
     * Calculate payment progress
     */
    public function calculatePaymentProgress($saleId) {
        $sale = $this->getById($saleId);
        
        // Get total paid from installments
        $sql = "SELECT SUM(amount) as total_paid 
                FROM sale_installments 
                WHERE sale_id = ? AND status = 'paid'";
        
        $result = $this->db->query($sql, [$saleId]);
        $row = $result->fetch_assoc();
        $totalPaid = $row['total_paid'] ?? 0.00;
        
        $progress = ($totalPaid / $sale['total_payable']) * 100;
        
        return [
            'total_payable' => $sale['total_payable'],
            'total_paid' => $totalPaid,
            'balance' => $sale['total_payable'] - $totalPaid,
            'progress_percent' => round($progress, 2)
        ];
    }
    
    /**
     * Record installment payment
     */
    public function recordInstallmentPayment($installmentId, $paymentData) {
        $installmentModel = new SaleInstallment();
        $installment = $installmentModel->getById($installmentId);
        
        if (!$installment) {
            throw new Exception("Installment not found");
        }
        
        // Record payment
        $paymentModel = new Payment();
        $paymentId = $paymentModel->recordPayment([
            'payer_id' => $paymentData['payer_id'],
            'amount' => $installment['amount'],
            'payment_method' => $paymentData['payment_method'],
            'transaction_reference' => $paymentData['transaction_reference'],
            'status' => 'verified'
        ]);
        
        // Update installment status
        $installmentModel->update($installmentId, [
            'status' => 'paid',
            'paid_date' => date('Y-m-d H:i:s'),
            'receipt_number' => $paymentData['receipt_number'] ?? null
        ]);
        
        // Create invoice for tracking
        $sale = $this->getById($installment['sale_id']);
        $invoiceModel = new Invoice();
        $invoiceModel->createInvoice([
            'tenant_id' => $sale['buyer_id'],
            'type' => 'Sale Installment',
            'description' => $installment['milestone_name'] ?? 'Installment Payment',
            'amount' => $installment['amount'],
            'total_amount' => $installment['amount'],
            'balance' => 0.00,
            'due_date' => $installment['due_date'],
            'status' => 'paid'
        ]);
        
        return $paymentId;
    }
}
?>
