<?php

namespace App\Http\Controllers\Backend;

use App\Http\Controllers\Controller;
use App\Models\Setting;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Str;

class BackendController extends Controller
{
    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Contracts\View\View
     */
    public $module_title;

    public $module_name;

    public $module_path;

    public $module_icon;

    public $module_model;

    public function __construct()
    {
        $this->module_title = 'Settings';

        // module name
        $this->module_name = 'settings';

        // directory path of the module
        $this->module_path = 'settings';

        // module icon
        $this->module_icon = 'c-icon fas fa-settings';
    }

    public function index()
    {


        // Get real statistics from the database
        $stats = $this->getDashboardStats();

        // Get recent activities
        $recentActivities = $this->getRecentActivities();

        // Get top content
        $topContent = $this->getTopContent();

        // Get system health data
        $systemHealth = $this->getSystemHealth();

        // Get user growth data for charts
        $userGrowthData = $this->getUserGrowthData();

        // Get engagement metrics
        $engagementMetrics = $this->getEngagementMetrics();

        return view('admin.pages.dashboard.index', compact(
            'stats',
            'recentActivities',
            'topContent',
            'systemHealth',
            'userGrowthData',
            'engagementMetrics'
        ));
    }

    /**
     * Get dashboard statistics
     */
    private function getDashboardStats()
    {
        try {
            // User statistics
            $totalUsers = 0;
            $newUsersThisMonth = 0;
            $activeUsers = 0;
            try {
                if (class_exists('\App\Models\User')) {
                    $totalUsers = \App\Models\User::count();
                    $newUsersThisMonth = \App\Models\User::whereMonth('created_at', now()->month)->count();
                    $activeUsers = \App\Models\User::where('last_seen_at', '>=', now()->subDays(7))->count();
                }
            } catch (\Exception $e) {
                // Ignore if users table doesn't exist
            }

            // Post statistics
            $totalPosts = 0;
            $postsThisMonth = 0;
            try {
                if (class_exists('\App\Models\Post')) {
                    $totalPosts = \App\Models\Post::count();
                    $postsThisMonth = \App\Models\Post::whereMonth('created_at', now()->month)->count();
                }
            } catch (\Exception $e) {
                // Ignore if posts table doesn't exist
            }

            // Comment statistics
            $totalComments = 0;
            $commentsThisMonth = 0;
            try {
                if (class_exists('\App\Models\Comment')) {
                    $totalComments = \App\Models\Comment::count();
                    $commentsThisMonth = \App\Models\Comment::whereMonth('created_at', now()->month)->count();
                } elseif (class_exists('\App\Models\PostComment')) {
                    $totalComments = \App\Models\PostComment::count();
                    $commentsThisMonth = \App\Models\PostComment::whereMonth('created_at', now()->month)->count();
                }
            } catch (\Exception $e) {
                // Ignore if comments table doesn't exist
            }

            // Message statistics (using chat messages if available)
            $totalMessages = 0;
            $messagesThisMonth = 0;
            try {
                if (class_exists('\App\Models\Message')) {
                    $totalMessages = \App\Models\Message::count();
                    $messagesThisMonth = \App\Models\Message::whereMonth('created_at', now()->month)->count();
                } elseif (class_exists('\App\Models\ChatMessage')) {
                    $totalMessages = \App\Models\ChatMessage::count();
                    $messagesThisMonth = \App\Models\ChatMessage::whereMonth('created_at', now()->month)->count();
                }
            } catch (\Exception $e) {
                // Ignore if table doesn't exist
            }

            // Page statistics
            $totalPages = 0;
            $pagesThisMonth = 0;
            try {
                if (class_exists('\App\Models\Page')) {
                    $totalPages = \App\Models\Page::count();
                    $pagesThisMonth = \App\Models\Page::whereMonth('created_at', now()->month)->count();
                }
            } catch (\Exception $e) {
                // Ignore if pages table doesn't exist
            }

            // Group statistics
            $totalGroups = 0;
            $groupsThisMonth = 0;
            try {
                if (class_exists('\App\Models\Group')) {
                    $totalGroups = \App\Models\Group::count();
                    $groupsThisMonth = \App\Models\Group::whereMonth('created_at', now()->month)->count();
                }
            } catch (\Exception $e) {
                // Ignore if groups table doesn't exist
            }

            // Game statistics
            $totalGames = 0;
            $gamesThisMonth = 0;
            try {
                if (class_exists('\App\Models\Games\Game')) {
                    $totalGames = \App\Models\Games\Game::count();
                    $gamesThisMonth = \App\Models\Games\Game::whereMonth('created_at', now()->month)->count();
                }
            } catch (\Exception $e) {
                // Ignore if games table doesn't exist
            }

            // Online users (users active in last 5 minutes)
            $onlineUsers = 0;
            try {
                if (class_exists('\App\Models\User')) {
                    $onlineUsers = \App\Models\User::where('last_seen_at', '>=', now()->subMinutes(5))->count();
                }
            } catch (\Exception $e) {
                // Ignore if users table doesn't exist
            }

            return [
                'users' => [
                    'total' => $totalUsers,
                    'new_this_month' => $newUsersThisMonth,
                    'active' => $activeUsers,
                    'online' => $onlineUsers,
                    'growth_rate' => $totalUsers > 0 ? round(($newUsersThisMonth / $totalUsers) * 100, 1) : 0
                ],
                'posts' => [
                    'total' => $totalPosts,
                    'this_month' => $postsThisMonth,
                    'growth_rate' => $totalPosts > 0 ? round(($postsThisMonth / $totalPosts) * 100, 1) : 0
                ],
                'comments' => [
                    'total' => $totalComments,
                    'this_month' => $commentsThisMonth,
                    'growth_rate' => $totalComments > 0 ? round(($commentsThisMonth / $totalComments) * 100, 1) : 0
                ],
                'messages' => [
                    'total' => $totalMessages,
                    'this_month' => $messagesThisMonth,
                    'growth_rate' => $totalMessages > 0 ? round(($messagesThisMonth / $totalMessages) * 100, 1) : 0
                ],
                'pages' => [
                    'total' => $totalPages,
                    'this_month' => $pagesThisMonth,
                    'growth_rate' => $totalPages > 0 ? round(($pagesThisMonth / $totalPages) * 100, 1) : 0
                ],
                'groups' => [
                    'total' => $totalGroups,
                    'this_month' => $groupsThisMonth,
                    'growth_rate' => $totalGroups > 0 ? round(($groupsThisMonth / $totalGroups) * 100, 1) : 0
                ],
                'games' => [
                    'total' => $totalGames,
                    'this_month' => $gamesThisMonth,
                    'growth_rate' => $totalGames > 0 ? round(($gamesThisMonth / $totalGames) * 100, 1) : 0
                ]
            ];
        } catch (\Exception $e) {
            // Return default values if there's an error
            return [
                'users' => ['total' => 0, 'new_this_month' => 0, 'active' => 0, 'online' => 0, 'growth_rate' => 0],
                'posts' => ['total' => 0, 'this_month' => 0, 'growth_rate' => 0],
                'comments' => ['total' => 0, 'this_month' => 0, 'growth_rate' => 0],
                'messages' => ['total' => 0, 'this_month' => 0, 'growth_rate' => 0],
                'pages' => ['total' => 0, 'this_month' => 0, 'growth_rate' => 0],
                'groups' => ['total' => 0, 'this_month' => 0, 'growth_rate' => 0],
                'games' => ['total' => 0, 'this_month' => 0, 'growth_rate' => 0]
            ];
        }
    }

