<?php

namespace Database\Seeders;

use App\Models\User;
use App\Models\Listing;
use App\Models\Booking;
use App\Models\Review;
use App\Services\BadgeService;
use Illuminate\Database\Seeder;
use Faker\Factory as Faker;

class ReviewsSeeder extends Seeder
{
    public function run(): void
    {
        $faker = Faker::create();

        // Get all listings
        $listings = Listing::all();

        if ($listings->isEmpty()) {
            $this->command->error('No listings found. Please create listings first.');
            return;
        }

        // Get all users (potential reviewers)
        $users = User::where('role', 'user')->get();

        // Calculate how many users we need for 100 reviews
        $targetReviews = 100;
        $minUsersNeeded = (int) ceil($targetReviews / $listings->count());

        // Create additional users if needed
        if ($users->count() < $minUsersNeeded) {
            $usersToCreate = $minUsersNeeded - $users->count() + 5; // Add 5 extra for buffer
            $this->command->warn('Need ' . $usersToCreate . ' more users to create ' . $targetReviews . ' reviews...');

            $existingCount = User::where('email', 'LIKE', 'reviewer%@example.com')->count();

            for ($i = 1; $i <= $usersToCreate; $i++) {
                $users->push(User::create([
                    'name' => $faker->name(),
                    'email' => 'reviewer' . ($existingCount + $i) . '@example.com',
                    'password' => bcrypt('password'),
                    'role' => 'user',
                    'email_verified_at' => now(),
                ]));
            }

            $this->command->info('Created ' . $usersToCreate . ' additional users.');
        }

        $comments = [
            'Excellent experience! The place was exactly as described. Highly recommend!',
            'Amazing host and beautiful property. Would definitely stay here again.',
            'Perfect location and very clean. The host was very responsive and helpful.',
            'Outstanding service! Everything was perfect from start to finish.',
            'Loved our stay! The amenities were great and the host went above and beyond.',
            'Fantastic place! Very comfortable and well-maintained. Five stars!',
            'Wonderful experience. The property exceeded our expectations in every way.',
            'Superb accommodation! Clean, modern, and in a great location.',
            'Absolutely loved it! The host was amazing and the place was spotless.',
            'Incredible stay! Would highly recommend to anyone looking for quality accommodation.',
            'Perfect getaway spot. Everything was top-notch and the host was very welcoming.',
            'Great experience from booking to checkout. Highly satisfied!',
            'Beautiful property with excellent amenities. The host made us feel very welcome.',
            'Amazing stay! Clean, comfortable, and great value for money.',
            'Exceeded all expectations! The place was beautiful and the host was fantastic.',
            'Wonderful property in a prime location. Everything was perfect!',
            'Outstanding! The attention to detail was impressive. Highly recommend!',
            'Perfect place for our vacation. Clean, spacious, and well-equipped.',
            'Excellent host and gorgeous property. Would love to return!',
            'Fantastic experience! Everything was exactly as advertised and more.',
        ];

        $reviewCount = 0;

        $this->command->info('Generating ' . $targetReviews . ' reviews with ratings 4.5 and above...');

        while ($reviewCount < $targetReviews) {
            $listing = $listings->random();
            $user = $users->random();

            // Check if this user already reviewed this listing
            $existingReview = Review::where('listing_id', $listing->id)
                ->where('user_id', $user->id)
                ->first();

            if ($existingReview) {
                continue; // Skip if already reviewed
            }

            // Generate rating between 4.5 and 5.0 (90% 5-star, 10% 4-star for average > 4.5)
            $rating = $faker->randomElement([5, 5, 5, 5, 5, 5, 5, 5, 5, 4]);

            // Create booking for this review
            $booking = Booking::create([
                'listing_id' => $listing->id,
                'user_id' => $user->id,
                'check_in' => $faker->dateTimeBetween('-6 months', '-1 month'),
                'check_out' => $faker->dateTimeBetween('-1 month', 'now'),
                'guests' => $faker->numberBetween(1, 4),
                'total_price' => $faker->randomFloat(2, 100, 1000),
                'status' => 'completed',
            ]);

            // Create review
            Review::create([
                'listing_id' => $listing->id,
                'user_id' => $user->id,
                'booking_id' => $booking->id,
                'rating' => $rating,
                'comment' => $faker->randomElement($comments),
                'images' => null,
                'created_at' => $faker->dateTimeBetween('-6 months', 'now'),
            ]);

            $reviewCount++;

            if ($reviewCount % 10 == 0) {
                $this->command->info('Created ' . $reviewCount . ' reviews...');
            }
        }

        $this->command->info('Successfully created ' . $reviewCount . ' reviews!');

        // Calculate badges for all hosts
        $this->command->info('Calculating host badges...');

        $badgeService = app(BadgeService::class);
        $hosts = User::where('role', 'host')->orWhere('role', 'admin')->get();

        foreach ($hosts as $host) {
            if ($host->listings()->count() > 0) {
                $badgeService->updateUserBadges($host);
                $this->command->info('Updated badges for host: ' . $host->name);
            }
        }

        $this->command->info('Badge calculation completed!');
    }
}
