<?php

namespace Database\Seeders;

use App\Enums\CommissionType;
use App\Enums\CustomerType;
use App\Enums\OrderStatus;
use App\Enums\PaymentMethod;
use App\Enums\PaymentStatus;
use App\Models\Banner;
use App\Models\Cart;
use App\Models\Category;
use App\Models\DeliveryArea;
use App\Models\GuestCustomer;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\Partner;
use App\Models\Payment;
use App\Models\Product;
use App\Models\User;
use App\Models\Voucher;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

class DemoDataSeeder extends Seeder
{
    public function run(): void
    {
        $this->seedDeliveryAreas();
        $this->seedCustomers();
        $this->seedPartners();
        $this->seedCategories();
        $this->seedProducts();
        $this->seedBanners();
        $this->seedVouchers();
        $this->seedOrders();
        $this->seedCarts();

        $this->command->info('✓ Demo data berhasil dibuat.');
    }

    // ── Delivery Areas ────────────────────────────────────────────────────

    private function seedDeliveryAreas(): void
    {
        $areas = [
            ['name' => 'RT 01 – RT 04 (Dekat)',   'cost' => 2000],
            ['name' => 'RT 05 – RT 09 (Sedang)',   'cost' => 5000],
            ['name' => 'RT 10 – RT 14 (Jauh)',     'cost' => 8000],
            ['name' => 'Luar Desa (Kecamatan)',    'cost' => 12000, 'is_active' => false],
        ];

        foreach ($areas as $area) {
            DeliveryArea::firstOrCreate(
                ['name' => $area['name']],
                ['cost' => $area['cost'], 'is_active' => $area['is_active'] ?? true]
            );
        }

        $this->command->info('  → ' . count($areas) . ' area ongkir dibuat.');
    }

    // ── Customers ─────────────────────────────────────────────────────────

    private function seedCustomers(): void
    {
        // Customer utama untuk testing
        $demoCustomers = [
            ['name' => 'Ibu Sari Dewi',    'phone' => '081234500001', 'email' => 'sari@demo.com'],
            ['name' => 'Ibu Rina Hartati',  'phone' => '081234500002', 'email' => 'rina@demo.com'],
            ['name' => 'Pak Budi Santoso', 'phone' => '081234500003', 'email' => 'budi@demo.com'],
        ];

        foreach ($demoCustomers as $data) {
            $user = User::updateOrCreate(
                ['email' => $data['email']],
                [
                    'name'      => $data['name'],
                    'phone'     => $data['phone'],
                    'password'  => Hash::make('password'),
                    'is_active' => true,
                ]
            );
            $user->syncRoles(['customer']);
        }

        $this->command->info('  → ' . count($demoCustomers) . ' customer demo dibuat.');
    }

    // ── Partners ──────────────────────────────────────────────────────────

    private function seedPartners(): void
    {
        $partners = [
            [
                'name'    => 'Warung Bu Tini',
                'phone'   => '081300001111',
                'address' => 'RT 02/RW 01 Desa Budiharja',
                'notes'   => 'Spesialis makanan matang dan lauk pauk',
                'default_commission_type'  => CommissionType::Percent->value,
                'default_commission_value' => 10,
            ],
            [
                'name'    => 'Toko Pak Hendra',
                'phone'   => '081300002222',
                'address' => 'RT 05/RW 02 Desa Budiharja',
                'notes'   => 'Sembako dan kebutuhan sehari-hari',
                'default_commission_type'  => CommissionType::Percent->value,
                'default_commission_value' => 8,
            ],
            [
                'name'    => 'Dapur Mbak Yuni',
                'phone'   => '081300003333',
                'address' => 'RT 07/RW 03 Desa Budiharja',
                'notes'   => 'Kue, camilan, dan minuman segar',
                'default_commission_type'  => CommissionType::Fixed->value,
                'default_commission_value' => 2000,
            ],
            [
                'name'    => 'Toko Barokah',
                'phone'   => '081300004444',
                'address' => 'RT 01/RW 01 Desa Budiharja',
                'notes'   => 'Frozen food dan produk kemasan',
                'default_commission_type'  => CommissionType::Fixed->value,
                'default_commission_value' => 1500,
            ],
        ];

        foreach ($partners as $data) {
            Partner::firstOrCreate(['name' => $data['name']], array_merge($data, ['is_active' => true]));
        }

        $this->command->info('  → ' . count($partners) . ' partner (mitra) dibuat.');
    }

    // ── Categories ────────────────────────────────────────────────────────