    /**
     * Get recent activities
     */
    private function getRecentActivities()
    {
        try {
            $activities = collect();

            // Recent user registrations
            $recentUsers = collect();
            try {
                if (class_exists('\App\Models\User')) {
                    $recentUsers = \App\Models\User::latest()->take(3)->get();
                }
            } catch (\Exception $e) {
                // Ignore if users table doesn't exist
            }
            foreach ($recentUsers as $user) {
                $activities->push([
                    'type' => 'user_registered',
                    'title' => 'New User Registered',
                    'description' => $user->name . ' joined the platform',
                    'time' => $user->created_at->diffForHumans(),
                    'icon' => 'bi-person-plus',
                    'color' => 'primary',
                    'avatar' => $user->avatar ?? asset('assets/images/default-avatar.png')
                ]);
            }

            // Recent posts
            $recentPosts = collect();
            try {
                if (class_exists('\App\Models\Post')) {
                    $recentPosts = \App\Models\Post::with('user')->latest()->take(3)->get();
                }
            } catch (\Exception $e) {
                // Ignore if posts table doesn't exist
            }
            foreach ($recentPosts as $post) {
                $activities->push([
                    'type' => 'post_created',
                    'title' => 'New Post Created',
                    'description' => $post->user->name . ' created a new post',
                    'time' => $post->created_at->diffForHumans(),
                    'icon' => 'bi-file-post',
                    'color' => 'success',
                    'avatar' => $post->user->avatar ?? asset('assets/images/default-avatar.png')
                ]);
            }

            // Recent groups
            $recentGroups = collect();
            try {
                if (class_exists('\App\Models\Group')) {
                    $recentGroups = \App\Models\Group::latest()->take(2)->get();
                }
            } catch (\Exception $e) {
                // Ignore if groups table doesn't exist
            }
            foreach ($recentGroups as $group) {
                $activities->push([
                    'type' => 'group_created',
                    'title' => 'New Group Created',
                    'description' => 'Group "' . $group->name . '" was created',
                    'time' => $group->created_at->diffForHumans(),
                    'icon' => 'bi-people-fill',
                    'color' => 'info',
                    'avatar' => asset('assets/images/group-icon.png')
                ]);
            }

            return $activities->sortByDesc('time')->take(8);
        } catch (\Exception $e) {
            return collect();
        }
    }

