<?php

namespace App\Http\Controllers\Backend;

use App\Models\Job;
use App\Models\Page;
use App\Models\Post;
use App\Models\User;
use App\Models\Event;
use App\Models\Group;
use App\Models\PostReport;
use App\Models\UserReport;
use App\Models\Notification;
use App\Models\ReportModule;
use Illuminate\Http\Request;
use App\Models\Marketplace\Product;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;


class ReportController extends Controller
{
    /**
     * Display a dashboard of reports
     *
     * @return \Illuminate\View\View
     */
    public function index()
    {
        $pendingUserReports = UserReport::with(['reportingUser', 'reportedUser'])
            ->pending()
            ->count();

        $pendingPostReports = PostReport::with(['user', 'post'])
            ->pending()
            ->count();

        $totalPendingReports = $pendingUserReports + $pendingPostReports;
        $totalResolvedReports = UserReport::resolved()->count() + PostReport::resolved()->count();
        $totalDismissedReports = UserReport::dismissed()->count() + PostReport::dismissed()->count();

        return view('admin.pages.reports.index', compact(
            'pendingUserReports',
            'pendingPostReports',
            'totalPendingReports',
            'totalResolvedReports',
            'totalDismissedReports'
        ));
    }

    /**
     * Display a list of user reports
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\View\View
     */
    public function userReports(Request $request)
    {
        $status = $request->input('status', 'pending');

        $reports = UserReport::with(['reportingUser', 'reportedUser'])
            ->when($status === 'pending', function ($query) {
                return $query->pending();
            })
            ->when($status === 'resolved', function ($query) {
                return $query->resolved();
            })
            ->when($status === 'dismissed', function ($query) {
                return $query->dismissed();
            })
            ->latest()
            ->paginate(15);

        // Fetch user reports if needed
        $userReports = UserReport::all(); // Adjust this query as needed

        // Get count for pending reports
        $pendingReportsCount = UserReport::pending()->count();
        $resolvedReportsCount = UserReport::resolved()->count();
        $dismissedReportsCount = UserReport::dismissed()->count();


        return view('admin.pages.reports.user-reports', compact('reports', 'status', 'pendingReportsCount', 'resolvedReportsCount', 'dismissedReportsCount', 'userReports'));
    }

    /**
     * Display a list of post reports
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\View\View
     */
    public function postReports(Request $request)
    {
        $status = $request->input('status', 'pending');

        $reports = PostReport::with(['user', 'post'])
            ->when($status === 'pending', function ($query) {
                return $query->pending();
            })
            ->when($status === 'resolved', function ($query) {
                return $query->resolved();
            })
            ->when($status === 'dismissed', function ($query) {
                return $query->dismissed();
            })
            ->latest('created_at')
            ->paginate(15);

        // Get count for pending, resolved, and dismissed post reports
        $pendingPostReportsCount = PostReport::pending()->count();
        $resolvedPostReportsCount = PostReport::resolved()->count();
        $dismissedPostReportsCount = PostReport::dismissed()->count();
        $postReports = PostReport::all();

        return view('admin.pages.reports.post-reports', compact('reports', 'status', 'pendingPostReportsCount', 'resolvedPostReportsCount', 'dismissedPostReportsCount', 'postReports'));
    }

    /**
     * Display a list of module reports (groups, pages, products, events, jobs).
     */
    public function moduleReports(Request $request)
    {
        $statusMap = $this->moduleStatusMap();
        $statusFilter = $request->input('status', 'pending');

        if (!array_key_exists($statusFilter, $statusMap)) {
            $statusFilter = 'pending';
        }

        $reportsQuery = ReportModule::with('reporter')->latest('created_at');

        if ($statusFilter !== 'all' && isset($statusMap[$statusFilter])) {
            $reportsQuery->where('status', $statusMap[$statusFilter]);
        }

        $reports = $reportsQuery->paginate(20)->withQueryString();

        $reports->getCollection()->transform(function (ReportModule $report) {
            $report->module_route = $this->resolveModuleRoute($report);
            return $report;
        });

        $counts = [
            'pending' => ReportModule::pending()->count(),
            'resolved' => ReportModule::resolved()->count(),
            'dismissed' => ReportModule::dismissed()->count(),
            'total' => ReportModule::count(),
        ];

        return view('admin.pages.reports.module-reports', [
            'reports' => $reports,
            'statusFilter' => $statusFilter,
            'statusLabels' => $this->moduleStatusLabels(),
            'counts' => $counts,
        ]);
    }