    private function seedCategories(): void
    {
        $categories = [
            ['name' => 'Sembako',             'sort_order' => 1],
            ['name' => 'Makanan Siap Saji',   'sort_order' => 2],
            ['name' => 'Lauk Pauk',           'sort_order' => 3],
            ['name' => 'Camilan & Snack',     'sort_order' => 4],
            ['name' => 'Minuman',             'sort_order' => 5],
            ['name' => 'Kue & Roti',          'sort_order' => 6],
            ['name' => 'Kebutuhan Rumah',     'sort_order' => 7],
            ['name' => 'Frozen Food',         'sort_order' => 8],
        ];

        foreach ($categories as $cat) {
            Category::firstOrCreate(
                ['slug' => Str::slug($cat['name'])],
                ['name' => $cat['name'], 'sort_order' => $cat['sort_order'], 'is_active' => true]
            );
        }

        $this->command->info('  → ' . count($categories) . ' kategori dibuat.');
    }

    // ── Products ──────────────────────────────────────────────────────────

    private function seedProducts(): void
    {
        $partnerTini   = Partner::where('name', 'Warung Bu Tini')->first();
        $partnerHendra = Partner::where('name', 'Toko Pak Hendra')->first();
        $partnerYuni   = Partner::where('name', 'Dapur Mbak Yuni')->first();
        $partnerBarokah= Partner::where('name', 'Toko Barokah')->first();

        $catSembako    = Category::where('slug', 'sembako')->first();
        $catMakanan    = Category::where('slug', 'makanan-siap-saji')->first();
        $catLauk       = Category::where('slug', 'lauk-pauk')->first();
        $catCamilan    = Category::where('slug', 'camilan-snack')->first();
        $catMinuman    = Category::where('slug', 'minuman')->first();
        $catKue        = Category::where('slug', 'kue-roti')->first();
        $catFrozen     = Category::where('slug', 'frozen-food')->first();

        $products = [
            // Sembako — Toko Pak Hendra
            [
                'category_id' => $catSembako->id, 'partner_id' => $partnerHendra->id,
                'name' => 'Beras Pulen 5kg', 'unit' => 'karung',
                'buy_price' => 55000, 'sell_price' => 63000, 'is_featured' => true,
            ],
            [
                'category_id' => $catSembako->id, 'partner_id' => $partnerHendra->id,
                'name' => 'Minyak Goreng 1L', 'unit' => 'botol',
                'buy_price' => 15000, 'sell_price' => 18000,
            ],
            [
                'category_id' => $catSembako->id, 'partner_id' => $partnerHendra->id,
                'name' => 'Gula Pasir 1kg', 'unit' => 'bungkus',
                'buy_price' => 13000, 'sell_price' => 16000,
            ],
            [
                'category_id' => $catSembako->id, 'partner_id' => $partnerHendra->id,
                'name' => 'Telur Ayam 1kg', 'unit' => 'kg',
                'buy_price' => 25000, 'sell_price' => 28000, 'is_featured' => true,
            ],

            // Makanan — Warung Bu Tini
            [
                'category_id' => $catMakanan->id, 'partner_id' => $partnerTini->id,
                'name' => 'Nasi Uduk Komplit', 'unit' => 'porsi',
                'buy_price' => 12000, 'sell_price' => 18000, 'is_featured' => true,
            ],
            [
                'category_id' => $catMakanan->id, 'partner_id' => $partnerTini->id,
                'name' => 'Nasi Kuning Komplit', 'unit' => 'porsi',
                'buy_price' => 12000, 'sell_price' => 18000,
            ],
            [
                'category_id' => $catMakanan->id, 'partner_id' => $partnerTini->id,
                'name' => 'Lontong Sayur', 'unit' => 'porsi',
                'buy_price' => 10000, 'sell_price' => 15000,
            ],

            // Lauk — Warung Bu Tini
            [
                'category_id' => $catLauk->id, 'partner_id' => $partnerTini->id,
                'name' => 'Ayam Goreng', 'unit' => 'potong',
                'buy_price' => 12000, 'sell_price' => 17000, 'is_featured' => true,
            ],
            [
                'category_id' => $catLauk->id, 'partner_id' => $partnerTini->id,
                'name' => 'Tempe Mendoan', 'unit' => 'porsi',
                'buy_price' => 5000, 'sell_price' => 8000,
            ],
            [
                'category_id' => $catLauk->id, 'partner_id' => $partnerTini->id,
                'name' => 'Ikan Goreng', 'unit' => 'ekor',
                'buy_price' => 10000, 'sell_price' => 15000,
            ],

            // Camilan — Dapur Mbak Yuni
            [
                'category_id' => $catCamilan->id, 'partner_id' => $partnerYuni->id,
                'name' => 'Keripik Singkong Pedas', 'unit' => 'bungkus',
                'buy_price' => 7000, 'sell_price' => 11000,
                // Override komisi: percent 15%, beda dari default fixed Rp2000
                'commission_type' => CommissionType::Percent->value, 'commission_value' => 15,
            ],
            [
                'category_id' => $catCamilan->id, 'partner_id' => $partnerYuni->id,
                'name' => 'Pisang Goreng Crispy', 'unit' => 'porsi',
                'buy_price' => 8000, 'sell_price' => 13000,
            ],

            // Minuman — Dapur Mbak Yuni
            [
                'category_id' => $catMinuman->id, 'partner_id' => $partnerYuni->id,
                'name' => 'Es Teh Manis 1L', 'unit' => 'botol',
                'buy_price' => 4000, 'sell_price' => 7000, 'is_featured' => true,
            ],
            [
                'category_id' => $catMinuman->id, 'partner_id' => $partnerYuni->id,
                'name' => 'Es Jeruk 600ml', 'unit' => 'botol',
                'buy_price' => 5000, 'sell_price' => 8000,
            ],
            [
                'category_id' => $catMinuman->id, 'partner_id' => $partnerYuni->id,
                'name' => 'Jus Alpukat 400ml', 'unit' => 'cup',
                'buy_price' => 8000, 'sell_price' => 13000,
            ],

            // Kue — Dapur Mbak Yuni
            [
                'category_id' => $catKue->id, 'partner_id' => $partnerYuni->id,
                'name' => 'Kue Lapis', 'unit' => 'loyang',
                'buy_price' => 20000, 'sell_price' => 27000,
            ],
            [
                'category_id' => $catKue->id, 'partner_id' => $partnerYuni->id,
                'name' => 'Onde-Onde (5 pcs)', 'unit' => 'porsi',
                'buy_price' => 8000, 'sell_price' => 12000,
            ],

            // Frozen Food — Toko Barokah
            [
                'category_id' => $catFrozen->id, 'partner_id' => $partnerBarokah->id,
                'name' => 'Nugget Ayam 500g', 'unit' => 'bungkus',
                'buy_price' => 28000, 'sell_price' => 33000,
            ],
            [
                'category_id' => $catFrozen->id, 'partner_id' => $partnerBarokah->id,
                'name' => 'Sosis Sapi 375g', 'unit' => 'bungkus',
                'buy_price' => 22000, 'sell_price' => 27000,
            ],
        ];

        $count = 0;
        foreach ($products as $data) {
            $slug = Str::slug($data['name']);

            // Pastikan slug unik
            $existing = Product::withTrashed()->where('slug', $slug)->first();
            if ($existing) {
                continue; // skip jika sudah ada
            }

            Product::create(array_merge($data, [
                'slug'             => $slug,
                'is_active'        => true,
                'is_featured'      => $data['is_featured'] ?? false,
                'commission_type'  => $data['commission_type'] ?? null,
                'commission_value' => $data['commission_value'] ?? null,
            ]));

            $count++;
        }

        $this->command->info("  → {$count} produk dibuat.");
    }

