<?php

namespace App\Http\Controllers;

use App\Models\Page;
use App\Models\User;
use App\Models\PageLike;
use App\Models\CustomPage;
use Illuminate\Support\Str;
use App\Models\Notification;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Http\Resources\PageResource;
use App\Http\Resources\UserResource;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;

class PageController extends Controller
{
    /**
     * Fetch all pages except those owned by the authenticated user.
     */
    public function getAllPages(Request $request)
    {

        $userId = Auth::id();
        $perPage = (int) $request->input('per_page', 6);
        $search = $request->input('search', null);
        $category = $request->input('category', null);
        $isMe = $request->input('is_me', false);
        $following = $request->input('following', false);
        $verified = $request->input('verified', false);
        $unverified = $request->input('unverified', false);
        $sort = $request->input('sort', 'newest');
        $categories = $request->input('categories', null);
        $followers = $request->input('followers', null);

        $pages = Page::query()
            ->when(
                $isMe == 'true',
                function ($query) use ($userId) {
                    $query->where('user_id', $userId);
                },
                function ($query) use ($userId) {
                    $query->where('user_id', '!=', $userId); // Return all pages when isMe is false
                }
            )
            ->when($search, function ($query) use ($search) {
                $query->where('page_title', 'like', '%' . $search . '%')
                    ->orWhere('page_description', 'like', '%' . $search . '%')
                    ->orWhere('page_username', 'like', '%' . $search . '%')
                    ->orWhere('page_category', 'like', '%' . $search . '%');
            })
            ->when($category, function ($query) use ($category) {
                $query->where('page_category', $category);
            })
            ->when($categories, function ($query) use ($categories) {
                $categoryList = explode(',', $categories);
                $query->whereIn('page_category', $categoryList);
            })
            ->when($following, function ($query) use ($userId) {
                $query->whereHas('likes', function ($q) use ($userId) {
                    $q->where('user_id', $userId);
                });
            })
            ->when($verified, function ($query) {
                $query->where('is_verified', true);
            })
            ->when($unverified, function ($query) {
                $query->where('is_verified', false);
            })
            ->when($followers, function ($query) use ($followers) {
                $followerList = explode(',', $followers);
                foreach ($followerList as $followerFilter) {
                    switch ($followerFilter) {
                        case 'small':
                            $query->where('likes_count', '<', 1000);
                            break;
                        case 'medium':
                            $query->whereBetween('likes_count', [1000, 100000]);
                            break;
                        case 'large':
                            $query->where('likes_count', '>', 100000);
                            break;
                    }
                }
            })
            ->withCount('likes')
            ->when($sort, function ($query) use ($sort) {
                switch ($sort) {
                    case 'newest':
                        $query->orderBy('created_at', 'desc');
                        break;
                    case 'oldest':
                        $query->orderBy('created_at', 'asc');
                        break;
                    case 'most_followers':
                        $query->orderBy('likes_count', 'desc');
                        break;
                    case 'least_followers':
                        $query->orderBy('likes_count', 'asc');
                        break;
                    case 'alphabetical':
                        $query->orderBy('page_title', 'asc');
                        break;
                    default:
                        $query->orderBy('created_at', 'desc');
                }
            })
            ->paginate($perPage);

        if ($pages->isEmpty()) {
            return response()->json([
                'status' => 200,
                'message' => __('Api.no_data_found'),
                'data' => []
            ]);
        }

        return response()->json([
            'status' => 200,
            'message' => __('Api.pages_fetched_successfully'),
            'data' => PageResource::collection($pages),
            'pagination' => [
                'total' => $pages->total(),
                'per_page' => $pages->perPage(),
                'current_page' => $pages->currentPage(),
                'last_page' => $pages->lastPage(),
                'from' => $pages->firstItem(),
                'to' => $pages->lastItem()
            ]
        ]);
    }


    /**
     * Check if a page name or page URL already exists.
     */
    public function checkPageExistence(Request $request)
    {
        $request->validate([
            'page_name' => 'required|string|min:3',
            'page_url' => 'required|string'
        ]);

        $pageName = $request->input('page_name');
        $pageUrl = $request->input('page_url');

        $nameExists = Page::where('page_title', $pageName)->exists();
        $urlExists = Page::where('page_username', $pageUrl)->exists();

        return response()->json([
            'exists' => $nameExists || $urlExists,
            'name_exists' => $nameExists,
            'url_exists' => $urlExists
        ]);
    }


    /**
     * Fetch all pages created by the logged-in user.
     */
    public function userPages(Request $request)
    {
        $userId = Auth::id();
        $offset = (int) $request->input('offset', 0);
        $limit = (int) $request->input('limit', 6);

        $pages = Page::where('user_id', $userId)
            ->withCount('likes')
            ->offset($offset)
            ->limit($limit)
            ->get();

        return response()->json([
            'status' => 200,
            'message' => __('Api.pages_fetched_successfully'),
            'data' => PageResource::collection($pages)
        ]);
    }


    /**
     * Create a new page.
     */

