<?php
/**
 * Transaction Model
 * Handles all transaction database operations
 * 
 * @package RashwansBarber
 * @version 1.0
 */

class Transaction {
    
    private $db;
    
    public function __construct() {
        $this->db = Database::getInstance();
    }
    
    /**
     * Get all transactions with filters
     * 
     * @param int $locationId Location filter (null for all)
     * @param string $dateFrom Start date
     * @param string $dateTo End date
     * @param string $search Search term
     * @return array
     */
    public function getAllTransactions($locationId = null, $dateFrom = null, $dateTo = null, $search = null) {
        $sql = "SELECT 
                    t.transaction_id,
                    t.receipt_number,
                    t.transaction_date,
                    t.subtotal,
                    t.vat_amount,
                    t.total_amount,
                    t.status,
                    b.full_name as barber_name,
                    b.employee_id as barber_employee_id,
                    l.location_name,
                    u.full_name as cashier_name,
                    p.payment_method
                FROM transactions t
                JOIN barbers b ON t.barber_id = b.barber_id
                JOIN locations l ON t.location_id = l.location_id
                JOIN users u ON t.cashier_id = u.user_id
                LEFT JOIN payments p ON t.transaction_id = p.transaction_id
                WHERE 1=1";
        
        $params = [];
        
        if ($locationId) {
            $sql .= " AND t.location_id = ?";
            $params[] = $locationId;
        }
        
        if ($dateFrom) {
            $sql .= " AND DATE(t.transaction_date) >= ?";
            $params[] = $dateFrom;
        }
        
        if ($dateTo) {
            $sql .= " AND DATE(t.transaction_date) <= ?";
            $params[] = $dateTo;
        }
        
        if ($search) {
            $sql .= " AND (t.receipt_number LIKE ? OR b.full_name LIKE ? OR u.full_name LIKE ?)";
            $searchTerm = "%{$search}%";
            $params[] = $searchTerm;
            $params[] = $searchTerm;
            $params[] = $searchTerm;
        }
        
        $sql .= " ORDER BY t.transaction_date DESC LIMIT 100";
        
        return $this->db->fetchAll($sql, $params);
    }
    
    /**
     * Get transaction by ID
     * 
     * @param int $transactionId Transaction ID
     * @return array|false
     */
    public function getTransactionById($transactionId) {
        $sql = "SELECT 
                    t.*,
                    b.full_name as barber_name,
                    b.employee_id as barber_employee_id,
                    b.commission_rate as barber_commission_rate,
                    l.location_name,
                    l.address as location_address,
                    l.contact_number as location_phone,
                    u.full_name as cashier_name,
                    p.payment_method,
                    p.amount_tendered,
                    p.change_given,
                    p.card_type,
                    p.card_last_four
                FROM transactions t
                JOIN barbers b ON t.barber_id = b.barber_id
                JOIN locations l ON t.location_id = l.location_id
                JOIN users u ON t.cashier_id = u.user_id
                LEFT JOIN payments p ON t.transaction_id = p.transaction_id
                WHERE t.transaction_id = ?";
        
        return $this->db->fetchOne($sql, [$transactionId]);
    }
    
    /**
     * Get transaction by receipt number
     * 
     * @param string $receiptNumber Receipt number
     * @return array|false
     */
    public function getTransactionByReceipt($receiptNumber) {
        $sql = "SELECT 
                    t.*,
                    b.full_name as barber_name,
                    l.location_name,
                    u.full_name as cashier_name
                FROM transactions t
                JOIN barbers b ON t.barber_id = b.barber_id
                JOIN locations l ON t.location_id = l.location_id
                JOIN users u ON t.cashier_id = u.user_id
                WHERE t.receipt_number = ?";
        
        return $this->db->fetchOne($sql, [$receiptNumber]);
    }
    
