<?php

namespace Database\Seeders;

use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

class DatabaseSeeder extends Seeder
{
    public function run()
    {
        $this->seedUsers();
        $this->seedGeography();
        $this->seedCatalog();
        $this->seedPricing();
        $this->seedCms();
        $this->seedRapidSewaAdmin();
    }

    private function seedUsers(): void
    {
        User::updateOrCreate(
            ['phone' => '9999999999'],
            [
                'uuid' => (string) Str::uuid(),
                'name' => 'Super Admin',
                'email' => 'admin@pronto.local',
                'phone_country_code' => '+91',
                'role' => 'super_admin',
                'status' => 'active',
                'password' => Hash::make('admin12345'),
            ]
        );

        User::updateOrCreate(
            ['phone' => '8888888888'],
            [
                'uuid' => (string) Str::uuid(),
                'name' => 'Demo Customer',
                'email' => 'customer@pronto.local',
                'phone_country_code' => '+91',
                'role' => 'customer',
                'status' => 'active',
                'password' => Hash::make('customer123'),
            ]
        );
    }

    private function seedGeography(): void
    {
        $cities = [
            ['name' => 'Gurugram', 'slug' => 'gurugram', 'state' => 'Haryana'],
            ['name' => 'Delhi', 'slug' => 'delhi', 'state' => 'Delhi'],
            ['name' => 'Noida', 'slug' => 'noida', 'state' => 'Uttar Pradesh'],
            ['name' => 'Bengaluru', 'slug' => 'bengaluru', 'state' => 'Karnataka'],
            ['name' => 'Mumbai', 'slug' => 'mumbai', 'state' => 'Maharashtra'],
        ];

        foreach ($cities as $city) {
            DB::table('cities')->updateOrInsert(['slug' => $city['slug']], array_merge($city, [
                'country' => 'India',
                'timezone' => 'Asia/Kolkata',
                'status' => 'active',
                'created_at' => now(),
                'updated_at' => now(),
            ]));
        }

        $gurugram = DB::table('cities')->where('slug', 'gurugram')->first();
        $localities = ['Sector 14', 'Sector 29', 'DLF Phase 1', 'Sohna Road'];

        foreach ($localities as $name) {
            DB::table('localities')->updateOrInsert(
                ['city_id' => $gurugram->id, 'slug' => Str::slug($name)],
                [
                    'name' => $name,
                    'pincode' => '122001',
                    'status' => 'active',
                    'created_at' => now(),
                    'updated_at' => now(),
                ]
            );
        }

        DB::table('hubs')->updateOrInsert(
            ['city_id' => $gurugram->id, 'name' => 'Gurugram Central Hub'],
            [
                'address' => 'Central operations hub',
                'lat' => 28.4595,
                'lng' => 77.0266,
                'status' => 'active',
                'created_at' => now(),
                'updated_at' => now(),
            ]
        );

        DB::table('service_areas')->updateOrInsert(
            ['city_id' => $gurugram->id, 'name' => 'Gurugram Active Zone'],
            [
                'is_instant_enabled' => true,
                'is_scheduled_enabled' => true,
                'is_recurring_enabled' => true,
                'status' => 'active',
                'created_at' => now(),
                'updated_at' => now(),
            ]
        );
    }

