<?php
/**
 * ============================================================================
 * classes/Product.php - Product Management Class (FIXED VERSION)
 * ============================================================================
 */

namespace App;

use PDO;
use PDOException;

class Product {
    private $db;
    private $table = 'products';
    
    public $id;
    public $seller_id;
    public $enterprise_id;
    public $product_name;
    public $category;
    public $description;
    public $quantity;
    public $unit;
    public $price_per_unit;
    public $location;
    public $images;
    public $status;
    public $views;
    
    public function __construct($db) {
        $this->db = $db;
    }
    
    /**
     * Create new product
     */
    public function create($data) {
        try {
            // Validate required fields
            if (empty($data['product_name']) || empty($data['category']) || 
                empty($data['quantity']) || empty($data['price_per_unit'])) {
                return ['success' => false, 'message' => 'All required fields must be filled'];
            }
            
            // Handle image upload - ensure it's always an array
            $images = [];
            if (isset($data['images']) && !empty($data['images'])) {
                if (is_array($data['images'])) {
                    $images = $data['images'];
                } elseif (is_string($data['images'])) {
                    // If it's a single string, wrap it in an array
                    $images = [$data['images']];
                }
            }
            
            $sql = "INSERT INTO {$this->table} 
                    (seller_id, enterprise_id, product_name, category, description, 
                     quantity, unit, price_per_unit, location, images, status) 
                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
            
            $stmt = $this->db->prepare($sql);
            $result = $stmt->execute([
                $data['seller_id'],
                $data['enterprise_id'] ?? null,
                sanitize($data['product_name']),
                $data['category'],
                sanitize($data['description'] ?? ''),
                $data['quantity'],
                sanitize($data['unit']),
                $data['price_per_unit'],
                sanitize($data['location'] ?? ''),
                json_encode($images), // Always store as JSON
                'available'
            ]);
            
            if ($result) {
                $productId = $this->db->lastInsertId();
                
                // Log activity
                logActivity($data['seller_id'], 'add_product', "Added product: {$data['product_name']}");
                
                return [
                    'success' => true,
                    'message' => 'Product added successfully',
                    'product_id' => $productId
                ];
            }
            
            return ['success' => false, 'message' => 'Failed to add product'];
            
        } catch (PDOException $e) {
            error_log("Product creation error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Database error occurred'];
        }
    }
    
    /**
     * Get product by ID
     */
    public function getById($id) {
        $sql = "SELECT p.*, 
                u.full_name as seller_name, 
                u.phone_number as seller_phone,
                u.profile_picture as seller_avatar,
                (SELECT AVG(rating) FROM reviews WHERE reviewed_user_id = p.seller_id) as seller_rating,
                (SELECT COUNT(*) FROM reviews WHERE reviewed_user_id = p.seller_id) as seller_reviews
                FROM {$this->table} p
                LEFT JOIN users u ON p.seller_id = u.id
                WHERE p.id = ?";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$id]);
        $product = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($product) {
            // Decode images JSON - with fallback for non-JSON strings
            $product['images'] = $this->decodeImages($product['images']);
            
            // Increment views
            $this->incrementViews($id);
        }
        
        return $product;
    }
    
    /**
     * Decode images field - handles both JSON and plain strings
     */
    private function decodeImages($imagesData) {
        if (empty($imagesData)) {
            return [];
        }
        
        // Try to decode as JSON first
        $decoded = json_decode($imagesData, true);
        
        // If json_decode succeeded and returned an array, use it
        if (is_array($decoded)) {
            return $decoded;
        }
        
        // Otherwise, treat it as a single image path
        // Wrap it in an array
        return [$imagesData];
    }
    
    /**
     * Get all products with filters
     */
    public function getAll($filters = []) {
        $sql = "SELECT p.*, 
                u.full_name as seller_name,
                u.phone_number as seller_phone,
                u.profile_picture as seller_avatar,
                (SELECT AVG(rating) FROM reviews WHERE reviewed_user_id = p.seller_id) as seller_rating
                FROM {$this->table} p
                LEFT JOIN users u ON p.seller_id = u.id
                WHERE 1=1";
        
        $params = [];
        
        // Apply filters
        if (!empty($filters['category'])) {
            $sql .= " AND p.category = ?";
            $params[] = $filters['category'];
        }
        
        if (!empty($filters['status'])) {
            $sql .= " AND p.status = ?";
            $params[] = $filters['status'];
        } else {
            $sql .= " AND p.status = 'available'";
        }
        
        if (!empty($filters['seller_id'])) {
            $sql .= " AND p.seller_id = ?";
            $params[] = $filters['seller_id'];
        }
        
        if (!empty($filters['search'])) {
            $sql .= " AND (p.product_name LIKE ? OR p.description LIKE ?)";
            $searchTerm = '%' . $filters['search'] . '%';
            $params[] = $searchTerm;
            $params[] = $searchTerm;
        }
        
        if (!empty($filters['min_price'])) {
            $sql .= " AND p.price_per_unit >= ?";
            $params[] = $filters['min_price'];
        }
        
        if (!empty($filters['max_price'])) {
            $sql .= " AND p.price_per_unit <= ?";
            $params[] = $filters['max_price'];
        }
        
        if (!empty($filters['location'])) {
            $sql .= " AND p.location LIKE ?";
            $params[] = '%' . $filters['location'] . '%';
        }
        
        // Sorting
        $orderBy = $filters['sort'] ?? 'created_at';
        $orderDir = $filters['order'] ?? 'DESC';
        $sql .= " ORDER BY p.{$orderBy} {$orderDir}";
        
        // Pagination
        $page = $filters['page'] ?? 1;
        $perPage = $filters['per_page'] ?? PRODUCTS_PER_PAGE;
        $offset = ($page - 1) * $perPage;
        $sql .= " LIMIT ? OFFSET ?";
        $params[] = (int)$perPage;
        $params[] = (int)$offset;
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        $products = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        // Decode images for each product
        foreach ($products as &$product) {
            $product['images'] = $this->decodeImages($product['images']);
        }
        
        return $products;
    }
    
    /**
     * Get total products count
     */
    public function getCount($filters = []) {
        $sql = "SELECT COUNT(*) as total FROM {$this->table} WHERE 1=1";
        $params = [];
        
        if (!empty($filters['category'])) {
            $sql .= " AND category = ?";
            $params[] = $filters['category'];
        }
        
        if (!empty($filters['status'])) {
            $sql .= " AND status = ?";
            $params[] = $filters['status'];
        } else {
            $sql .= " AND status = 'available'";
        }
        
        if (!empty($filters['seller_id'])) {
            $sql .= " AND seller_id = ?";
            $params[] = $filters['seller_id'];
        }
        
        if (!empty($filters['search'])) {
            $sql .= " AND (product_name LIKE ? OR description LIKE ?)";
            $searchTerm = '%' . $filters['search'] . '%';
            $params[] = $searchTerm;
            $params[] = $searchTerm;
        }
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        
        return $result['total'];
    }
    
    /**
     * Update product
     */
    public function update($id, $data) {
        try {
            // Get current product
            $current = $this->getById($id);
            if (!$current) {
                return ['success' => false, 'message' => 'Product not found'];
            }
            
            // Handle images update
            $images = $current['images'];
            if (isset($data['images'])) {
                if (is_array($data['images'])) {
                    $images = $data['images'];
                } elseif (is_string($data['images'])) {
                    $images = [$data['images']];
                }
            }
            
            $sql = "UPDATE {$this->table} SET 
                    product_name = ?,
                    category = ?,
                    description = ?,
                    quantity = ?,
                    unit = ?,
                    price_per_unit = ?,
                    location = ?,
                    images = ?,
                    updated_at = CURRENT_TIMESTAMP
                    WHERE id = ?";
            
            $stmt = $this->db->prepare($sql);
            $result = $stmt->execute([
                sanitize($data['product_name']),
                $data['category'],
                sanitize($data['description'] ?? ''),
                $data['quantity'],
                sanitize($data['unit']),
                $data['price_per_unit'],
                sanitize($data['location'] ?? ''),
                json_encode($images),
                $id
            ]);
            
            if ($result) {
                logActivity($current['seller_id'], 'update_product', "Updated product: {$data['product_name']}");
                return ['success' => true, 'message' => 'Product updated successfully'];
            }
            
            return ['success' => false, 'message' => 'Failed to update product'];
            
        } catch (PDOException $e) {
            error_log("Product update error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Database error occurred'];
        }
    }
    
    /**
     * Update product status
     */
    public function updateStatus($id, $status) {
        $validStatuses = ['available', 'sold', 'reserved', 'expired'];
        
        if (!in_array($status, $validStatuses)) {
            return ['success' => false, 'message' => 'Invalid status'];
        }
        
        $sql = "UPDATE {$this->table} SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?";
        $stmt = $this->db->prepare($sql);
        $result = $stmt->execute([$status, $id]);
        
        if ($result) {
            return ['success' => true, 'message' => 'Status updated successfully'];
        }
        
        return ['success' => false, 'message' => 'Failed to update status'];
    }
    
    /**
     * Delete product
     */
    public function delete($id) {
        try {
            // Get product details first
            $product = $this->getById($id);
            if (!$product) {
                return ['success' => false, 'message' => 'Product not found'];
            }
            
            // Delete product images
            if (!empty($product['images'])) {
                foreach ($product['images'] as $image) {
                    deleteFile($image);
                }
            }
            
            $sql = "DELETE FROM {$this->table} WHERE id = ?";
            $stmt = $this->db->prepare($sql);
            $result = $stmt->execute([$id]);
            
            if ($result) {
                logActivity($product['seller_id'], 'delete_product', "Deleted product: {$product['product_name']}");
                return ['success' => true, 'message' => 'Product deleted successfully'];
            }
            
            return ['success' => false, 'message' => 'Failed to delete product'];
            
        } catch (PDOException $e) {
            error_log("Product deletion error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Database error occurred'];
        }
    }
    
    /**
     * Increment product views
     */
    private function incrementViews($id) {
        $sql = "UPDATE {$this->table} SET views = views + 1 WHERE id = ?";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$id]);
    }
    
    /**
     * Get related products
     */
    public function getRelated($productId, $category, $limit = 4) {
        $sql = "SELECT p.*, u.full_name as seller_name
                FROM {$this->table} p
                LEFT JOIN users u ON p.seller_id = u.id
                WHERE p.category = ? AND p.id != ? AND p.status = 'available'
                ORDER BY RAND()
                LIMIT ?";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$category, $productId, $limit]);
        $products = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        foreach ($products as &$product) {
            $product['images'] = $this->decodeImages($product['images']);
        }
        
        return $products;
    }
    
    /**
     * Get seller's products
     */
    public function getByseller($sellerId, $limit = null) {
        $sql = "SELECT * FROM {$this->table} 
                WHERE seller_id = ? 
                ORDER BY created_at DESC";
        
        if ($limit) {
            $sql .= " LIMIT ?";
        }
        
        $stmt = $this->db->prepare($sql);
        
        if ($limit) {
            $stmt->execute([$sellerId, $limit]);
        } else {
            $stmt->execute([$sellerId]);
        }
        
        $products = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        foreach ($products as &$product) {
            $product['images'] = $this->decodeImages($product['images']);
        }
        
        return $products;
    }
    
    /**
     * Search products
     */
    public function search($query, $filters = []) {
        $filters['search'] = $query;
        return $this->getAll($filters);
    }
    
    /**
     * Get featured products
     */
    public function getFeatured($limit = 6) {
        $sql = "SELECT p.*, u.full_name as seller_name,
                (SELECT AVG(rating) FROM reviews WHERE reviewed_user_id = p.seller_id) as seller_rating
                FROM {$this->table} p
                LEFT JOIN users u ON p.seller_id = u.id
                WHERE p.status = 'available'
                ORDER BY p.views DESC, p.created_at DESC
                LIMIT ?";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$limit]);
        $products = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        foreach ($products as &$product) {
            $product['images'] = $this->decodeImages($product['images']);
        }
        
        return $products;
    }
    
    /**
     * Get products by category
     */
    public function getByCategory($category, $limit = null) {
        $sql = "SELECT p.*, u.full_name as seller_name
                FROM {$this->table} p
                LEFT JOIN users u ON p.seller_id = u.id
                WHERE p.category = ? AND p.status = 'available'
                ORDER BY p.created_at DESC";
        
        if ($limit) {
            $sql .= " LIMIT ?";
        }
        
        $stmt = $this->db->prepare($sql);
        
        if ($limit) {
            $stmt->execute([$category, $limit]);
        } else {
            $stmt->execute([$category]);
        }
        
        $products = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        foreach ($products as &$product) {
            $product['images'] = $this->decodeImages($product['images']);
        }
        
        return $products;
    }
}