    // ── Banners ───────────────────────────────────────────────────────────

    private function seedBanners(): void
    {
        $banners = [
            ['title' => 'Selamat Datang di Titipin Ba Be',   'sort_order' => 1],
            ['title' => 'Produk Segar Setiap Hari',          'sort_order' => 2],
            ['title' => 'Gratis Ongkir Wilayah RT 01-04',    'sort_order' => 3],
        ];

        foreach ($banners as $data) {
            Banner::firstOrCreate(
                ['title' => $data['title']],
                ['image' => 'banners/placeholder.jpg', 'is_active' => true, 'sort_order' => $data['sort_order']]
            );
        }

        $this->command->info('  → ' . count($banners) . ' banner dibuat.');
    }

    // ── Vouchers ──────────────────────────────────────────────────────────

    private function seedVouchers(): void
    {
        $vouchers = [
            [
                'code'        => 'SELAMAT10',
                'type'        => 'percent',
                'value'       => 10,
                'min_order'   => 30000,
                'max_discount'=> 10000,
                'quota'       => 50,
                'valid_from'  => now()->toDateString(),
                'valid_until' => now()->addDays(30)->toDateString(),
            ],
            [
                'code'        => 'GRATIS5000',
                'type'        => 'fixed',
                'value'       => 5000,
                'min_order'   => 25000,
                'max_discount'=> null,
                'quota'       => null, // unlimited
                'valid_from'  => now()->toDateString(),
                'valid_until' => now()->addDays(60)->toDateString(),
            ],
            [
                'code'        => 'EXPIRED', // untuk testing voucher kadaluarsa
                'type'        => 'fixed',
                'value'       => 10000,
                'min_order'   => 0,
                'max_discount'=> null,
                'quota'       => null,
                'valid_from'  => now()->subDays(60)->toDateString(),
                'valid_until' => now()->subDay()->toDateString(),
            ],
        ];

        foreach ($vouchers as $data) {
            Voucher::firstOrCreate(
                ['code' => $data['code']],
                array_merge($data, ['used_count' => 0, 'is_active' => true])
            );
        }

        $this->command->info('  → ' . count($vouchers) . ' voucher dibuat.');
    }