    private function seedCatalog(): void
    {
        $categories = [
            ['name' => 'Hourly Help', 'slug' => 'hourly-help', 'sort_order' => 1],
            ['name' => 'Cleaning', 'slug' => 'cleaning', 'sort_order' => 2],
            ['name' => 'Kitchen', 'slug' => 'kitchen', 'sort_order' => 3],
            ['name' => 'Laundry', 'slug' => 'laundry', 'sort_order' => 4],
            ['name' => 'Express', 'slug' => 'express', 'sort_order' => 5],
        ];

        foreach ($categories as $category) {
            DB::table('service_categories')->updateOrInsert(
                ['slug' => $category['slug']],
                array_merge($category, ['status' => 'active', 'created_at' => now(), 'updated_at' => now()])
            );
        }

        $skillMap = [
            'cleaning' => 'Cleaning',
            'kitchen-prep' => 'Kitchen Prep',
            'laundry' => 'Laundry',
            'plant-care' => 'Plant Care',
            'car-cleaning' => 'Car Surface Cleaning',
        ];

        foreach ($skillMap as $slug => $name) {
            DB::table('skills')->updateOrInsert(
                ['slug' => $slug],
                ['name' => $name, 'status' => 'active', 'created_at' => now(), 'updated_at' => now()]
            );
        }

        $services = [
            ['Hourly Bookings', 'hourly-bookings', 'hourly-help', 'hourly', 60, 199, 'cleaning'],
            ['Bathroom Cleaning', 'bathroom-cleaning', 'cleaning', 'task', 60, 249, 'cleaning'],
            ['Fridge Cleaning', 'fridge-cleaning', 'cleaning', 'task', 45, 199, 'cleaning'],
            ['Packing or Unpacking', 'packing-unpacking', 'hourly-help', 'hourly', 60, 229, 'cleaning'],
            ['Utensils', 'utensils', 'kitchen', 'task', 45, 149, 'kitchen-prep'],
            ['Kitchen Prep', 'kitchen-prep', 'kitchen', 'task', 60, 249, 'kitchen-prep'],
            ['Dusting and Wiping', 'dusting-wiping', 'cleaning', 'task', 60, 199, 'cleaning'],
            ['Sweeping and Mopping', 'sweeping-mopping', 'cleaning', 'task', 60, 199, 'cleaning'],
            ['Pre-Party Express Clean', 'pre-party-express-clean', 'express', 'express', 90, 399, 'cleaning'],
            ['Complete Wardrobe Cleaning', 'wardrobe-cleaning', 'cleaning', 'task', 90, 349, 'cleaning'],
            ['After-Party Express Clean', 'after-party-express-clean', 'express', 'express', 120, 499, 'cleaning'],
            ['Ironing and Folding', 'ironing-folding', 'laundry', 'task', 60, 199, 'laundry'],
            ['Window Cleaning', 'window-cleaning', 'cleaning', 'task', 60, 249, 'cleaning'],
            ['Laundry', 'laundry', 'laundry', 'task', 60, 249, 'laundry'],
            ['Kitchen Cleaning', 'kitchen-cleaning', 'kitchen', 'task', 90, 349, 'cleaning'],
            ['Balcony Cleaning', 'balcony-cleaning', 'cleaning', 'task', 45, 179, 'cleaning'],
            ['Fan Cleaning', 'fan-cleaning', 'cleaning', 'task', 45, 149, 'cleaning'],
            ['Kitchen Cabinet Cleaning', 'kitchen-cabinet-cleaning', 'kitchen', 'task', 90, 349, 'cleaning'],
            ['Plant Care', 'plant-care', 'hourly-help', 'task', 45, 149, 'plant-care'],
            ['Car Surface Cleaning', 'car-surface-cleaning', 'cleaning', 'task', 45, 199, 'car-cleaning'],
        ];

        foreach ($services as [$name, $slug, $categorySlug, $type, $duration, $price, $skillSlug]) {
            $category = DB::table('service_categories')->where('slug', $categorySlug)->first();
            DB::table('services')->updateOrInsert(
                ['slug' => $slug],
                [
                    'category_id' => $category->id,
                    'name' => $name,
                    'description' => $name . ' service with trained house-help professional.',
                    'content_html' => '<h3>' . e($name) . '</h3><p>Professional RapidSewa expert will complete this service with checklist, quality control, and customer rating.</p>',
                    'icon_path' => 'icons/service.png',
                    'image_slider_json' => json_encode(['images/services/default-1.jpg', 'images/services/default-2.jpg']),
                    'service_type' => $type,
                    'default_duration_minutes' => $duration,
                    'min_duration_minutes' => 30,
                    'max_duration_minutes' => 240,
                    'mrp_price' => $price + 99,
                    'sale_price' => $price,
                    'hourly_rate' => $type === 'hourly' ? $price : null,
                    'is_hourly_enabled' => $type === 'hourly',
                    'is_stackable' => true,
                    'requires_photos' => in_array($type, ['express', 'task'], true),
                    'status' => 'active',
                    'created_at' => now(),
                    'updated_at' => now(),
                ]
            );

            $service = DB::table('services')->where('slug', $slug)->first();
            $skill = DB::table('skills')->where('slug', $skillSlug)->first();
            DB::table('service_skill_requirements')->updateOrInsert(
                ['service_id' => $service->id, 'skill_id' => $skill->id],
                ['required_level' => 'trained', 'created_at' => now(), 'updated_at' => now()]
            );

            foreach (['Before-service check', 'Task completed', 'Area cleaned and verified'] as $index => $title) {
                DB::table('service_checklist_items')->updateOrInsert(
                    ['service_id' => $service->id, 'title' => $title],
                    [
                        'type' => $index === 0 ? 'pro_visible' : 'completion_required',
                        'is_required' => true,
                        'sort_order' => $index + 1,
                        'created_at' => now(),
                        'updated_at' => now(),
                    ]
                );
            }
        }
    }

