<?php

namespace App\Http\Controllers\Backend;

use App\Http\Controllers\Controller;
use App\Models\Group;
use App\Models\GroupCategory;
use App\Models\GroupMember;
use App\Models\GroupPost;
use App\Models\GroupReport;
use App\Models\Post;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;

class GroupController extends Controller
{
    /**
     * Display a listing of all groups
     *
     * @return \Illuminate\View\View
     */
    public function index(Request $request)
    {
        $query = Group::with(['creator', 'category', 'owner']);
        
        // Filter by search term
        if ($request->has('search') && !empty($request->input('search'))) {
            $search = $request->input('search');
            $query->where('name', 'like', "%{$search}%")
                ->orWhere('description', 'like', "%{$search}%");
        }
        
        // Filter by privacy
        if ($request->has('privacy') && !empty($request->input('privacy'))) {
            $query->where('is_private', $request->input('privacy'));
        }
        
        // Filter by date range
        if ($request->has('date_from') && !empty($request->input('date_from'))) {
            $query->whereDate('created_at', '>=', $request->input('date_from'));
        }
        if ($request->has('date_to') && !empty($request->input('date_to'))) {
            $query->whereDate('created_at', '<=', $request->input('date_to'));
        }
        
        // Sort by
        switch($request->input('sort')) {
            case 'oldest':
                $query->orderBy('created_at', 'asc');
                break;
            case 'members':
                $query->orderBy('members_count', 'desc');
                break;
            default: // newest
                $query->orderBy('created_at', 'desc');
                break;
        }
        
        $groups = $query->paginate(15);
        $categories = GroupCategory::all();
        
        // Get counts for dashboard
        $totalGroups = Group::count();
        $publicGroups = Group::where('is_private', '0')->count();
        $privateGroups = Group::where('is_private', '1')->count();
        
        return view('admin.pages.groups.index', compact(
            'groups', 
            'categories', 
            'totalGroups', 
            'publicGroups', 
            'privateGroups'
        ));
    }

    /**
     * Display the group details page
     *
     * @param  int  $id
     * @return \Illuminate\View\View
     */
    public function show($id)
    {
        $group = Group::with(['creator', 'category', 'members.user'])->findOrFail($id);
        
        // Get group statistics
        $totalMembers = $group->members()->count();
        $totalPosts = GroupPost::where('group_id', $id)->count();
        $totalAdmins = $group->members()->where('role', 'admin')->count();
        $totalModerators = $group->members()->where('role', 'moderator')->count();
        
        // Get recent members
        $recentMembers = $group->members()
            ->with('user')
            ->orderBy('created_at', 'desc')
            ->limit(10)
            ->get();
            
        // Get recent posts
        $recentPosts = GroupPost::with('user')
            ->where('group_id', $id)
            ->orderBy('created_at', 'desc')
            ->limit(10)
            ->get();
        
        return view('admin.pages.groups.show', compact(
            'group', 
            'totalMembers', 
            'totalPosts', 
            'totalAdmins',
            'totalModerators',
            'recentMembers',
            'recentPosts'
        ));
    }

    /**
     * Display the featured groups page
     *
     * @return \Illuminate\View\View
     */
    public function featured(Request $request)
    {
        $featuredGroups = Group::with('creator', 'category')
            ->where('is_featured', true)
            ->paginate(15);
            
        $nonFeaturedGroups = Group::with('creator')
            ->where('is_featured', false)
            ->orderBy('members_count', 'desc')
            ->limit(20)
            ->get();
            
        // Fetch suggested groups (you can define your own logic for what constitutes a "suggested" group)
        $suggestedGroups = Group::with('creator', 'category')
            ->where('is_featured', false) // Example condition
            ->where('is_private', 0) // Example condition
            ->inRandomOrder() // Randomly suggest groups
            ->limit(5) // Limit the number of suggested groups
            ->get();
            
        return view('admin.pages.groups.featured', compact('featuredGroups', 'nonFeaturedGroups', 'suggestedGroups'));
    }
    