    // ── Orders ────────────────────────────────────────────────────────────

    private function seedOrders(): void
    {
        $customers    = User::role('customer')->get();
        $areas        = DeliveryArea::where('is_active', true)->get();
        $products     = Product::where('is_active', true)->get();
        $adminUser    = User::where('email', 'admin@titipinbabe.com')->first();

        if ($customers->isEmpty() || $areas->isEmpty() || $products->isEmpty()) {
            $this->command->warn('  ! Tidak cukup data untuk membuat order demo.');
            return;
        }

        $ordersData = [
            // Order 1: Customer login, pending (belum bayar)
            [
                'customer'  => $customers->first(),
                'area'      => $areas->first(),
                'items'     => [
                    ['product' => $products->where('name', 'Nasi Uduk Komplit')->first(), 'qty' => 2],
                    ['product' => $products->where('name', 'Es Teh Manis 1L')->first(),   'qty' => 2],
                ],
                'status'    => OrderStatus::Pending,
                'method'    => PaymentMethod::Transfer,
                'assigned'  => null,
            ],

            // Order 2: Customer login, sudah bayar (menunggu verifikasi)
            [
                'customer'  => $customers->first(),
                'area'      => $areas->skip(1)->first(),
                'items'     => [
                    ['product' => $products->where('name', 'Beras Pulen 5kg')->first(),    'qty' => 1],
                    ['product' => $products->where('name', 'Telur Ayam 1kg')->first(),     'qty' => 2],
                ],
                'status'    => OrderStatus::Paid,
                'method'    => PaymentMethod::Transfer,
                'assigned'  => $adminUser,
            ],

            // Order 3: Sudah selesai
            [
                'customer'  => $customers->skip(1)->first(),
                'area'      => $areas->first(),
                'items'     => [
                    ['product' => $products->where('name', 'Ayam Goreng')->first(),         'qty' => 3],
                    ['product' => $products->where('name', 'Tempe Mendoan')->first(),       'qty' => 2],
                ],
                'status'    => OrderStatus::Completed,
                'method'    => PaymentMethod::Cod,
                'assigned'  => $adminUser,
            ],

            // Order 4: Customer ke-2, diproses
            [
                'customer'  => $customers->skip(1)->first(),
                'area'      => $areas->first(),
                'items'     => [
                    ['product' => $products->where('name', 'Keripik Singkong Pedas')->first(), 'qty' => 3],
                    ['product' => $products->where('name', 'Es Teh Manis 1L')->first(),        'qty' => 3],
                ],
                'status'    => OrderStatus::Processing,
                'method'    => PaymentMethod::Qris,
                'assigned'  => $adminUser,
            ],

            // Order 5: Guest checkout, pending
            [
                'customer'  => null, // guest
                'area'      => $areas->first(),
                'items'     => [
                    ['product' => $products->where('name', 'Kue Lapis')->first(),     'qty' => 1],
                    ['product' => $products->where('name', 'Onde-Onde (5 pcs)')->first(), 'qty' => 2],
                ],
                'status'    => OrderStatus::Pending,
                'method'    => PaymentMethod::Transfer,
                'assigned'  => null,
            ],
        ];

        $orderCount = 0;
        foreach ($ordersData as $index => $data) {
            // Hitung subtotal
            $subtotal = 0;
            foreach ($data['items'] as $item) {
                if ($item['product']) {
                    $subtotal += $item['product']->sell_price * $item['qty'];
                }
            }

            $deliveryCost = $data['area']->cost;
            $grandTotal   = $subtotal + $deliveryCost;

            $orderNumber = 'TBB-' . now()->format('Ymd') . '-' . str_pad($index + 1, 4, '0', STR_PAD_LEFT);

            // Handle guest customer
            $guestCustomer = null;
            $customerId    = null;
            $customerType  = CustomerType::User;

            if ($data['customer'] === null) {
                $guestCustomer = GuestCustomer::create([
                    'session_id' => 'demo_session_' . ($index + 1),
                    'name'       => 'Tamu Demo ' . ($index + 1),
                    'phone'      => '08900000000' . ($index + 1),
                    'address'    => 'RT 03/RW 02 Desa Budiharja',
                ]);
                $customerType = CustomerType::Guest;
            } else {
                $customerId = $data['customer']->id;
            }

            // Buat order
            $order = Order::create([
                'order_number'      => $orderNumber,
                'customer_type'     => $customerType->value,
                'user_id'           => $customerId,
                'guest_customer_id' => $guestCustomer?->id,
                'customer_name'     => $data['customer']?->name ?? $guestCustomer->name,
                'customer_phone'    => $data['customer']?->phone ?? $guestCustomer->phone,
                'delivery_address_snapshot'  => $data['customer']
                    ? 'RT 0' . ($index + 1) . '/RW 01 Desa Budiharja'
                    : $guestCustomer->address,
                'assigned_admin_id' => $data['assigned']?->id,
                'delivery_area_id'  => $data['area']->id,
                'delivery_cost'     => $deliveryCost,
                'voucher_id'        => null,
                'discount_amount'   => 0,
                'subtotal'          => $subtotal,
                'grand_total'       => $grandTotal,
                'status'            => $data['status']->value,
                'payment_method'    => $data['method']->value,
                'payment_deadline'  => $data['method']->requiresProof()
                    ? now()->addHours(24)
                    : null,
            ]);

            // Buat order items (snapshot)
            foreach ($data['items'] as $item) {
                if (! $item['product']) {
                    continue;
                }

                $product = $item['product'];
                $qty     = $item['qty'];

                // Ambil komisi efektif
                $commType  = $product->commission_type ?? $product->partner->default_commission_type;
                $commValue = $product->commission_value ?? $product->partner->default_commission_value;

                OrderItem::create([
                    'order_id'         => $order->id,
                    'product_id'       => $product->id,
                    'product_name'     => $product->name,
                    'product_image'    => $product->image,
                    'buy_price'        => $product->buy_price,
                    'sell_price'       => $product->sell_price,
                    'commission_type'  => $commType instanceof CommissionType ? $commType->value : $commType,
                    'commission_value' => $commValue,
                    'quantity'         => $qty,
                    'subtotal'         => $product->sell_price * $qty,
                ]);
            }

            // Buat payment record
            $paymentStatus = match ($data['status']) {
                OrderStatus::Paid                               => PaymentStatus::Pending,
                OrderStatus::Processing, OrderStatus::Completed => PaymentStatus::Verified,
                default                                         => PaymentStatus::Pending,
            };

            Payment::create([
                'order_id'    => $order->id,
                'method'      => $data['method']->value,
                'amount'      => $grandTotal,
                'proof_image' => in_array($data['status'], [OrderStatus::Paid, OrderStatus::Processing, OrderStatus::Completed])
                    ? 'payments/demo_proof.jpg'
                    : null,
                'status'      => $paymentStatus->value,
                'verified_by' => in_array($data['status'], [OrderStatus::Processing, OrderStatus::Completed])
                    ? $adminUser?->id
                    : null,
                'verified_at' => in_array($data['status'], [OrderStatus::Processing, OrderStatus::Completed])
                    ? now()->subHours(2)
                    : null,
            ]);

            $orderCount++;
        }

        $this->command->info("  → {$orderCount} order demo dibuat.");
    }

    // ── Carts ─────────────────────────────────────────────────────────────

    private function seedCarts(): void
    {
        $customer = User::where('email', 'sari@demo.com')->first();
        $products = Product::where('is_active', true)->take(3)->get();

        if (! $customer || $products->isEmpty()) {
            return;
        }

        foreach ($products as $product) {
            Cart::firstOrCreate(
                ['user_id' => $customer->id, 'product_id' => $product->id],
                ['quantity' => 1]
            );
        }

        $this->command->info('  → Cart demo untuk sari@demo.com dibuat (' . $products->count() . ' item).');
    }
}