    private function seedPricing(): void
    {
        $priceBookId = DB::table('price_books')->updateOrInsert(
            ['name' => 'Default India Price Book'],
            ['status' => 'active', 'starts_at' => now(), 'created_at' => now(), 'updated_at' => now()]
        );

        $priceBook = DB::table('price_books')->where('name', 'Default India Price Book')->first();

        $prices = [
            'hourly-bookings' => 199,
            'bathroom-cleaning' => 249,
            'fridge-cleaning' => 199,
            'packing-unpacking' => 229,
            'utensils' => 149,
            'kitchen-prep' => 249,
            'dusting-wiping' => 199,
            'sweeping-mopping' => 199,
            'pre-party-express-clean' => 399,
            'wardrobe-cleaning' => 349,
            'after-party-express-clean' => 499,
            'ironing-folding' => 199,
            'window-cleaning' => 249,
            'laundry' => 249,
            'kitchen-cleaning' => 349,
            'balcony-cleaning' => 179,
            'fan-cleaning' => 149,
            'kitchen-cabinet-cleaning' => 349,
            'plant-care' => 149,
            'car-surface-cleaning' => 199,
        ];

        foreach ($prices as $slug => $price) {
            $service = DB::table('services')->where('slug', $slug)->first();
            if (! $service) {
                continue;
            }

            DB::table('service_prices')->updateOrInsert(
                ['price_book_id' => $priceBook->id, 'service_id' => $service->id, 'variant_id' => null],
                [
                    'base_price' => $price,
                    'currency' => 'INR',
                    'duration_minutes' => $service->default_duration_minutes,
                    'created_at' => now(),
                    'updated_at' => now(),
                ]
            );
        }

        DB::table('fee_rules')->updateOrInsert(
            ['name' => 'Convenience Fee'],
            ['fee_type' => 'convenience', 'calculation_type' => 'fixed', 'value' => 25, 'status' => 'active', 'created_at' => now(), 'updated_at' => now()]
        );

        DB::table('fee_rules')->updateOrInsert(
            ['name' => 'Pro Welfare Fee'],
            ['fee_type' => 'pro_welfare', 'calculation_type' => 'percent', 'value' => 2, 'status' => 'active', 'created_at' => now(), 'updated_at' => now()]
        );

        DB::table('tax_rules')->updateOrInsert(
            ['name' => 'GST 18%'],
            ['tax_type' => 'gst', 'percent' => 18, 'hsn_sac' => '998533', 'status' => 'active', 'created_at' => now(), 'updated_at' => now()]
        );

        DB::table('coupons')->updateOrInsert(
            ['code' => 'WELCOME50'],
            [
                'description' => 'Flat Rs 50 off on first booking',
                'discount_type' => 'fixed',
                'discount_value' => 50,
                'max_discount' => 50,
                'min_order_amount' => 199,
                'starts_at' => now()->subDay(),
                'ends_at' => now()->addYear(),
                'usage_limit' => 10000,
                'per_user_limit' => 1,
                'status' => 'active',
                'created_at' => now(),
                'updated_at' => now(),
            ]
        );
    }