    /**
     * Show detail for a module report.
     */
    public function showModuleReport($id)
    {
        $report = ReportModule::with('reporter')->findOrFail($id);
        $report->module_route = $this->resolveModuleRoute($report);

        $relatedReports = ReportModule::with('reporter')
            ->where('module_name', $report->module_name)
            ->where('module_id', $report->module_id)
            ->where('id', '!=', $report->id)
            ->latest('created_at')
            ->limit(10)
            ->get()
            ->transform(function (ReportModule $related) {
                $related->module_route = $this->resolveModuleRoute($related);
                return $related;
            });

        return view('admin.pages.reports.module-report-detail', [
            'report' => $report,
            'relatedReports' => $relatedReports,
        ]);
    }

    /**
     * Delete a module report.
     */
    public function deleteModuleReport($id)
    {
        $report = ReportModule::findOrFail($id);
        $report->delete();

        return redirect()->route('admin.reports.module-reports')->with('success', 'Report deleted successfully.');
    }

    /**
     * Handle approve / reject / delete actions for module reports.
     */
    public function moduleAction(Request $request)
    {
        $data = $request->validate([
            'report_id' => ['required', 'integer', 'exists:report_modules,id'],
            'action' => ['required', 'in:approve,reject,delete'],
        ]);

        $report = ReportModule::findOrFail($data['report_id']);
        $action = $data['action'];
        $message = null;

        if ($action === 'approve') {
            if ($report->module_name == 'page') {
                $pageModel = new Page();
                $pageModel->deletePage($report->module_id);
            } elseif ($report->module_name == 'group') {
                $groupModel = new Group();
                $groupModel->deletGroup($report->module_id);
            } elseif ($report->module_name == 'product') {
                $groupModel = new Product();
                $groupModel->deleteProduct($report->module_id);
            } elseif ($report->module_name == 'event') {
                $groupModel = new Event();
                $groupModel->deleteEvent($report->module_id);
            } elseif ($report->module_name == 'job') {
                $groupModel = new Job();
                $groupModel->deleteJob($report->module_id);
            }

            if ($report) {
                try {
                    $report->delete();
                } catch (\Throwable $e) {
                    return redirect()
                        ->back()
                        ->withErrors(['approve' => 'Failed to remove the reported module: ' . $e->getMessage()]);
                }
            }

            $report->status = ReportModule::STATUS_RESOLVED;
            $report->save();
            $message = 'Module report approved successfully.';
        } elseif ($action === 'reject') {
            Notification::create([
                'from_user_id' => Auth::id() ?? 1,
                'to_user_id' => $report->user_id,
                'type' => 'Admin-Notification',
                'text' => 'Module report is rejected by admin',
            ]);

            $report->status = ReportModule::STATUS_DISMISSED;
            $report->save();
            $message = 'Module report rejected.';
        } elseif ($action === 'delete') {
            $report->delete();
            $message = 'Module report deleted.';
        }

        return redirect()
            ->route('admin.reports.module-reports')
            ->with('success', $message ?? 'Module report action completed.');
    }

    /**
     * Show details of a user report
     *
     * @param  int  $id
     * @return \Illuminate\View\View
     */
    public function showUserReport($id)
    {
        $report = UserReport::with(['reportingUser', 'reportedUser'])
            ->findOrFail($id);

        // Get other reports against this user
        $otherReports = UserReport::where('report_user_id', $report->report_user_id)
            ->where('id', '!=', $report->id)
            ->with('reportingUser')
            ->latest()
            ->limit(5)
            ->get();

        // Get count of all submitted reports
        $reportsSubmittedCount = UserReport::count(); // This will give you the total count of submitted reports

        // Fetch user reports if needed
        $userReports = UserReport::all(); // Adjust this query as needed


        return view('admin.pages.reports.user-report-detail', compact('report', 'otherReports', 'userReports', 'reportsSubmittedCount'));
    }

    /**
     * Show details of a post report
     *
     * @param  int  $id
     * @return \Illuminate\View\View
     */
    public function showPostReport($id)
    {
        $report = PostReport::with(['user', 'post', 'post.user'])
            ->findOrFail($id);

        // Get other reports on this post
        $otherReports = PostReport::where('post_id', $report->post_id)
            ->where('id', '!=', $report->id)
            ->with('user')
            ->latest('created_at')
            ->limit(5)
            ->get();
        $postReports = PostReport::all();
        $reportsSubmittedCount = PostReport::count();

        return view('admin.pages.reports.post-report-detail', compact('report', 'otherReports', 'postReports', 'reportsSubmittedCount'));
    }