    /**
     * Get top content
     */
    private function getTopContent()
    {
        try {
            $content = collect();

            // Top posts by likes
            $topPosts = collect();
            try {
                if (class_exists('\App\Models\PostLike')) {
                    $topPosts = \App\Models\Post::withCount(['likes' => function ($query) {
                        $query->from('post_likes');
                    }])
                        ->with('user')
                        ->orderBy('likes_count', 'desc')
                        ->take(5)
                        ->get();
                } else {
                    // Fallback to posts ordered by created_at
                    $topPosts = \App\Models\Post::with('user')
                        ->orderBy('created_at', 'desc')
                        ->take(5)
                        ->get();
                }
            } catch (\Exception $e) {
                // Fallback to posts ordered by created_at
                $topPosts = \App\Models\Post::with('user')
                    ->orderBy('created_at', 'desc')
                    ->take(5)
                    ->get();
            }

            foreach ($topPosts as $post) {
                $content->push([
                    'type' => 'post',
                    'title' => $post->user->name . '\'s Post',
                    'subtitle' => 'Post',
                    'views' => $post->likes_count ?? 0,
                    'status' => 'trending',
                    'avatar' => $post->user->avatar ?? asset('assets/images/default-avatar.png'),
                    'growth' => '+12.4%'
                ]);
            }

            // Top games
            $topGames = collect();
            try {
                if (class_exists('\App\Models\Games\Game')) {
                    $topGames = \App\Models\Games\Game::withCount('plays')
                        ->orderBy('plays_count', 'desc')
                        ->take(3)
                        ->get();
                }
            } catch (\Exception $e) {
                // Ignore if games table doesn't exist
            }

            foreach ($topGames as $game) {
                $content->push([
                    'type' => 'game',
                    'title' => $game->title,
                    'subtitle' => 'Game',
                    'views' => $game->plays_count,
                    'status' => 'popular',
                    'avatar' => $game->image ?? asset('assets/images/game-icon.png'),
                    'growth' => '+8.7%'
                ]);
            }

            return $content->sortByDesc('views')->take(5);
        } catch (\Exception $e) {
            return collect();
        }
    }

    /**
     * Get system health data
     */
    private function getSystemHealth()
    {
        try {
            return [
                'disk_usage' => $this->getDiskUsage(),
                'memory_usage' => $this->getMemoryUsage(),
                'database_connections' => DB::connection()->getPdo() ? 'Connected' : 'Disconnected',
                'cache_status' => 'Active',
                'queue_status' => 'Running',
                'last_backup' => now()->subDays(1)->format('M d, Y H:i'),
                'system_uptime' => '15 days, 8 hours'
            ];
        } catch (\Exception $e) {
            return [
                'disk_usage' => 0,
                'memory_usage' => 0,
                'database_connections' => 'Unknown',
                'cache_status' => 'Unknown',
                'queue_status' => 'Unknown',
                'last_backup' => 'Unknown',
                'system_uptime' => 'Unknown'
            ];
        }
    }