    private function seedCms(): void
    {
        $pages = [
            'terms' => ['Terms and Conditions', '<p>Platform terms for customer and professional services.</p>'],
            'privacy' => ['Privacy Policy', '<p>Privacy policy covering account, booking, payment, and support data.</p>'],
            'cancellation-policy' => ['Cancellation Policy', '<p>Instant, scheduled, and recurring bookings follow the configured refund policy.</p>'],
            'delete-account' => ['Delete Account', '<p>Customers can request account deletion from the app.</p>'],
        ];

        foreach ($pages as $slug => [$title, $body]) {
            DB::table('cms_pages')->updateOrInsert(
                ['slug' => $slug],
                ['title' => $title, 'body_html' => $body, 'version' => '1.0', 'status' => 'published', 'published_at' => now(), 'created_at' => now(), 'updated_at' => now()]
            );
        }

        $faqs = [
            ['How fast can I book?', 'Instant bookings can start assignment after payment and availability check.'],
            ['Can I schedule later?', 'Yes, choose scheduled booking and select a slot.'],
            ['Can I make recurring bookings?', 'Yes, recurring plans can be paused, resumed, or cancelled.'],
            ['How do Pros get paid?', 'Professional earnings are tracked and paid through payout batches.'],
        ];

        foreach ($faqs as $index => [$question, $answer]) {
            DB::table('faqs')->updateOrInsert(
                ['question' => $question],
                ['answer' => $answer, 'category' => 'general', 'sort_order' => $index + 1, 'status' => 'active', 'created_at' => now(), 'updated_at' => now()]
            );
        }

        DB::table('app_configs')->updateOrInsert(
            ['key' => 'booking_rules'],
            [
                'value_json' => json_encode([
                    'quote_expiry_minutes' => 15,
                    'instant_assignment_delay_minutes' => 15,
                    'scheduled_full_refund_before_hours' => 6,
                    'scheduled_half_refund_before_hours' => 3,
                    'recurring_free_cancel_before_hours' => 3,
                ]),
                'description' => 'Operational booking and refund rules.',
                'created_at' => now(),
                'updated_at' => now(),
            ]
        );

        foreach (['otp', 'booking_confirmed', 'pro_assigned', 'refund_processed', 'payout_processed'] as $key) {
            DB::table('notification_templates')->updateOrInsert(
                ['channel' => 'sms', 'template_key' => $key],
                ['body' => ucfirst(str_replace('_', ' ', $key)) . ' notification.', 'status' => 'active', 'created_at' => now(), 'updated_at' => now()]
            );
        }
    }