    public function addPage(Request $request)
    {
        $validatedData = $request->validate([
            'page_title' => 'required|string|min:5|max:50|regex:/^[a-zA-Z0-9 ]+$/',
            'page_description' => 'required|string|min:10',
            'page_category' => 'required|string',
            'website' => 'nullable|url',
            'avatar' => 'nullable',
            'cover' => 'nullable',
            'page_username' => 'string'
        ]);

        $userId = Auth::id();
        $pageTitle = $validatedData['page_title'];

        if (empty($request->input('page_username'))) {
            $pageUsername = Str::slug($pageTitle);
        } else {
            $pageUsername = Str::slug($request->input('page_username'));
        }

        // Generate a truly unique page username using random suffix if needed
        $originalUsername = $pageUsername;

        while (Page::withTrashed()->where('page_username', $pageUsername)->exists()) {
            $randomSuffix = Str::random(5); // you can change length if needed
            $pageUsername = $originalUsername . '-' . $randomSuffix;
        }
        try {
            $page = Page::create([
                'user_id' => $userId,
                'page_username' => $pageUsername,
                'page_title' => $pageTitle,
                'page_description' => $validatedData['page_description'],
                'page_category' => $validatedData['page_category'],
                'website' => $validatedData['website'] ?? null,
                'avatar' => $validatedData['avatar'] ?? null,
                'cover' => $validatedData['cover'] ?? null,
            ]);

            return response()->json([
                'status' => 201,
                'message' => __('Api.page_created_successfully'),
                'data' => new PageResource($page)
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 500,
                'message' => __('Api.page_creation_failed'),
                'error' => $e->getMessage()
            ], 500);
        }
    }




    /**
     * Like or Unlike a Page.
     */
    public function likeUnlikePage(Request $request)
    {
        $request->validate([
            'page_id' => 'required|integer|exists:pages,id'
        ]);

        $loggedinUser = Auth::user();
        $userId = $loggedinUser->id;
        $pageId = $request->input('page_id');

        $like = PageLike::where('page_id', $pageId)->where('user_id', $userId)->first();
        $page = Page::find($pageId);
        if (empty($page)) {
            return response()->json([
                'status' => 400,
                'message' => __('Api.page_not_found'),
                'data' => 0
            ]);
        }
        if ($like) {
            $like->delete();
            Page::find($pageId)->decrement('likes_count');
            return response()->json([
                'status' => 200,
                'message' => __('Api.page_successfully_unliked'),
                'data' => 0
            ]);
        } else {
            PageLike::create(['page_id' => $pageId, 'user_id' => $userId]);
            Page::find($pageId)->increment('likes_count');
            $userdata = User::select('device_id', 'notification_setting')
                ->where('id', $page->user_id)
                ->first(); // Make sure to use first() to get a single result

            if (!empty($userdata) && $userId != $page->user_id) {
                // Decode the JSON column and access the 'notify_like' value
                $notify_liked_page = json_decode(str_replace("\xc2\xa0", ' ', $userdata->notification_setting))->notify_liked_page;
                if ($notify_liked_page == 1) {
                    Notification::create([
                        'from_user_id' => $userId,
                        'to_user_id' => $page->user_id,
                        'type' => 'page_like',
                        'text' => 'liked your page',
                        'page_id' => $page->id,
                    ]);
                    if (!empty($userdata->device_id)) {
                        sendFirebaseNotification($userdata->device_id, 'Page Liked ', $loggedinUser->username . ' liked your page');
                    }
                }
            }

            return response()->json([
                'status' => 200,
                'message' => __('Api.page_successfully_liked'),
                'data' => 1
            ]);
        }
    }

    /**
     * Get liked pages by the logged-in user.
     */
    public function getLikedPages()
    {
        $userId = Auth::id();
        $likedPages = PageLike::where('user_id', $userId)->with('page')->get();

        return response()->json([
            'status' => 200,
            'message' => __('Api.fetch_liked_pages_success'),
            'data' => PageResource::collection($likedPages)
        ], 200);
    }

    /**
     * Get details of a specific page.
     */
    public function getPageData(Request $request)
    {
        $request->validate(['page_id' => 'required|integer|exists:pages,id']);

        // Fetch the page with additional data if needed
        $page = Page::withCount('likes')->find($request->input('page_id'));

        if (!$page) {
            return response()->json([
                'status' => 404,
                'message' => __('Api.page_not_found'),
                'data' => null,
            ], 404);
        }



        // Optionally, you can include user-specific data, like if the user liked the page
        $userLiked = Auth::check() ? $page->likes()->where('user_id', Auth::id())->exists() : false;

        return response()->json([
            'status' => 200,
            'message' => __('Api.page_fetched_successfully'),
            'data' =>  new PageResource($page),

        ]);
    }


    /**
     * Delete a page.
     */
    public function deletePage(Request $request)
    {
        $request->validate(['page_id' => 'required|integer|exists:pages,id']);
        $pageModel = new Page();
        $page = $pageModel->find($request->input('page_id'));
        if ($page->user_id != Auth::id()) {
            return response()->json([
                'status' => 403,
                'message' => __('Api.not_allowed'),
            ], 403);
        }

        $pageModel->deletePage($page->id);

        return response()->json([
            'status' => 200,
            'message' => __('Api.page_deleted_successfully'),
        ], 200);
    }

