<?php
/**
 * ============================================================================
 * classes/Group.php - Group Management Class
 * Compatible with existing Database class
 * ============================================================================
 */

namespace App;

use PDO;
use Exception;

class Group {
    private $db;
    
    public function __construct($db) {
        $this->db = $db;
    }
    
    /**
     * Get group details with user membership status
     */
    public function getDetails($groupId, $userId) {
        $sql = "SELECT g.*,
                u.full_name as creator_name,
                (SELECT COUNT(*) FROM group_members WHERE group_id = g.id AND status = 'active') as member_count,
                (SELECT COUNT(*) FROM group_posts WHERE group_id = g.id) as post_count,
                gm.role,
                gm.status as membership_status
                FROM groups g
                LEFT JOIN users u ON g.created_by = u.id
                LEFT JOIN group_members gm ON g.id = gm.group_id AND gm.user_id = ?
                WHERE g.id = ?";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$userId, $groupId]);
        return $stmt->fetch(PDO::FETCH_ASSOC);
    }
    
    /**
     * Get group members
     */
    public function getMembers($groupId, $status = 'active') {
        $sql = "SELECT gm.*, u.full_name, u.profile_picture, u.district_id, u.email
                FROM group_members gm
                JOIN users u ON gm.user_id = u.id
                WHERE gm.group_id = ? AND gm.status = ?
                ORDER BY 
                    CASE gm.role 
                        WHEN 'admin' THEN 1
                        WHEN 'moderator' THEN 2
                        ELSE 3
                    END,
                    gm.joined_at ASC";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$groupId, $status]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    
    /**
     * Get group posts with comments and likes
     */
    public function getPosts($groupId, $limit = 50) {
        $sql = "SELECT gp.*, 
                u.full_name, u.profile_picture,
                (SELECT COUNT(*) FROM group_post_likes WHERE post_id = gp.id) as likes_count,
                (SELECT COUNT(*) FROM group_post_comments WHERE post_id = gp.id) as comments_count
                FROM group_posts gp
                JOIN users u ON gp.user_id = u.id
                WHERE gp.group_id = ?
                ORDER BY gp.is_pinned DESC, gp.created_at DESC
                LIMIT ?";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$groupId, $limit]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    
    /**
     * Get post comments
     */
    public function getPostComments($postId) {
        $sql = "SELECT gpc.*, u.full_name, u.profile_picture
                FROM group_post_comments gpc
                JOIN users u ON gpc.user_id = u.id
                WHERE gpc.post_id = ?
                ORDER BY gpc.created_at ASC";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$postId]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    
    /**
     * Get pending join requests
     */
    public function getPendingRequests($groupId) {
        $sql = "SELECT gm.*, u.full_name, u.profile_picture, u.district_id, u.email
                FROM group_members gm
                JOIN users u ON gm.user_id = u.id
                WHERE gm.group_id = ? AND gm.status = 'pending'
                ORDER BY gm.joined_at ASC";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$groupId]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    
    /**
     * Join a group
     */
    public function join($groupId, $userId) {
        try {
            // Get group privacy setting
            $sql = "SELECT privacy FROM groups WHERE id = ?";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$groupId]);
            $group = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if (!$group) {
                return ['success' => false, 'message' => 'Group not found'];
            }
            
            // Check if already a member
            $sql = "SELECT id, status FROM group_members WHERE group_id = ? AND user_id = ?";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$groupId, $userId]);
            $existing = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if ($existing) {
                if ($existing['status'] === 'active') {
                    return ['success' => false, 'message' => 'You are already a member'];
                } elseif ($existing['status'] === 'pending') {
                    return ['success' => false, 'message' => 'Your request is pending approval'];
                }
            }
            
            // Determine status based on privacy
            $status = ($group['privacy'] === 'public') ? 'active' : 'pending';
            
            // Add member
            $sql = "INSERT INTO group_members (group_id, user_id, role, status, joined_at)
                    VALUES (?, ?, 'member', ?, NOW())
                    ON DUPLICATE KEY UPDATE status = ?, joined_at = NOW()";
            
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$groupId, $userId, $status, $status]);
            
            $message = ($status === 'active') 
                ? 'Successfully joined the group!' 
                : 'Join request sent! Waiting for admin approval.';
            