    /**
     * Toggle the featured status of a group
     *
     * @param  int  $id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function toggleFeatured($id)
    {
        $group = Group::findOrFail($id);
        $group->is_featured = !$group->is_featured;
        $group->save();
        
        $status = $group->is_featured ? 'featured' : 'unfeatured';
        
        return json_encode(['success' => true]);
    }
    
    /**
     * Display the reported groups page
     *
     * @return \Illuminate\View\View
     */
    public function reported(Request $request)
    {
        $query = GroupReport::with(['group.creator', 'user'])
            ->when($request->has('status') && $request->status !== '' && !empty($request->status), function($q) use ($request) {
                return $q->where('status', $request->status);
            });

        $reports = $query->latest()->paginate(15);
        
        // Get counts for different statuses
        $pendingCount = GroupReport::where('status', 'pending')->count();
        $resolvedCount = GroupReport::where('status', 'resolved')->count();
        $dismissedCount = GroupReport::where('status', 'dismissed')->count();
            
        return view('admin.pages.groups.reported', compact(
            'reports',
            'pendingCount',
            'resolvedCount',
            'dismissedCount'
        ));
    }
    
    /**
     * Display the group categories page
     *
     * @return \Illuminate\View\View
     */
    public function categories()
    {
        $categories = GroupCategory::withCount('groups')->get();
        
        return view('admin.pages.groups.categories', compact('categories'));
    }

