<?php

namespace App\Repositories;

use App\Models\Community;
use App\Models\User;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;

class CommunityRepository
{
    public function getAllCommunities(array $filters = [])
    {
        $query = Community::withCount(['members', 'posts'])
            ->with(['members' => function($query) {
                $query->limit(5);
            }]);

        // Apply filters
        if (isset($filters['search'])) {
            $query->where('name', 'like', "%{$filters['search']}%")
                  ->orWhere('description', 'like', "%{$filters['search']}%");
        }

        if (isset($filters['user_id'])) {
            $query->whereHas('members', function($q) use ($filters) {
                $q->where('user_id', $filters['user_id']);
            });
        }

        return $query->latest()->get();
    }

    public function getPaginatedCommunities(array $filters = []): LengthAwarePaginator
    {
        $query = Community::withCount(['members', 'posts'])
            ->with(['members' => function($query) {
                $query->limit(5);
            }]);

        // Apply filters
        if (isset($filters['search'])) {
            $query->where('name', 'like', "%{$filters['search']}%")
                  ->orWhere('description', 'like', "%{$filters['search']}%");
        }

        return $query->latest()->paginate(12);
    }

    public function findById(int $id): ?Community
    {
        return Community::withCount(['members', 'posts'])
            ->with(['members', 'posts.user'])
            ->find($id);
    }

    public function findBySlug(string $slug): ?Community
    {
        return Community::withCount(['members', 'posts'])
            ->with(['members', 'posts.user'])
            ->where('slug', $slug)
            ->first();
    }

    public function createCommunity(array $data): Community
    {
        return DB::transaction(function () use ($data) {
            $community = Community::create($data);

            // Add creator as admin member
            if (isset($data['created_by'])) {
                $community->addMember(User::find($data['created_by']), 'admin');
            }

            return $community;
        });
    }

    public function updateCommunity(Community $community, array $data): Community
    {
        return DB::transaction(function () use ($community, $data) {
            $community->update($data);
            return $community->fresh();
        });
    }

    public function deleteCommunity(Community $community): bool
    {
        return DB::transaction(function () use ($community) {
            // Detach all members first
            $community->members()->detach();
            
            // Detach all posts from this community
            $community->posts()->detach();

            return $community->delete();
        });
    }

    public function joinCommunity(Community $community, User $user, string $role = 'member'): void
    {
        DB::transaction(function () use ($community, $user, $role) {
            if (!$community->isMember($user)) {
                $community->addMember($user, $role);
            }
        });
    }

    public function leaveCommunity(Community $community, User $user): void
    {
        DB::transaction(function () use ($community, $user) {
            $community->removeMember($user);
        });
    }

    public function updateMemberRole(Community $community, User $user, string $role): void
    {
        DB::transaction(function () use ($community, $user, $role) {
            $community->updateMemberRole($user, $role);
        });
    }

    public function getUserCommunities(User $user, array $filters = [])
    {
        $query = $user->communities()
            ->withCount(['members', 'posts'])
            ->withPivot('role', 'joined_at');

        if (isset($filters['search'])) {
            $query->where('name', 'like', "%{$filters['search']}%");
        }

        return $query->orderBy('name')->get();
    }

    public function getCommunityMembers(Community $community, array $filters = []): LengthAwarePaginator
    {
        $query = $community->members()
            ->withPivot('role', 'joined_at')
            ->withCount(['rateMyPays', 'jobExperiences']);

        if (isset($filters['search'])) {
            $query->where('name', 'like', "%{$filters['search']}%")
                  ->orWhere('email', 'like', "%{$filters['search']}%");
        }

        if (isset($filters['role'])) {
            $query->wherePivot('role', $filters['role']);
        }

        return $query->orderBy('name')->paginate(20);
    }

    public function getCommunityPosts(Community $community, array $filters = []): LengthAwarePaginator
    {
        $query = $community->posts()
            ->with(['user', 'jobExperience', 'communities'])
            ->withCount(['likes', 'comments', 'ratings']);

        if (isset($filters['search'])) {
            $query->where('content', 'like', "%{$filters['search']}%")
                  ->orWhereHas('jobExperience', function($q) use ($filters) {
                      $q->where('job_title', 'like', "%{$filters['search']}%")
                        ->orWhere('company_name', 'like', "%{$filters['search']}%");
                  });
        }

        if (isset($filters['user_id'])) {
            $query->where('user_id', $filters['user_id']);
        }

        return $query->latest()->paginate(15);
    }

    public function addPostToCommunity(Community $community, int $postId): void
    {
        DB::transaction(function () use ($community, $postId) {
            $community->posts()->attach($postId);
        });
    }

    public function removePostFromCommunity(Community $community, int $postId): void
    {
        DB::transaction(function () use ($community, $postId) {
            $community->posts()->detach($postId);
        });
    }

    public function getCommunitiesForDropdown(): array
    {
        return Community::select('id', 'name', 'slug')
            ->orderBy('name')
            ->get()
            ->map(function ($community) {
                return [
                    'id' => $community->id,
                    'name' => $community->name,
                    'slug' => $community->slug,
                ];
            })
            ->toArray();
    }

    public function userCanPostInCommunity(User $user, Community $community): bool
    {
        return $user->canPostInCommunity($community);
    }

    public function userIsMember(User $user, Community $community): bool
    {
        return $community->isMember($user);
    }

    public function getUserRoleInCommunity(User $user, Community $community): ?string
    {
        return $community->getMemberRole($user);
    }
}