            return ['success' => true, 'message' => $message, 'status' => $status];
            
        } catch (Exception $e) {
            error_log("Join group error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Failed to join group'];
        }
    }
    
    /**
     * Leave a group
     */
    public function leave($groupId, $userId) {
        try {
            // Check if user is the last admin
            $sql = "SELECT COUNT(*) as admin_count FROM group_members 
                    WHERE group_id = ? AND role = 'admin' AND status = 'active'";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$groupId]);
            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            
            $sql2 = "SELECT role FROM group_members WHERE group_id = ? AND user_id = ?";
            $stmt2 = $this->db->prepare($sql2);
            $stmt2->execute([$groupId, $userId]);
            $member = $stmt2->fetch(PDO::FETCH_ASSOC);
            
            if ($member && $member['role'] === 'admin' && $result['admin_count'] <= 1) {
                return ['success' => false, 'message' => 'You are the last admin. Please assign another admin before leaving.'];
            }
            
            // Remove member
            $sql = "DELETE FROM group_members WHERE group_id = ? AND user_id = ?";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$groupId, $userId]);
            
            return ['success' => true, 'message' => 'You have left the group'];
            
        } catch (Exception $e) {
            error_log("Leave group error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Failed to leave group'];
        }
    }
    
    /**
     * Approve member (admin only)
     */
    public function approveMember($groupId, $memberId, $adminId) {
        try {
            if (!$this->isAdmin($groupId, $adminId)) {
                return ['success' => false, 'message' => 'Unauthorized'];
            }
            
            $sql = "UPDATE group_members SET status = 'active' 
                    WHERE group_id = ? AND user_id = ? AND status = 'pending'";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$groupId, $memberId]);
            
            if ($stmt->rowCount() > 0) {
                return ['success' => true, 'message' => 'Member approved'];
            } else {
                return ['success' => false, 'message' => 'No pending request found'];
            }
            
        } catch (Exception $e) {
            error_log("Approve member error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Failed to approve member'];
        }
    }
    
    /**
     * Reject member (admin only)
     */
    public function rejectMember($groupId, $memberId, $adminId) {
        try {
            if (!$this->isAdmin($groupId, $adminId)) {
                return ['success' => false, 'message' => 'Unauthorized'];
            }
            
            $sql = "DELETE FROM group_members 
                    WHERE group_id = ? AND user_id = ? AND status = 'pending'";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$groupId, $memberId]);
            
            if ($stmt->rowCount() > 0) {
                return ['success' => true, 'message' => 'Request rejected'];
            } else {
                return ['success' => false, 'message' => 'No pending request found'];
            }
            
        } catch (Exception $e) {
            error_log("Reject member error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Failed to reject member'];
        }
    }
    
    /**
     * Remove member (admin only)
     */
    public function removeMember($groupId, $memberId, $adminId) {
        try {
            if (!$this->isAdmin($groupId, $adminId)) {
                return ['success' => false, 'message' => 'Unauthorized'];
            }
            
            // Can't remove another admin
            $sql = "SELECT role FROM group_members WHERE group_id = ? AND user_id = ?";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$groupId, $memberId]);
            $member = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if ($member && $member['role'] === 'admin') {
                return ['success' => false, 'message' => 'Cannot remove an admin'];
            }
            
            $sql = "DELETE FROM group_members WHERE group_id = ? AND user_id = ?";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$groupId, $memberId]);
            
            return ['success' => true, 'message' => 'Member removed'];
            
        } catch (Exception $e) {
            error_log("Remove member error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Failed to remove member'];
        }
    }
    
    /**
     * Add member (admin only)
     */
    public function addMember($groupId, $memberId, $adminId) {
        try {
            if (!$this->isAdmin($groupId, $adminId)) {
                return ['success' => false, 'message' => 'Unauthorized'];
            }
            
            $sql = "INSERT INTO group_members (group_id, user_id, role, status, joined_at)
                    VALUES (?, ?, 'member', 'active', NOW())
                    ON DUPLICATE KEY UPDATE status = 'active'";
            
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$groupId, $memberId]);
            
            return ['success' => true, 'message' => 'Member added'];
            
        } catch (Exception $e) {
            error_log("Add member error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Failed to add member'];
        }
    }
    
    /**
     * Update member role (admin only)
     */
    public function updateMemberRole($groupId, $memberId, $newRole, $adminId) {
        try {
            if (!$this->isAdmin($groupId, $adminId)) {
                return ['success' => false, 'message' => 'Unauthorized'];
            }
            
            $sql = "UPDATE group_members SET role = ? 
                    WHERE group_id = ? AND user_id = ? AND status = 'active'";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$newRole, $groupId, $memberId]);
            
            if ($stmt->rowCount() > 0) {
                return ['success' => true, 'message' => 'Role updated'];
            } else {
                return ['success' => false, 'message' => 'Member not found'];
            }
            
        } catch (Exception $e) {
            error_log("Update role error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Failed to update role'];
        }
    }
    
    /**
     * Create a post
     */
    public function createPost($groupId, $userId, $content, $mediaUrls = null) {
        try {
            if (!$this->isMember($groupId, $userId)) {
                return ['success' => false, 'message' => 'You must be a member to post'];
            }
            
            $mediaJson = $mediaUrls ? json_encode($mediaUrls) : null;
            
            $sql = "INSERT INTO group_posts (group_id, user_id, content, media_urls, created_at)
                    VALUES (?, ?, ?, ?, NOW())";
            
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$groupId, $userId, $content, $mediaJson]);
            
            return ['success' => true, 'message' => 'Post created', 'post_id' => $this->db->lastInsertId()];
            
        } catch (Exception $e) {
            error_log("Create post error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Failed to create post'];
        }
    }
    
    /**
     * Delete a post
     */
    public function deletePost($postId, $userId, $groupId) {
        try {
            // Check if user owns the post or is admin
            $sql = "SELECT user_id FROM group_posts WHERE id = ?";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$postId]);
            $post = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if (!$post) {
                return ['success' => false, 'message' => 'Post not found'];
            }
            
            $isOwner = ($post['user_id'] == $userId);
            $isAdmin = $this->isAdmin($groupId, $userId);
            
            if (!$isOwner && !$isAdmin) {
                return ['success' => false, 'message' => 'Unauthorized'];
            }
            
            $sql = "DELETE FROM group_posts WHERE id = ?";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$postId]);
            
            return ['success' => true, 'message' => 'Post deleted'];
            
        } catch (Exception $e) {
            error_log("Delete post error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Failed to delete post'];
        }
    }
    
    /**
     * Like/unlike a post
     */
    public function likePost($postId, $userId) {
        try {
            // Check if already liked
            $sql = "SELECT id FROM group_post_likes WHERE post_id = ? AND user_id = ?";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$postId, $userId]);
            
            if ($stmt->fetch()) {
                // Unlike
                $sql = "DELETE FROM group_post_likes WHERE post_id = ? AND user_id = ?";
                $stmt = $this->db->prepare($sql);
                $stmt->execute([$postId, $userId]);
                return ['success' => true, 'action' => 'unliked'];
            } else {
                // Like
                $sql = "INSERT INTO group_post_likes (post_id, user_id, created_at) VALUES (?, ?, NOW())";
                $stmt = $this->db->prepare($sql);
                $stmt->execute([$postId, $userId]);
                return ['success' => true, 'action' => 'liked'];
            }
            
        } catch (Exception $e) {
            error_log("Like post error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Failed to like post'];
        }
    }
    
    /**
     * Comment on a post
     */
    public function commentOnPost($postId, $userId, $content) {
        try {
            $sql = "INSERT INTO group_post_comments (post_id, user_id, content, created_at)
                    VALUES (?, ?, ?, NOW())";
            
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$postId, $userId, $content]);
            
            return ['success' => true, 'message' => 'Comment added', 'comment_id' => $this->db->lastInsertId()];
            
        } catch (Exception $e) {
            error_log("Comment error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Failed to add comment'];
        }
    }
    
    /**
     * Get suggested groups
     */
    public function getSuggestedGroups($userId, $limit = 12) {
        $sql = "SELECT g.*,
                (SELECT COUNT(*) FROM group_members WHERE group_id = g.id AND status = 'active') as member_count,
                (SELECT COUNT(*) FROM group_posts WHERE group_id = g.id) as post_count,
                u.full_name as creator_name
                FROM groups g
                LEFT JOIN users u ON g.created_by = u.id
                WHERE g.privacy IN ('public', 'private')
                AND g.id NOT IN (
                    SELECT group_id FROM group_members WHERE user_id = ? AND status = 'active'
                )
                ORDER BY member_count DESC, g.created_at DESC
                LIMIT ?";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$userId, $limit]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    
    /**
     * Pin/unpin a post (admin only)
     */
    public function togglePinPost($postId, $groupId, $userId) {
        try {
            if (!$this->isAdmin($groupId, $userId)) {
                return ['success' => false, 'message' => 'Unauthorized'];
            }
            
            $sql = "UPDATE group_posts SET is_pinned = NOT is_pinned WHERE id = ? AND group_id = ?";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$postId, $groupId]);
            
            return ['success' => true, 'message' => 'Post pin status updated'];
            
        } catch (Exception $e) {
            error_log("Toggle pin error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Failed to update pin status'];
        }
    }
    
    /**
     * Check if user is a member
     */
    private function isMember($groupId, $userId) {
        $sql = "SELECT id FROM group_members 
                WHERE group_id = ? AND user_id = ? AND status = 'active'";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$groupId, $userId]);
        return $stmt->fetch() !== false;
    }
    
    /**
     * Check if user is admin or moderator
     */
    private function isAdmin($groupId, $userId) {
        $sql = "SELECT role FROM group_members 
                WHERE group_id = ? AND user_id = ? AND status = 'active'";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$groupId, $userId]);
        $member = $stmt->fetch(PDO::FETCH_ASSOC);
        
        return $member && in_array($member['role'], ['admin', 'moderator']);
    }
}