    /**
     * Update the status of a user report
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function updateUserReportStatus(Request $request, $id)
    {
        $request->validate([
            'status' => 'required|in:pending,resolved,dismissed',
            'action' => 'nullable|in:block,delete,none',
        ]);

        $report = UserReport::findOrFail($id);
        $report->status = $request->status;
        $report->save();

        // Take action on the reported user if requested
        if ($request->action !== 'none' && $request->action) {
            $user = User::find($report->report_user_id);

            if ($user) {
                if ($request->action === 'block') {
                    $user->blocked = true;
                    $user->save();
                } elseif ($request->action === 'delete') {
                    $user->delete();
                }
            }
        }

        return redirect()->route('admin.reports.user-reports')
            ->with('success', 'User report updated successfully.');
    }

    /**
     * Update the status of a post report
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function updatePostReportStatus(Request $request, $id)
    {
        $request->validate([
            'status' => 'required|in:pending,resolved,dismissed',
            'action' => 'nullable|in:delete,none',
        ]);

        $report = PostReport::findOrFail($id);
        $report->status = $request->status;
        $report->save();

        // Take action on the reported post if requested
        if ($request->action !== 'none' && $request->action) {
            $post = Post::find($report->post_id);

            if ($post && $request->action === 'delete') {
                $post->delete();
            }
        }

        return redirect()->route('admin.reports.post-reports')
            ->with('success', 'Post report updated successfully.');
    }

    /**
     * Delete a user report
     *
     * @param  int  $id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function deleteUserReport($id)
    {
        $report = UserReport::findOrFail($id);
        $report->delete();

        return redirect()->route('admin.reports.user-reports')
            ->with('success', 'User report deleted successfully.');
    }

    /**
     * Delete a post report
     *
     * @param  int  $id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function deletePostReport($id)
    {
        $report = PostReport::findOrFail($id);
        $report->delete();

        return redirect()->route('admin.reports.post-reports')
            ->with('success', 'Post report deleted successfully.');
    }

    /**
     * Update all reports for a specific user to resolved status
     *
     * @param  int  $userId
     * @return \Illuminate\Http\RedirectResponse
     */
    public function resolveAllUserReports($userId)
    {
        UserReport::where('report_user_id', $userId)
            ->update(['status' => 'resolved']);

        return redirect()->back()
            ->with('success', 'All reports for this user have been resolved.');
    }

    /**
     * Update all reports for a specific post to resolved status
     *
     * @param  int  $postId
     * @return \Illuminate\Http\RedirectResponse
     */
    public function resolveAllPostReports($postId)
    {
        PostReport::where('post_id', $postId)
            ->update(['status' => 'resolved']);

        return redirect()->back()
            ->with('success', 'All reports for this post have been resolved.');
    }

    /**
     * Map readable status keys to database values.
     *
     * @return array<string, int|null>
     */
    protected function moduleStatusMap(): array
    {
        return [
            'all' => null,
            'pending' => ReportModule::STATUS_PENDING,
            'resolved' => ReportModule::STATUS_RESOLVED,
            'dismissed' => ReportModule::STATUS_DISMISSED,
        ];
    }

    /**
     * Status labels keyed by their filter keys.
     */
    protected function moduleStatusLabels(bool $includeAll = true): array
    {
        $labels = [
            'pending' => ReportModule::STATUS_LABELS[ReportModule::STATUS_PENDING],
            'resolved' => ReportModule::STATUS_LABELS[ReportModule::STATUS_RESOLVED],
            'dismissed' => ReportModule::STATUS_LABELS[ReportModule::STATUS_DISMISSED],
        ];

        if ($includeAll) {
            return ['all' => 'All'] + $labels;
        }

        return $labels;
    }

    /**
     * Resolve admin route for a reported module.
     */
    protected function resolveModuleRoute(ReportModule $report): ?string
    {
        if (!$report->module_id) {
            return null;
        }

        if (!$report->module_record) {
            return null;
        }

        try {
            return match ($report->module_name) {
                'group' => route('admin.groups.show', $report->module_id),
                'page' => route('admin.pages.show', $report->module_id),
                'product' => route('admin.marketplace.products.show', $report->module_id),
                'event' => route('admin.events.show', $report->module_id),
                'job' => route('admin.jobs.show', $report->module_id),
                default => null,
            };
        } catch (\Throwable $e) {
            return null;
        }
    }
}