    /**
     * Get disk usage percentage
     */
    private function getDiskUsage()
    {
        try {
            $totalSpace = disk_total_space(storage_path());
            $freeSpace = disk_free_space(storage_path());
            return round((($totalSpace - $freeSpace) / $totalSpace) * 100, 1);
        } catch (\Exception $e) {
            return 0;
        }
    }

    /**
     * Get memory usage percentage
     */
    private function getMemoryUsage()
    {
        try {
            $memoryLimit = ini_get('memory_limit');
            $memoryUsage = memory_get_usage(true);
            return round(($memoryUsage / $this->returnBytes($memoryLimit)) * 100, 1);
        } catch (\Exception $e) {
            return 0;
        }
    }

    /**
     * Convert memory limit string to bytes
     */
    private function returnBytes($val)
    {
        $val = trim($val);
        $last = strtolower($val[strlen($val) - 1]);
        $val = substr($val, 0, -1);
        switch ($last) {
            case 'g':
                $val *= 1024;
            case 'm':
                $val *= 1024;
            case 'k':
                $val *= 1024;
        }
        return $val;
    }

    /**
     * Get user growth data for charts
     */
    private function getUserGrowthData()
    {
        try {
            $data = [];
            try {
                if (class_exists('\App\Models\User')) {
                    for ($i = 11; $i >= 0; $i--) {
                        $date = now()->subMonths($i);
                        $count = \App\Models\User::whereYear('created_at', $date->year)
                            ->whereMonth('created_at', $date->month)
                            ->count();

                        $data[] = [
                            'month' => $date->format('M Y'),
                            'users' => $count
                        ];
                    }
                }
            } catch (\Exception $e) {
                // Generate sample data if table doesn't exist
                for ($i = 11; $i >= 0; $i--) {
                    $date = now()->subMonths($i);
                    $data[] = [
                        'month' => $date->format('M Y'),
                        'users' => rand(10, 100)
                    ];
                }
            }
            return $data;
        } catch (\Exception $e) {
            return [];
        }
    }

    /**
     * Get engagement metrics
     */
    private function getEngagementMetrics()
    {
        try {
            return [
                'posts_per_user' => (class_exists('\App\Models\User') && class_exists('\App\Models\Post') && \App\Models\User::count() > 0) ? round(\App\Models\Post::count() / \App\Models\User::count(), 1) : 0,
                'comments_per_post' => (class_exists('\App\Models\Post') && \App\Models\Post::count() > 0) ? round((class_exists('\App\Models\Comment') ? \App\Models\Comment::count() : (class_exists('\App\Models\PostComment') ? \App\Models\PostComment::count() : 0)) / \App\Models\Post::count(), 1) : 0,
                'likes_per_post' => (class_exists('\App\Models\Post') && \App\Models\Post::count() > 0) ? round((class_exists('\App\Models\PostLike') ? \App\Models\PostLike::count() : 0) / \App\Models\Post::count(), 1) : 0,
                'active_users_percentage' => (class_exists('\App\Models\User') && \App\Models\User::count() > 0) ? round((\App\Models\User::where('last_seen_at', '>=', now()->subDays(7))->count() / \App\Models\User::count()) * 100, 1) : 0
            ];
        } catch (\Exception $e) {
            return [
                'posts_per_user' => 0,
                'comments_per_post' => 0,
                'likes_per_post' => 0,
                'active_users_percentage' => 0
            ];
        }
    }

    public function generalSettings()
    {
        $setting = Setting::first();
        return view('admin.pages.settings.general_settings')->with(compact('setting'));
    }
    public function mailConfiguration()
    {
        $setting = Setting::first();
        return view('admin.pages.settings.mail_configurations');
    }
    public function enableDisableFeatures()
    {
        $setting = Setting::first();
        return view('admin.pages.settings.enable_disable_features');
    }
    public function paymentSettings()
    {
        return view('admin.pages.settings.payment_settings');
    }
    public function socialLogins()
    {
        $settings = Setting::getSettings();

        return view('admin.pages.settings.social_logins', compact('settings'));
    }
    public function uploadConfigurations()
    {
        $setting = Setting::first();
        return view('admin.pages.settings.upload_config');
    }
    public function websiteInfo()
    {
        return view('admin.pages.settings.website_info');
    }
    public function proSystem()
    {
        return view('admin.pages.pro_system.pro_system');
    }

