<?php

namespace Database\Seeders;

use App\Models\Customer;
use App\Models\Invoice;
use App\Models\InvoiceItem;
use Carbon\Carbon;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class InvoiceSeeder extends Seeder
{
    use WithoutModelEvents;

    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        $customerIds = Customer::pluck('id')->toArray();

        if (empty($customerIds)) {
            $this->command->info('No customers found. Please run CustomerSeeder first.');

            return;
        }

        $statuses = ['draft', 'sent', 'viewed', 'partial', 'paid', 'overdue', 'cancelled'];
        $products = [
            ['description' => 'Web Development Services', 'unit_price' => 2500.00],
            ['description' => 'Mobile App Development', 'unit_price' => 5000.00],
            ['description' => 'UI/UX Design Services', 'unit_price' => 1500.00],
            ['description' => 'SEO Optimization Package', 'unit_price' => 800.00],
            ['description' => 'Cloud Hosting (Annual)', 'unit_price' => 1200.00],
            ['description' => 'Technical Consulting', 'unit_price' => 150.00],
            ['description' => 'Database Management', 'unit_price' => 900.00],
            ['description' => 'Security Audit', 'unit_price' => 2000.00],
            ['description' => 'Content Management System', 'unit_price' => 3500.00],
            ['description' => 'E-commerce Integration', 'unit_price' => 4500.00],
            ['description' => 'API Development', 'unit_price' => 2800.00],
            ['description' => 'DevOps Setup', 'unit_price' => 1800.00],
            ['description' => 'Training & Support', 'unit_price' => 500.00],
            ['description' => 'Maintenance Package (Monthly)', 'unit_price' => 350.00],
            ['description' => 'Custom Software Development', 'unit_price' => 8000.00],
        ];

        for ($i = 1; $i <= 25; $i++) {
            $issueDate = Carbon::now()->subDays(rand(1, 90));
            $dueDate = (clone $issueDate)->addDays(rand(15, 45));
            $status = $statuses[array_rand($statuses)];

            // Calculate amounts
            $numItems = rand(1, 4);
            $items = [];
            $subtotal = 0;

            for ($j = 0; $j < $numItems; $j++) {
                $product = $products[array_rand($products)];
                $quantity = rand(1, 5);
                $taxRate = [0, 5, 10, 18, 20][array_rand([0, 5, 10, 18, 20])];
                $itemTotal = $product['unit_price'] * $quantity;
                $taxAmount = $itemTotal * ($taxRate / 100);

                $items[] = [
                    'description' => $product['description'],
                    'quantity' => $quantity,
                    'unit_price' => $product['unit_price'],
                    'tax_rate' => $taxRate,
                    'tax_amount' => $taxAmount,
                    'total' => $itemTotal + $taxAmount,
                    'sort_order' => $j,
                ];

                $subtotal += $itemTotal;
            }

            $totalTax = array_sum(array_column($items, 'tax_amount'));
            $discountType = rand(0, 1) ? 'percentage' : 'fixed';
            $discountAmount = $discountType === 'percentage'
                ? $subtotal * (rand(0, 15) / 100)
                : rand(0, 500);
            $total = $subtotal + $totalTax - $discountAmount;

            $paidAmount = 0;
            if ($status === 'paid') {
                $paidAmount = $total;
            } elseif ($status === 'partial') {
                $paidAmount = $total * (rand(20, 80) / 100);
            }

            $invoiceNumber = 'INV-'.str_pad($i, 6, '0', STR_PAD_LEFT);

            $invoice = Invoice::updateOrCreate(
                ['invoice_number' => $invoiceNumber],
                [
                    'customer_id' => $customerIds[array_rand($customerIds)],
                    'issue_date' => $issueDate,
                    'due_date' => $dueDate,
                    'status' => $status,
                    'subtotal' => $subtotal,
                    'tax_amount' => $totalTax,
                    'discount_amount' => $discountAmount,
                    'discount_type' => $discountType,
                    'total' => $total,
                    'paid_amount' => $paidAmount,
                    'balance' => $total - $paidAmount,
                    'currency' => 'USD',
                    'exchange_rate' => 1,
                    'notes' => 'Thank you for your business!',
                    'terms' => 'Payment due within the specified due date. Late payments may incur additional fees.',
                    'sent_at' => in_array($status, ['sent', 'viewed', 'partial', 'paid', 'overdue']) ? $issueDate->addDay() : null,
                    'viewed_at' => in_array($status, ['viewed', 'partial', 'paid']) ? $issueDate->addDays(2) : null,
                ]
            );

            // Delete existing items and create new ones
            InvoiceItem::where('invoice_id', $invoice->id)->delete();

            // Create invoice items using bulk insert
            $itemsToInsert = array_map(function ($item) use ($invoice) {
                return array_merge($item, [
                    'invoice_id' => $invoice->id,
                    'created_at' => now(),
                    'updated_at' => now(),
                ]);
            }, $items);

            InvoiceItem::insert($itemsToInsert);
        }
    }
}
