<?php
/**
 * ============================================================================
 * classes/Friendship.php - Enhanced Friendship Management Class
 * ============================================================================
 * With proper profile picture path handling
 */

namespace App;

use PDO;
use PDOException;

class Friendship {
    private $db;
    private $table = 'friendships';
    
    public function __construct($db) {
        $this->db = $db;
    }
    
    /**
     * Get proper profile picture URL
     */
    private function getProfilePictureUrl($profilePicture) {
        if (!$profilePicture) {
            return 'assets/images/default-avatar.png';
        }
        
        // If it's already a full path, return as is
        if (strpos($profilePicture, 'assets/') === 0) {
            return $profilePicture;
        }
        
        // If it starts with ../, remove it
        if (strpos($profilePicture, '../') === 0) {
            return str_replace('../', '', $profilePicture);
        }
        
        // If it's just a filename, assume it's in assets/uploads/profiles/
        if (strpos($profilePicture, '/') === false) {
            return 'assets/uploads/profiles/' . $profilePicture;
        }
        
        return $profilePicture;
    }
    
    /**
     * Process user data to fix profile picture paths
     */
    private function processUserData($users) {
        if (empty($users)) {
            return [];
        }
        
        foreach ($users as &$user) {
            $user['profile_picture'] = $this->getProfilePictureUrl($user['profile_picture']);
        }
        
        return $users;
    }
    