    /**
     * Get transaction items
     * 
     * @param int $transactionId Transaction ID
     * @return array
     */
    public function getTransactionItems($transactionId) {
        $sql = "SELECT 
                    ti.*,
                    s.service_category
                FROM transaction_items ti
                LEFT JOIN services s ON ti.service_id = s.service_id
                WHERE ti.transaction_id = ?
                ORDER BY ti.item_id";
        
        return $this->db->fetchAll($sql, [$transactionId]);
    }
    
    /**
     * Void a transaction
     * 
     * @param int $transactionId Transaction ID
     * @param string $reason Void reason
     * @param int $userId User who voided
     * @return bool
     */
    public function voidTransaction($transactionId, $reason, $userId) {
        try {
            $this->db->beginTransaction();
            
            $sql = "UPDATE transactions 
                    SET status = 'void', 
                        void_reason = ?, 
                        void_by = ?, 
                        void_date = NOW() 
                    WHERE transaction_id = ? AND status = 'completed'";
            
            $result = $this->db->update($sql, [$reason, $userId, $transactionId]);
            
            $this->db->commit();
            
            return $result > 0;
        } catch (Exception $e) {
            $this->db->rollback();
            error_log("Void transaction error: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Get daily summary
     * 
     * @param int $locationId Location ID
     * @param string $date Date (Y-m-d format)
     * @return array
     */
    public function getDailySummary($locationId, $date) {
        $sql = "SELECT 
                    COUNT(t.transaction_id) as transaction_count,
                    COALESCE(SUM(t.subtotal), 0) as total_subtotal,
                    COALESCE(SUM(t.vat_amount), 0) as total_vat,
                    COALESCE(SUM(t.total_amount), 0) as total_sales,
                    COALESCE(SUM(CASE WHEN p.payment_method = 'cash' THEN p.amount ELSE 0 END), 0) as cash_sales,
                    COALESCE(SUM(CASE WHEN p.payment_method = 'card' THEN p.amount ELSE 0 END), 0) as card_sales,
                    COALESCE(SUM(CASE WHEN p.payment_method = 'mobile_payment' THEN p.amount ELSE 0 END), 0) as mobile_sales,
                    COALESCE(SUM(ti.commission_amount), 0) as total_commission
                FROM transactions t
                LEFT JOIN payments p ON t.transaction_id = p.transaction_id
                LEFT JOIN transaction_items ti ON t.transaction_id = ti.transaction_id
                WHERE t.location_id = ? 
                AND DATE(t.transaction_date) = ?
                AND t.status = 'completed'";
        
        return $this->db->fetchOne($sql, [$locationId, $date]);
    }
    
    /**
     * Get recent transactions
     * 
     * @param int $locationId Location ID
     * @param int $limit Limit
     * @return array
     */
    public function getRecentTransactions($locationId, $limit = 10) {
        $sql = "SELECT 
                    t.transaction_id,
                    t.receipt_number,
                    t.transaction_date,
                    t.total_amount,
                    t.status,
                    b.full_name as barber_name,
                    u.full_name as cashier_name
                FROM transactions t
                JOIN barbers b ON t.barber_id = b.barber_id
                JOIN users u ON t.cashier_id = u.user_id
                WHERE t.location_id = ?
                ORDER BY t.transaction_date DESC
                LIMIT ?";
        
        return $this->db->fetchAll($sql, [$locationId, $limit]);
    }
    
    /**
     * Get transactions by barber
     * 
     * @param int $barberId Barber ID
     * @param string $dateFrom Start date
     * @param string $dateTo End date
     * @return array
     */
    public function getTransactionsByBarber($barberId, $dateFrom, $dateTo) {
        $sql = "SELECT 
                    t.*,
                    l.location_name,
                    u.full_name as cashier_name
                FROM transactions t
                JOIN locations l ON t.location_id = l.location_id
                JOIN users u ON t.cashier_id = u.user_id
                WHERE t.barber_id = ?
                AND DATE(t.transaction_date) BETWEEN ? AND ?
                AND t.status = 'completed'
                ORDER BY t.transaction_date DESC";
        
        return $this->db->fetchAll($sql, [$barberId, $dateFrom, $dateTo]);
    }
    
    /**
     * Get transaction count
     * 
     * @param int $locationId Location ID
     * @param string $dateFrom Start date
     * @param string $dateTo End date
     * @return int
     */
    public function getTransactionCount($locationId = null, $dateFrom = null, $dateTo = null) {
        $sql = "SELECT COUNT(*) as count FROM transactions WHERE 1=1";
        $params = [];
        
        if ($locationId) {
            $sql .= " AND location_id = ?";
            $params[] = $locationId;
        }
        
        if ($dateFrom) {
            $sql .= " AND DATE(transaction_date) >= ?";
            $params[] = $dateFrom;
        }
        
        if ($dateTo) {
            $sql .= " AND DATE(transaction_date) <= ?";
            $params[] = $dateTo;
        }
        
        $result = $this->db->fetchOne($sql, $params);
        return $result['count'];
    }
	
    	/**
 	* Get daily totals for cash-up
 	*/
	public function getDailyTotals($locationId, $date) {
    	try {
        	$db = Database::getInstance()->getConnection();
        
        	$query = "SELECT 
                    	COUNT(DISTINCT t.transaction_id) as transaction_count,
                    	SUM(t.total_amount) as total_sales,
                    	SUM(t.subtotal) as subtotal,
                    	SUM(t.vat_amount) as vat_amount,
                    	COUNT(DISTINCT CASE WHEN p.payment_method = 'cash' THEN t.transaction_id END) as cash_count,
                    	COUNT(DISTINCT CASE WHEN p.payment_method = 'card' THEN t.transaction_id END) as card_count,
                    	COUNT(DISTINCT CASE WHEN p.payment_method = 'mobile_payment' THEN t.transaction_id END) as mobile_count
                  	FROM transactions t
                  	LEFT JOIN payments p ON t.transaction_id = p.transaction_id
                  	WHERE t.location_id = :location_id
                  	AND DATE(t.transaction_date) = :date
                  	AND t.status = 'completed'";
        
        	$stmt = $db->prepare($query);
        	$stmt->bindParam(':location_id', $locationId, PDO::PARAM_INT);
        	$stmt->bindParam(':date', $date, PDO::PARAM_STR);
        	$stmt->execute();
        
        	return $stmt->fetch(PDO::FETCH_ASSOC);
        
    	} catch (PDOException $e) {
        	error_log("Transaction getDailyTotals Error: " . $e->getMessage());
        	return false;
    	}
	}


    /**
     * Get payment method breakdown for cash-up
     */
    /**
   * Get payment method breakdown for cash-up
   */
	public function getPaymentBreakdown($locationId, $date) {
    	try {
        	$db = Database::getInstance()->getConnection();

        	$query = "SELECT
                	 SUM(CASE WHEN p.payment_method = 'cash' THEN p.amount ELSE 0 END) as cash,
                   	 SUM(CASE WHEN p.payment_method = 'card' THEN p.amount ELSE 0 END) as card,
                    	SUM(CASE WHEN p.payment_method = 'mobile_payment' THEN p.amount ELSE 0 END) as mobile_payment
                  	FROM payments p
                  	INNER JOIN transactions t ON p.transaction_id = t.transaction_id
                  	WHERE t.location_id = :location_id
                  	AND DATE(t.transaction_date) = :date
                  	AND t.status = 'completed'";

        	$stmt = $db->prepare($query);
        	$stmt->bindParam(':location_id', $locationId, PDO::PARAM_INT);
        	$stmt->bindParam(':date', $date, PDO::PARAM_STR);
        	$stmt->execute();

        	return $stmt->fetch(PDO::FETCH_ASSOC);

    	} catch (PDOException $e) {
        	error_log("Transaction getPaymentBreakdown Error: " . $e->getMessage());
        	return false;
    	}
   }
}	
?>
