<?php

namespace App\Http\Controllers\Api\Admin;

use App\Enums\ReservationStatus;
use App\Http\Controllers\Controller;
use App\Models\Listing;
use App\Models\Reservation;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class ReportController extends Controller
{
    /**
     * Reservation report
     */
    public function reservations(Request $request): JsonResponse
    {
        $fromDate = $request->get('from_date', now()->startOfMonth()->toDateString());
        $toDate = $request->get('to_date', now()->endOfMonth()->toDateString());

        // Summary
        $summary = Reservation::whereBetween('created_at', [$fromDate, $toDate])
            ->select(
                DB::raw('COUNT(*) as total_count'),
                DB::raw("SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed_count"),
                DB::raw("SUM(CASE WHEN status = 'cancelled' THEN 1 ELSE 0 END) as cancelled_count"),
                DB::raw("SUM(CASE WHEN status = 'completed' THEN total_amount ELSE 0 END) as total_revenue"),
                DB::raw("AVG(CASE WHEN status = 'completed' THEN total_amount ELSE NULL END) as avg_order_value"),
                DB::raw('SUM(guest_count) as total_guests')
            )
            ->first();

        // By status
        $byStatus = Reservation::whereBetween('created_at', [$fromDate, $toDate])
            ->select('status', DB::raw('COUNT(*) as count'), DB::raw('SUM(total_amount) as revenue'))
            ->groupBy('status')
            ->get();

        // Daily breakdown
        $daily = Reservation::whereBetween('created_at', [$fromDate, $toDate])
            ->select(
                DB::raw('DATE(created_at) as date'),
                DB::raw('COUNT(*) as count'),
                DB::raw('SUM(total_amount) as revenue')
            )
            ->groupBy(DB::raw('DATE(created_at)'))
            ->orderBy('date')
            ->get();

        // Top listings
        $topListings = Listing::withCount(['reservations' => function ($query) use ($fromDate, $toDate) {
            $query->whereBetween('created_at', [$fromDate, $toDate])
                ->where('status', ReservationStatus::COMPLETED);
        }])
            ->withSum(['reservations' => function ($query) use ($fromDate, $toDate) {
                $query->whereBetween('created_at', [$fromDate, $toDate])
                    ->where('status', ReservationStatus::COMPLETED);
            }], 'total_amount')
            ->having('reservations_count', '>', 0)
            ->orderByDesc('reservations_count')
            ->take(10)
            ->get(['id', 'title']);

        return response()->json([
            'period' => [
                'from' => $fromDate,
                'to' => $toDate,
            ],
            'summary' => $summary,
            'by_status' => $byStatus,
            'daily' => $daily,
            'top_listings' => $topListings,
        ]);
    }

    /**
     * Listing report
     */
    public function listings(Request $request): JsonResponse
    {
        $fromDate = $request->get('from_date', now()->startOfMonth()->toDateString());
        $toDate = $request->get('to_date', now()->endOfMonth()->toDateString());

        // Summary
        $summary = [
            'total' => Listing::count(),
            'new_in_period' => Listing::whereBetween('created_at', [$fromDate, $toDate])->count(),
            'active' => Listing::where('status', 'active')->count(),
            'pending' => Listing::where('status', 'pending')->count(),
            'total_views' => Listing::sum('view_count'),
        ];

        // By type
        $byType = Listing::join('listing_types', 'listings.listing_type_id', '=', 'listing_types.id')
            ->select('listing_types.name', DB::raw('COUNT(*) as count'))
            ->groupBy('listing_types.id', 'listing_types.name')
            ->get();

        // By city
        $byCity = Listing::join('cities', 'listings.city_id', '=', 'cities.id')
            ->join('provinces', 'cities.province_id', '=', 'provinces.id')
            ->select('provinces.name as province', 'cities.name as city', DB::raw('COUNT(*) as count'))
            ->groupBy('provinces.id', 'provinces.name', 'cities.id', 'cities.name')
            ->orderByDesc('count')
            ->take(20)
            ->get();

        // By status
        $byStatus = Listing::select('status', DB::raw('COUNT(*) as count'))
            ->groupBy('status')
            ->get();

        // Most viewed
        $mostViewed = Listing::with('city:id,name')
            ->orderByDesc('view_count')
            ->take(10)
            ->get(['id', 'title', 'city_id', 'view_count']);

        return response()->json([
            'period' => [
                'from' => $fromDate,
                'to' => $toDate,
            ],
            'summary' => $summary,
            'by_type' => $byType,
            'by_city' => $byCity,
            'by_status' => $byStatus,
            'most_viewed' => $mostViewed,
        ]);
    }

    /**
     * User report
     */
    public function users(Request $request): JsonResponse
    {
        $fromDate = $request->get('from_date', now()->startOfMonth()->toDateString());
        $toDate = $request->get('to_date', now()->endOfMonth()->toDateString());

        // Summary
        $summary = [
            'total' => User::count(),
            'new_in_period' => User::whereBetween('created_at', [$fromDate, $toDate])->count(),
            'customers' => User::where('role', 'customer')->count(),
            'boat_owners' => User::where('role', 'boat_owner')->count(),
            'active' => User::where('is_active', true)->count(),
        ];

        // By role
        $byRole = User::select('role', DB::raw('COUNT(*) as count'))
            ->groupBy('role')
            ->get();

        // Registration trend
        $registrationTrend = User::whereBetween('created_at', [$fromDate, $toDate])
            ->select(
                DB::raw('DATE(created_at) as date'),
                DB::raw('COUNT(*) as count')
            )
            ->groupBy(DB::raw('DATE(created_at)'))
            ->orderBy('date')
            ->get();

        // Top boat owners by reservations
        $topOwners = User::where('role', 'boat_owner')
            ->withCount(['listings' => function ($query) {
                $query->where('status', 'active');
            }])
            ->with(['listings' => function ($query) {
                $query->withCount('reservations');
            }])
            ->take(10)
            ->get(['id', 'name', 'email']);

        return response()->json([
            'period' => [
                'from' => $fromDate,
                'to' => $toDate,
            ],
            'summary' => $summary,
            'by_role' => $byRole,
            'registration_trend' => $registrationTrend,
            'top_owners' => $topOwners,
        ]);
    }
}