    /**
     * Send friend request
     */
    public function sendRequest($userId, $friendId) {
        try {
            // Check if request already exists
            $sql = "SELECT * FROM {$this->table} 
                    WHERE (user_id = ? AND friend_id = ?) 
                    OR (user_id = ? AND friend_id = ?)";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$userId, $friendId, $friendId, $userId]);
            
            if ($stmt->fetch()) {
                return ['success' => false, 'message' => 'Friend request already exists'];
            }
            
            $sql = "INSERT INTO {$this->table} (user_id, friend_id) VALUES (?, ?)";
            $stmt = $this->db->prepare($sql);
            
            if ($stmt->execute([$userId, $friendId])) {
                // Create notification
                $sql = "INSERT INTO notifications (user_id, title, message, type, link)
                        VALUES (?, ?, ?, 'info', ?)";
                $stmt = $this->db->prepare($sql);
                $stmt->execute([
                    $friendId,
                    'New Friend Request',
                    'You have a new friend request',
                    '/friends/index.php'
                ]);
                
                return ['success' => true, 'message' => 'Friend request sent'];
            }
            
            return ['success' => false, 'message' => 'Failed to send request'];
            
        } catch (PDOException $e) {
            error_log("Friend request error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Database error occurred'];
        }
    }
    
    /**
     * Accept friend request
     */
    public function acceptRequest($friendshipId, $userId) {
        try {
            $sql = "UPDATE {$this->table} 
                    SET status = 'accepted', accepted_at = CURRENT_TIMESTAMP
                    WHERE id = ? AND friend_id = ? AND status = 'pending'";
            
            $stmt = $this->db->prepare($sql);
            
            if ($stmt->execute([$friendshipId, $userId])) {
                return ['success' => true, 'message' => 'Friend request accepted'];
            }
            
            return ['success' => false, 'message' => 'Failed to accept request'];
            
        } catch (PDOException $e) {
            return ['success' => false, 'message' => 'Database error occurred'];
        }
    }
    
    /**
     * Reject/delete friend request
     */
    public function deleteRequest($friendshipId, $userId) {
        $sql = "DELETE FROM {$this->table} 
                WHERE id = ? AND (user_id = ? OR friend_id = ?)";
        
        $stmt = $this->db->prepare($sql);
        
        if ($stmt->execute([$friendshipId, $userId, $userId])) {
            return ['success' => true, 'message' => 'Request deleted'];
        }
        
        return ['success' => false, 'message' => 'Failed to delete request'];
    }
    
    /**
     * Get user's friends with proper image paths
     */
    public function getFriends($userId) {
        $sql = "SELECT 
                CASE 
                    WHEN f.user_id = ? THEN f.friend_id
                    ELSE f.user_id
                END as friend_user_id,
                u.full_name, 
                COALESCE(
                    (SELECT photo_url FROM profile_photos 
                     WHERE user_id = u.id AND photo_type = 'profile' AND is_current = 1 
                     LIMIT 1),
                    u.profile_picture
                ) as profile_picture,
                u.user_type,
                d.district_name as district,
                s.subcounty_name as subcounty,
                f.accepted_at
                FROM {$this->table} f
                JOIN users u ON (
                    CASE 
                        WHEN f.user_id = ? THEN f.friend_id = u.id
                        ELSE f.user_id = u.id
                    END
                )
                LEFT JOIN districts d ON u.district_id = d.id
                LEFT JOIN subcounties s ON u.subcounty_id = s.id
                WHERE (f.user_id = ? OR f.friend_id = ?)
                AND f.status = 'accepted'
                ORDER BY f.accepted_at DESC";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$userId, $userId, $userId, $userId]);
        $friends = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        return $this->processUserData($friends);
    }
    
    /**
     * Get pending requests with proper image paths
     */
    public function getPendingRequests($userId) {
        $sql = "SELECT f.*, 
                u.full_name, 
                COALESCE(
                    (SELECT photo_url FROM profile_photos 
                     WHERE user_id = u.id AND photo_type = 'profile' AND is_current = 1 
                     LIMIT 1),
                    u.profile_picture
                ) as profile_picture,
                u.user_type,
                d.district_name as district,
                s.subcounty_name as subcounty
                FROM {$this->table} f
                JOIN users u ON f.user_id = u.id
                LEFT JOIN districts d ON u.district_id = d.id
                LEFT JOIN subcounties s ON u.subcounty_id = s.id
                WHERE f.friend_id = ? AND f.status = 'pending'
                ORDER BY f.requested_at DESC";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$userId]);
        $requests = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        return $this->processUserData($requests);
    }
    
    /**
     * Check friendship status
     */
    public function getStatus($userId, $friendId) {
        $sql = "SELECT status, 
                CASE WHEN user_id = ? THEN 'sent' ELSE 'received' END as direction
                FROM {$this->table}
                WHERE (user_id = ? AND friend_id = ?) 
                OR (user_id = ? AND friend_id = ?)";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$userId, $userId, $friendId, $friendId, $userId]);
        return $stmt->fetch(PDO::FETCH_ASSOC);
    }
    
    /**
     * Get friend suggestions with proper image paths
     */
    public function getFriendSuggestions($userId, $limit = 20) {
        $sql = "SELECT DISTINCT u.id, 
                u.full_name, 
                COALESCE(
                    (SELECT photo_url FROM profile_photos 
                     WHERE user_id = u.id AND photo_type = 'profile' AND is_current = 1 
                     LIMIT 1),
                    u.profile_picture
                ) as profile_picture,
                u.user_type,
                d.district_name as district,
                s.subcounty_name as subcounty,
                COUNT(DISTINCT mf.friend_id) as mutual_friends_count,
                CASE 
                    WHEN u.district_id = (SELECT district_id FROM users WHERE id = ?) THEN 3
                    WHEN u.subcounty_id = (SELECT subcounty_id FROM users WHERE id = ?) THEN 2
                    ELSE 1
                END as location_score
                FROM users u
                LEFT JOIN districts d ON u.district_id = d.id
                LEFT JOIN subcounties s ON u.subcounty_id = s.id
                LEFT JOIN {$this->table} mf ON (
                    (mf.user_id = u.id OR mf.friend_id = u.id) 
                    AND mf.status = 'accepted'
                    AND (mf.user_id IN (
                        SELECT CASE WHEN user_id = ? THEN friend_id ELSE user_id END 
                        FROM {$this->table} 
                        WHERE (user_id = ? OR friend_id = ?) AND status = 'accepted'
                    ) OR mf.friend_id IN (
                        SELECT CASE WHEN user_id = ? THEN friend_id ELSE user_id END 
                        FROM {$this->table} 
                        WHERE (user_id = ? OR friend_id = ?) AND status = 'accepted'
                    ))
                )
                WHERE u.id != ?
                AND u.is_active = 1
                AND u.id NOT IN (
                    SELECT CASE WHEN user_id = ? THEN friend_id ELSE user_id END
                    FROM {$this->table}
                    WHERE (user_id = ? OR friend_id = ?)
                )
                GROUP BY u.id
                ORDER BY mutual_friends_count DESC, location_score DESC, u.created_at DESC
                LIMIT ?";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([
            $userId, $userId, // location score
            $userId, $userId, $userId, // mutual friends check 1
            $userId, $userId, $userId, // mutual friends check 2
            $userId, // exclude self
            $userId, $userId, $userId, // exclude existing friends
            $limit
        ]);
        $suggestions = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        return $this->processUserData($suggestions);
    }
    
    /**
     * Get mutual friends with proper image paths
     */
    public function getMutualFriends($userId1, $userId2) {
        $sql = "SELECT DISTINCT u.id, u.full_name, 
                COALESCE(
                    (SELECT photo_url FROM profile_photos 
                     WHERE user_id = u.id AND photo_type = 'profile' AND is_current = 1 
                     LIMIT 1),
                    u.profile_picture
                ) as profile_picture
                FROM users u
                WHERE u.id IN (
                    SELECT CASE WHEN user_id = ? THEN friend_id ELSE user_id END
                    FROM {$this->table}
                    WHERE (user_id = ? OR friend_id = ?) AND status = 'accepted'
                )
                AND u.id IN (
                    SELECT CASE WHEN user_id = ? THEN friend_id ELSE user_id END
                    FROM {$this->table}
                    WHERE (user_id = ? OR friend_id = ?) AND status = 'accepted'
                )";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$userId1, $userId1, $userId1, $userId2, $userId2, $userId2]);
        $mutualFriends = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        return $this->processUserData($mutualFriends);
    }
    
    /**
     * Search all users with proper image paths
     */
    public function searchAllUsers($userId, $search = '', $userType = '', $district = '') {
        $sql = "SELECT u.id, 
                u.full_name, 
                COALESCE(
                    (SELECT photo_url FROM profile_photos 
                     WHERE user_id = u.id AND photo_type = 'profile' AND is_current = 1 
                     LIMIT 1),
                    u.profile_picture
                ) as profile_picture,
                u.user_type,
                d.district_name as district,
                s.subcounty_name as subcounty,
                (SELECT status FROM {$this->table} 
                 WHERE (user_id = ? AND friend_id = u.id) 
                 OR (user_id = u.id AND friend_id = ?)) as friendship_status
                FROM users u
                LEFT JOIN districts d ON u.district_id = d.id
                LEFT JOIN subcounties s ON u.subcounty_id = s.id
                WHERE u.id != ?
                AND u.is_active = 1";
        
        $params = [$userId, $userId, $userId];
        
        if ($search) {
            $sql .= " AND (u.full_name LIKE ? OR u.phone_number LIKE ?)";
            $params[] = "%{$search}%";
            $params[] = "%{$search}%";
        }
        
        if ($userType) {
            $sql .= " AND u.user_type = ?";
            $params[] = $userType;
        }
        
        if ($district) {
            $sql .= " AND d.district_name = ?";
            $params[] = $district;
        }
        
        $sql .= " ORDER BY u.full_name LIMIT 50";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        return $this->processUserData($users);
    }
    
    /**
     * Remove friend (unfriend)
     */
    public function removeFriend($userId, $friendId) {
        try {
            $sql = "DELETE FROM {$this->table} 
                    WHERE ((user_id = ? AND friend_id = ?) OR (user_id = ? AND friend_id = ?))
                    AND status = 'accepted'";
            
            $stmt = $this->db->prepare($sql);
            
            if ($stmt->execute([$userId, $friendId, $friendId, $userId])) {
                return ['success' => true, 'message' => 'Friend removed successfully'];
            }
            
            return ['success' => false, 'message' => 'Failed to remove friend'];
            
        } catch (PDOException $e) {
            error_log("Unfriend error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Database error occurred'];
        }
    }
    
    /**
     * Check if users are friends
     */
    public function areFriends($userId1, $userId2) {
        $sql = "SELECT COUNT(*) FROM {$this->table} 
                WHERE ((user_id = ? AND friend_id = ?) OR (user_id = ? AND friend_id = ?))
                AND status = 'accepted'";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$userId1, $userId2, $userId2, $userId1]);
        return $stmt->fetchColumn() > 0;
    }
    
    /**
     * Get user profile for friend view
     */
    public function getUserProfile($userId) {
        $sql = "SELECT u.*, up.*, 
                COALESCE(
                    (SELECT photo_url FROM profile_photos 
                     WHERE user_id = u.id AND photo_type = 'profile' AND is_current = 1 
                     LIMIT 1),
                    u.profile_picture
                ) as profile_picture,
                COALESCE(
                    (SELECT photo_url FROM profile_photos 
                     WHERE user_id = u.id AND photo_type = 'cover' AND is_current = 1 
                     LIMIT 1),
                    up.cover_photo
                ) as cover_photo,
                d.district_name, s.subcounty_name,
                (SELECT COUNT(*) FROM friendships 
                 WHERE (user_id = u.id OR friend_id = u.id) 
                 AND status = 'accepted') as friends_count,
                (SELECT COUNT(*) FROM posts WHERE user_id = u.id) as posts_count
                FROM users u
                LEFT JOIN user_profiles up ON u.id = up.user_id
                LEFT JOIN districts d ON u.district_id = d.id
                LEFT JOIN subcounties s ON u.subcounty_id = s.id
                WHERE u.id = ?";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$userId]);
        $profile = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($profile) {
            $profile['profile_picture'] = $this->getProfilePictureUrl($profile['profile_picture']);
            if ($profile['cover_photo']) {
                $profile['cover_photo'] = $this->getProfilePictureUrl($profile['cover_photo']);
            }
        }
        
        return $profile;
    }
}
?>