    /**
     * Update page details.
     */
    public function updatePage(Request $request)
    {
        $validatedData = $request->validate([
            'page_id' => 'required|integer|exists:pages,id',
            'page_title' => 'nullable|string|min:5|max:50|regex:/^[a-zA-Z0-9 ]+$/',
            'page_description' => 'nullable|string|min:10',
            'page_category' => 'nullable|string',
            'website' => 'nullable|url',
            'avatar' => 'nullable|string',
            'cover' => 'nullable|string',
        ]);

        $userId = Auth::id();
        $page = Page::find($validatedData['page_id']);

        if (!$page) {
            return response()->json([
                'status' => 404,
                'message' => __('Api.page_not_found')
            ], 404);
        }

        if ($page->user_id !== $userId) {
            return response()->json([
                'status' => 403,
                'message' => __('Api.not_allowed')
            ], 403);
        }

        $updateData = array_filter($validatedData, function ($value) {
            return !is_null($value) && $value !== '';
        });

        if (empty($updateData)) {
            return response()->json([
                'status' => 400,
                'message' => __('Api.no_valid_data_provided')
            ], 400);
        }

        $page->update($updateData);

        return response()->json([
            'status' => 200,
            'message' => __('Api.page_updated_successfully'),
            'data' => new PageResource($page)
        ]);
    }

    public function getUsersWhoLikedPage(Request $request)
    {
        $validatedData = $request->validate([
            'page_id' => 'required|integer|exists:pages,id'
        ]);

        $pageId = $validatedData['page_id'];

        $users = \App\Models\User::whereHas('pageLikes', function ($query) use ($pageId) {
            $query->where('page_id', $pageId);
        })->get();

        if ($users->isEmpty()) {
            return response()->json([
                'status' => 400,
                'message' => __('Api.no_users_found'),
                'data' => []
            ]);
        }

        return response()->json([
            'status' => 200,
            'message' => __('Api.users_fetched_successfully'),
            'data' => UserResource::collection($users)
        ]);
    }

    /**
     * Search for pages based on a query.
     */
    public function search(Request $request)
    {
        $request->validate([
            'query' => 'required|string|min:1',
        ]);

        $searchQuery = $request->input('query');

        $pages = Page::where('active', true)
            ->where(function ($query) use ($searchQuery) {
                $query->where('page_title', 'like', "%{$searchQuery}%")
                    ->orWhere('page_description', 'like', "%{$searchQuery}%")
                    ->orWhere('page_username', 'like', "%{$searchQuery}%")
                    ->orWhere('page_category', 'like', "%{$searchQuery}%");
            })
            ->latest()
            ->get();

        return response()->json([
            'status' => 200,
            'message' => 'Pages fetched successfully.',
            'data' => PageResource::collection($pages),
        ]);
    }

    /**
     * Display a custom page by its slug.
     *
     * @param  string  $slug
     * @return \Illuminate\View\View|\Illuminate\Http\RedirectResponse
     */
    public function showCustomPage($slug)
    {
        $customPage = CustomPage::where('slug', $slug)
            ->where('active', true)
            ->first();

        if (!$customPage) {
            abort(404);
        }

        return view('front_end.pages.custom_page', compact('customPage'));
    }

    /**
     * Get suggested pages for the authenticated user
     */
    public function getSuggestedPages()
    {
        try {
            $userId = Auth::id();

            // Get pages that the user hasn't liked yet
            $suggestedPages = Page::whereNotIn('id', function ($query) use ($userId) {
                $query->select('page_id')
                    ->from('page_likes')
                    ->where('user_id', $userId);
            })
                ->where('user_id', '!=', $userId) // Exclude user's own pages
                ->withCount('likes')
                ->orderBy('likes_count', 'desc')
                ->limit(5)
                ->get();

            return response()->json([
                'success' => true,
                'pages' => $suggestedPages->map(function ($page) {
                    return [
                        'id' => $page->id,
                        'name' => $page->page_title,
                        'cover_image' => $page->page_cover_image,
                        'followers_count' => $page->likes_count,
                        'category' => $page->page_category
                    ];
                })
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to load suggested pages'
            ], 500);
        }
    }

    /**
     * Get page statistics
     */
    public function getPageStats()
    {
        try {
            $userId = Auth::id();

            $stats = [
                'total_pages' => Page::count(),
                'following_count' => PageLike::where('user_id', $userId)->count(),
                'verified_count' => Page::where('is_verified', true)->count(),
                'my_pages_count' => Page::where('user_id', $userId)->count(),
                'popular_count' => Page::where('likes_count', '>', 1000)->count(),
                'recent_count' => Page::where('created_at', '>=', now()->subDays(7))->count(),
            ];

            return response()->json([
                'status' => 200,
                'message' => 'Stats loaded successfully',
                'data' => $stats
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 500,
                'message' => 'Failed to load stats',
                'data' => []
            ], 500);
        }
    }
}