    /**
     * Update the specified group
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function update(Request $request, $id)
    {
        try {
            $group = Group::findOrFail($id);
            
            $validator = Validator::make($request->all(), [
                'name' => 'nullable|string|min:3|max:50',
                'description' => 'nullable|string|min:10|max:500',
                'privacy' => 'nullable|string|in:public,private,hidden',
                'category_id' => 'nullable|exists:group_categories,id',
                'cover_image' => 'nullable|image|mimes:jpeg,png,jpg|max:2048'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Validation failed',
                    'errors' => $validator->errors()
                ], 422);
            }

            $groupData = $validator->validated();

            // Update slug if name is changed
            if (isset($groupData['name'])) {
                $newSlug = Str::slug($groupData['name']);
                // Check if new slug exists for other groups
                $existingGroup = Group::where('slug', $newSlug)
                    ->where('id', '!=', $id)
                    ->first();
                if ($existingGroup) {
                    return response()->json([
                        'success' => false,
                        'message' => 'Validation failed',
                        'errors' => ['name' => ['A group with this URL already exists']]
                    ], 422);
                }
                $groupData['slug'] = $newSlug;
            }

            // Handle privacy settings
            if (isset($groupData['privacy'])) {
                $groupData['is_private'] = $groupData['privacy'] === 'private';
                $groupData['allow_members_to_post'] = $groupData['privacy'] === 'public';
                $groupData['privacy'] = $request->privacy;
                unset($groupData['privacy']);
            }

            // Handle cover image upload
            if ($request->hasFile('cover_image')) {
                $groupData['cover_image'] = storeMedia($request->file('cover_image'), 'group_covers');
            }

            $group->update(array_filter($groupData));
            
            return response()->json([
                'success' => true,
                'message' => 'Group updated successfully',
                'data' => $group
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to update group: ' . $e->getMessage()
            ], 500);
        }
    }
    
    /**
     * Store a new group category
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function storeCategory(Request $request)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255|unique:group_categories,name',
            'description' => 'nullable|string',
            'icon' => 'nullable|string|max:50',
        ]);
        
        GroupCategory::create($validated);
        
        return redirect()->route('admin.groups.categories')
            ->with('success', 'Category created successfully');
    }
    
    /**
     * Update a group category
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function updateCategory(Request $request, $id)
    {
        $category = GroupCategory::findOrFail($id);
        
        $validated = $request->validate([
            'name' => 'required|string|max:255|unique:group_categories,name,' . $id,
            'description' => 'nullable|string',
            'icon' => 'nullable|string|max:50',
        ]);
        
        $category->update($validated);
        
        return json_encode(['success' => true]);
    }
    
    /**
     * Delete a group category
     *
     * @param  int  $id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function deleteCategory($id)
    {
        $category = GroupCategory::findOrFail($id);
        
        // Check if groups are using this category
        $groupsCount = $category->groups()->count();
        
        if ($groupsCount > 0) {
            return redirect()->route('admin.groups.categories')
                ->with('error', "Cannot delete category. {$groupsCount} groups are using this category.");
        }
        
        $category->delete();
        
        return redirect()->route('admin.groups.categories')
            ->with('success', 'Category deleted successfully');
    }
    
    /**
     * Display the group statistics page
     *
     * @return \Illuminate\View\View
     */
    public function statistics()
    {
        // Overall statistics
        $totalGroups = Group::count();
        $totalPublicGroups = Group::where('type', 'public')->count();
        $totalPrivateGroups = Group::where('type', 'private')->count();
        $totalMembers = GroupMember::count();
        $totalPosts = Post::where('post_type', 'group_post')->count();
        
        // Most active groups (by post count)
        $mostActiveGroups = Group::withCount('posts')
            ->orderBy('id', 'desc')
            ->limit(10)
            ->get();
            
        // Largest groups (by member count)
        $largestGroups = Group::withCount('members')
            ->orderBy('members_count', 'desc')
            ->limit(10)
            ->get();
            
        // Most moderated groups (groups with most admins/moderators)
        $mostModeratedGroups = Group::withCount(['members as moderators_count' => function ($query) {
                $query->where('role', 'admin')->orWhere('role', 'moderator');
            }])
            ->orderBy('moderators_count', 'desc')
            ->limit(10)
            ->get();
            
        // Groups by category
        $groupsByCategory = GroupCategory::withCount('groups')
            ->orderBy('groups_count', 'desc')
            ->get();
            
        // Recent group creation trend (last 12 months)
        $groupCreationTrend = DB::table('groups')
            ->select(DB::raw('MONTH(created_at) as month, YEAR(created_at) as year, COUNT(*) as count'))
            ->where('created_at', '>=', now()->subMonths(12))
            ->groupBy('year', 'month')
            ->orderBy('year')
            ->orderBy('month')
            ->get();
            
        // Format data for charts
        $categoryLabels = $groupsByCategory->pluck('name')->toJson();
        $categoryCounts = $groupsByCategory->pluck('groups_count')->toJson();
        
        $trendLabels = $groupCreationTrend->map(function ($item) {
            return date('M Y', mktime(0, 0, 0, $item->month, 1, $item->year));
        })->toJson();
        
        $trendCounts = $groupCreationTrend->pluck('count')->toJson();
        
        return view('admin.pages.groups.statistics', compact(
            'totalGroups',
            'totalPublicGroups',
            'totalPrivateGroups',
            'totalMembers',
            'totalPosts',
            'mostActiveGroups',
            'largestGroups',
            'mostModeratedGroups',
            'groupsByCategory',
            'categoryLabels',
            'categoryCounts',
            'trendLabels',
            'trendCounts'
        ));
    }
    
    /**
     * Update group status (active/inactive)
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function updateStatus(Request $request, $id)
    {
        $group = Group::findOrFail($id);
        $group->active = $request->input('status');
        $group->save();
        
        $statusText = $group->active ? 'activated' : 'deactivated';
        
        return redirect()->back()->with('success', "Group has been {$statusText} successfully");
    }
    
    /**
     * Delete a group
     *
     * @param  int  $id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function destroy($id)
    {
        $group = Group::findOrFail($id);
        
        // Delete all related data
        // This assumes you have cascading deletes set up in your migrations
        // Otherwise you'll need to manually delete related records
        $group->delete();
        
        return json_encode(['success' => true]);
    }

    // Functions for update the report status and delete the report
    public function updateReport(Request $request, $id){
        $report = GroupReport::findOrFail($id);
        $report->status = $request->input('status');
        $report->save();
        return redirect()->back()->with('success', 'Report status updated successfully');
    }

    public function deleteReport($id){
        $report = GroupReport::findOrFail($id);
        // Soft Delete, update deleted_at
        $report->delete();
        return redirect()->back()->with('success', 'Report deleted successfully');
    }
}