    private function seedRapidSewaAdmin(): void
    {
        $modules = [
            'dashboard',
            'staff',
            'zone',
            'customers',
            'vendors',
            'bookings',
            'marketing',
            'services',
            'hourly',
            'tracking',
            'banners',
            'onboarding',
            'complaints',
            'sos',
            'faq',
            'templates',
            'reports',
            'cms',
            'payment',
            'settings',
            'support',
            'languages',
        ];

        DB::table('admin_roles')->updateOrInsert(
            ['slug' => 'super-admin'],
            ['name' => 'Super Admin', 'description' => 'Full RapidSewa admin access.', 'status' => 'active', 'created_at' => now(), 'updated_at' => now()]
        );

        $role = DB::table('admin_roles')->where('slug', 'super-admin')->first();

        foreach ($modules as $module) {
            foreach (['view', 'create', 'edit', 'delete'] as $action) {
                $slug = $module . '.' . $action;
                DB::table('admin_permissions')->updateOrInsert(
                    ['slug' => $slug],
                    ['module' => $module, 'name' => ucfirst($module) . ' ' . ucfirst($action), 'created_at' => now(), 'updated_at' => now()]
                );
                $permission = DB::table('admin_permissions')->where('slug', $slug)->first();
                DB::table('admin_role_permissions')->updateOrInsert(
                    ['admin_role_id' => $role->id, 'admin_permission_id' => $permission->id],
                    ['created_at' => now(), 'updated_at' => now()]
                );
            }
        }

        $admin = User::where('phone', '9999999999')->first();
        if ($admin) {
            DB::table('staff_profiles')->updateOrInsert(
                ['user_id' => $admin->id],
                [
                    'admin_role_id' => $role->id,
                    'employee_code' => 'RS-ADMIN-001',
                    'department' => 'Management',
                    'designation' => 'Super Admin',
                    'status' => 'active',
                    'created_at' => now(),
                    'updated_at' => now(),
                ]
            );
        }

        $customer = User::where('phone', '8888888888')->first();
        if ($customer) {
            DB::table('customer_addresses')->updateOrInsert(
                ['user_id' => $customer->id, 'label' => 'Home'],
                [
                    'city_id' => DB::table('cities')->where('slug', 'gurugram')->value('id'),
                    'address_line_1' => 'Demo RapidSewa customer address',
                    'pincode' => '122001',
                    'lat' => 28.4595,
                    'lng' => 77.0266,
                    'is_default' => true,
                    'created_at' => now(),
                    'updated_at' => now(),
                ]
            );
        }

        $vendorUser = User::updateOrCreate(
            ['phone' => '7777777777'],
            [
                'uuid' => (string) Str::uuid(),
                'name' => 'Demo Expert',
                'email' => 'expert@rapidsewa.local',
                'phone_country_code' => '+91',
                'role' => 'professional',
                'status' => 'active',
                'password' => Hash::make('expert123'),
            ]
        );

        DB::table('professionals')->updateOrInsert(
            ['user_id' => $vendorUser->id],
            [
                'pro_code' => 'RS-PRO-001',
                'vendor_business_name' => 'RapidSewa Demo Expert',
                'city_id' => DB::table('cities')->where('slug', 'gurugram')->value('id'),
                'onboarding_status' => 'active',
                'employment_type' => 'partner',
                'rating_avg' => 4.8,
                'completed_jobs_count' => 38,
                'status' => 'active',
                'online_status' => 'online',
                'wallet_balance' => 2450,
                'plan_name' => 'Gold Expert Plan',
                'services_done_count' => 38,
                'bank_name' => 'Demo Bank',
                'bank_account_number' => 'XXXXXX1234',
                'bank_ifsc' => 'DEMO0001234',
                'full_address' => 'RapidSewa vendor demo address',
                'document_status' => 'verified',
                'created_at' => now(),
                'updated_at' => now(),
            ]
        );

        DB::table('deals')->updateOrInsert(
            ['title' => 'Weekend Cleaning Deal'],
            ['description' => 'Special offer for weekend cleaning services.', 'deal_type' => 'percent', 'value' => 15, 'status' => 'active', 'created_at' => now(), 'updated_at' => now()]
        );

        DB::table('service_packages')->updateOrInsert(
            ['name' => 'Monthly Home Care Pack'],
            ['description' => 'Recurring home care service package.', 'mrp_price' => 2499, 'sale_price' => 1999, 'validity_days' => 30, 'status' => 'active', 'created_at' => now(), 'updated_at' => now()]
        );

        DB::table('app_banners')->updateOrInsert(
            ['title' => 'Book RapidSewa Expert Today'],
            ['subtitle' => 'Instant, scheduled, and hourly services.', 'image_path' => 'banners/home-hero.jpg', 'deep_link' => 'rapidsewa://services', 'sort_order' => 1, 'status' => 'active', 'created_at' => now(), 'updated_at' => now()]
        );

        foreach ([
            ['Choose Service', 'Select instant, scheduled, or hourly service.', 1],
            ['Track Expert', 'See your expert live on map.', 2],
            ['Pay Securely', 'Pay with wallet, UPI, card, or Rapid Coin.', 3],
        ] as [$title, $content, $order]) {
            DB::table('onboarding_screens')->updateOrInsert(
                ['title' => $title],
                ['content' => $content, 'image_path' => 'onboarding/' . Str::slug($title) . '.png', 'sort_order' => $order, 'status' => 'active', 'created_at' => now(), 'updated_at' => now()]
            );
        }

        DB::table('payment_gateways')->updateOrInsert(
            ['slug' => 'razorpay'],
            ['name' => 'Razorpay', 'mode' => 'test', 'key_id' => 'rzp_test_key_here', 'key_secret' => encrypt('rzp_test_secret_here'), 'status' => 'inactive', 'created_at' => now(), 'updated_at' => now()]
        );

        DB::table('map_settings')->updateOrInsert(
            ['provider' => 'google'],
            ['api_key' => 'ADD_GOOGLE_MAP_KEY_HERE', 'default_lat' => 28.4595, 'default_lng' => 77.0266, 'default_zoom' => 12, 'status' => 'active', 'created_at' => now(), 'updated_at' => now()]
        );

        foreach ([
            ['en', 'app', 'book_now', 'Book Now'],
            ['hi', 'app', 'book_now', 'Abhi Book Karein'],
            ['en', 'admin', 'dashboard', 'Dashboard'],
            ['hi', 'admin', 'dashboard', 'Dashboard'],
        ] as [$locale, $group, $key, $value]) {
            DB::table('language_strings')->updateOrInsert(
                ['locale' => $locale, 'group_name' => $group, 'translation_key' => $key],
                ['translation_value' => $value, 'created_at' => now(), 'updated_at' => now()]
            );
        }
    }
}