    public function updateGeneralSettings(Request $request)
    {
        $request->validate([
            'name' => 'required',
            'value' => 'required',
        ]);
        dd($request->all());
        $setting = Setting::where('name', $request->name)->first();
        if ($setting) {
            $setting->where('name', $request->name)->update(['val' => $request->value, 'type' => $request->type]);
        } else {
            $setting = Setting::create(
                ['name' => $request->name, 'val' => $request->value, 'type' => $request->type]
            );
        }

        return true;
    }

    public function updateSettings(Request $request)
    {
        $request->validate([
            'name' => 'required|string',
            'value' => 'nullable',
            'type' => 'nullable|string',
            'visibility' => 'nullable|string|in:public,private',
        ]);

        $setting = Setting::updateOrCreate(
            ['name' => $request->name],
            [
                'val' => $request->value,
                'type' => $request->type ?? 'string',
            ]
        );
        Setting::refreshCache();
        return true;
    }

    public function upload(Request $request)
    {
        // Define allowed types for different inputs
        $allowedTypes = [
            'image' => [],
            'json'  => ['google_cloud_file'],
            'video' => [],
            'pdf'   => [],
        ];

        // Define MIME type rules explicitly
        $mimeRules = [
            'image' => 'image|mimes:jpeg,jpg,png,gif',
            'video' => 'mimes:mp4,mkv,avi',
            'json'  => 'mimes:json,application/json', // Explicitly allowing both json and application/json
            'pdf'   => 'mimes:pdf',
        ];

        // Fetch the input name from the request
        $inputName = $request->input('input_name');
        $fileType = null;

        // Match the input name to the allowed types
        foreach ($allowedTypes as $type => $inputs) {
            if (in_array($inputName, $inputs)) {
                $fileType = $type;
                break;
            }
        }

        // If no matching file type found, return an error
        if (!$fileType) {
            return response()->json(['message' => 'Invalid file input field'], 400);
        }

        // Manually check the MIME type before validation
        $file = $request->file('file');
        $mimeType = $file->getMimeType();
        // Manually check if the MIME type matches for json
        if ($fileType === 'json' && $mimeType !== 'application/json') {
            return response()->json(['message' => 'The file must be a valid JSON file'], 400);
        }

        // Validate the file (if it's not a JSON, the regular validation will be applied)
        $validationRules = [
            'file' => 'required|file|max:2048',
            'folder' => 'required|string',
        ];

        // Add the appropriate MIME type validation rule based on the file type
        if (isset($mimeRules[$fileType])) {
            $validationRules['file'] .= '|' . $mimeRules[$fileType];
        }

        // Run the validation
        $request->validate($validationRules);

        // Upload the file (use your custom upload function)
        $filename = uploadFile($file, $request->folder);

        return response()->json(['success' => true, 'filename' => $filename]);
    }


    public function getFile($folder, $filename)
    {
        return response()->json(['file_url' => getFileUrl($filename, $folder)]);
    }

    public function audio_video_settings()
    {
        return view('admin.pages.settings.audio_video_settings');
    }

    public function nodejs_settings()
    {
        return view('admin.pages.settings.nodejs_settings');
    }

    public function cronJobSettings()
    {
        $setting = Setting::first();
        return view('admin.pages.settings.cronJob_settings')->with(compact('setting'));
    }

    public function aiSettings()
    {
        $setting = Setting::first();
        return view('admin.pages.settings.ai_settings')->with(compact('setting'));
    }

    public function postSettings()
    {
        return view('admin.pages.settings.postSettings');
    }

    public function manageColorPost()
    {
        return view('admin.pages.settings.manageColorPost');
    }

    public function manageReactions()
    {
        return view('admin.pages.settings.managePostReactions');
    }

    public function liveStreaming()
    {
        return view('admin.pages.settings.livestream_settings');
    }
}
