<?php

declare(strict_types=1);

namespace Database\Seeders;

use App\Enums\Status;
use App\Models\BankCard;
use App\Models\Charge;
use App\Models\Invoice;
use App\Models\InvoiceItem;
use App\Models\Payment;
use App\Models\Project;
use App\Models\User;
use App\Models\WalletTransaction;
use App\Models\WithdrawalRequest;
use Database\Seeders\Support\DemoSeederContext;
use Illuminate\Database\Seeder;

class FinancialDemoSeeder extends Seeder
{
    public function run(): void
    {
        $user = DemoSeederContext::employer();
        $admin = DemoSeederContext::admin();
        $bankCard = $user ? BankCard::query()->where('user_id', $user->id)->where('is_default', true)->first() : null;

        if (! $user || ! $admin) {
            return;
        }

        $mainProject = DemoSeederContext::mainProject();
        $secondProject = DemoSeederContext::secondProject();

        $this->seedWalletTransactions($user, $mainProject, $secondProject);
        $this->seedWithdrawals($user, $admin, $bankCard);
        $this->seedPayments($user, $admin, $mainProject);
        $this->seedInvoices($user, $admin, $mainProject, $secondProject);

        $lastBalance = WalletTransaction::query()
            ->where('user_id', $user->id)
            ->orderByDesc('id')
            ->value('balance_after');

        if ($lastBalance !== null) {
            $user->updateQuietly(['wallet' => (int) $lastBalance]);
        }
    }

    private function seedWalletTransactions(User $user, ?Project $main, ?Project $second): void
    {
        $balance = (int) ($user->wallet ?? 0);

        $rows = [
            [
                'type' => WalletTransaction::TYPE_DEPOSIT,
                'amount' => 10_000_000,
                'description' => 'واریز کیف پول از درگاه',
                'tracking_code' => 'DP-' . now()->subDays(30)->format('Ymd') . '01',
                'status' => WalletTransaction::STATUS_COMPLETED,
                'created_at' => now()->subDays(30),
            ],
            [
                'type' => WalletTransaction::TYPE_DEPOSIT,
                'amount' => 5_500_000,
                'description' => 'واریز کیف پول',
                'tracking_code' => 'DP-' . now()->subDays(14)->format('Ymd') . '02',
                'status' => WalletTransaction::STATUS_COMPLETED,
                'created_at' => now()->subDays(14),
            ],
            [
                'type' => WalletTransaction::TYPE_PURCHASE,
                'amount' => 2_400_000,
                'description' => 'پرداخت فاکتور خوراک دام',
                'tracking_code' => 'INV-2026-0003',
                'status' => WalletTransaction::STATUS_COMPLETED,
                'project_id' => $main?->id,
                'created_at' => now()->subDays(10),
            ],
            [
                'type' => WalletTransaction::TYPE_PROFIT,
                'amount' => 1_800_000,
                'description' => 'سود دوره‌ای پروژه',
                'tracking_code' => 'PR-' . now()->subDays(7)->format('Ymd'),
                'status' => WalletTransaction::STATUS_COMPLETED,
                'project_id' => $main?->id,
                'created_at' => now()->subDays(7),
            ],
            [
                'type' => WalletTransaction::TYPE_FEE,
                'amount' => 150_000,
                'description' => 'کارمزد نگهداری',
                'tracking_code' => 'FEE-' . now()->subDays(3)->format('Ymd'),
                'status' => WalletTransaction::STATUS_COMPLETED,
                'created_at' => now()->subDays(3),
            ],
            [
                'type' => WalletTransaction::TYPE_PURCHASE,
                'amount' => 950_000,
                'description' => 'هزینه واکسیناسیون',
                'tracking_code' => 'INV-2026-0004',
                'status' => WalletTransaction::STATUS_COMPLETED,
                'project_id' => $second?->id,
                'created_at' => now()->subDays(2),
            ],
        ];

        $runningBalance = max($balance - array_sum(array_column($rows, 'amount')) + 10_000_000, 0);

        foreach ($rows as $row) {
            if ($row['type'] === WalletTransaction::TYPE_DEPOSIT || $row['type'] === WalletTransaction::TYPE_PROFIT) {
                $runningBalance += $row['amount'];
            } else {
                $runningBalance -= $row['amount'];
            }

            WalletTransaction::firstOrCreate(
                ['tracking_code' => $row['tracking_code']],
                array_merge($row, [
                    'user_id' => $user->id,
                    'balance_after' => $runningBalance,
                ])
            );
        }
    }

    private function seedWithdrawals(User $user, User $admin, ?BankCard $bankCard): void
    {
        WithdrawalRequest::firstOrCreate(
            ['transfer_ref' => 'WD-APPROVED-001'],
            [
                'user_id' => $user->id,
                'bank_card_id' => $bankCard?->id,
                'amount' => 2_000_000,
                'shaba' => 'IR120170000000123456789012',
                'account_holder_name' => 'یوسف روشندل',
                'wallet_balance_at_request' => $user->wallet,
                'status' => WithdrawalRequest::STATUS_APPROVED,
                'admin_note' => 'واریز انجام شد',
                'processed_by' => $admin->id,
                'processed_at' => now()->subDays(5),
                'created_at' => now()->subDays(6),
            ]
        );

        WithdrawalRequest::firstOrCreate(
            [
                'user_id' => $user->id,
                'amount' => 1_500_000,
                'status' => WithdrawalRequest::STATUS_PENDING,
            ],
            [
                'bank_card_id' => $bankCard?->id,
                'shaba' => 'IR120170000000123456789012',
                'account_holder_name' => 'یوسف روشندل',
                'wallet_balance_at_request' => $user->wallet,
                'created_at' => now()->subDay(),
            ]
        );

        WithdrawalRequest::firstOrCreate(
            ['transfer_ref' => 'WD-REJECTED-001'],
            [
                'user_id' => $user->id,
                'bank_card_id' => $bankCard?->id,
                'amount' => 500_000,
                'shaba' => 'IR120170000000123456789012',
                'account_holder_name' => 'یوسف روشندل',
                'wallet_balance_at_request' => $user->wallet,
                'status' => WithdrawalRequest::STATUS_REJECTED,
                'admin_note' => 'شماره شبا با نام صاحب حساب مطابقت ندارد',
                'processed_by' => $admin->id,
                'processed_at' => now()->subDays(3),
                'created_at' => now()->subDays(4),
            ]
        );
    }

    private function seedPayments(User $user, User $admin, ?Project $project): void
    {
        $charge = Charge::firstOrCreate(
            [
                'user_id' => $user->id,
                'amount' => 5_000_000,
            ],
            [
                'status' => 'completed',
                'created_at' => now()->subDays(14),
            ]
        );

        Payment::without('model')->firstOrCreate(
            ['ref_id' => 'DEMO-PAY-001'],
            [
                'user_id' => $user->id,
                'price' => 5_000_000,
                'gateway' => 'zarinpal',
                'status' => Status::PAID->value,
                'transaction_id' => 'A000DEMO001',
                'project_id' => $project?->id,
                'cellphone' => $user->cellphone,
                'email' => $user->email,
                'card_number' => '6104-****-3456',
                'model_type' => Charge::class,
                'model_id' => $charge->id,
                'created_by' => $admin->id,
                'created_at' => now()->subDays(14),
            ]
        );
    }

    private function seedInvoices(User $user, User $admin, ?Project $main, ?Project $second): void
    {
        $invoices = [
            [
                'number' => 'INV-2026-0001',
                'project_id' => $main?->id,
                'type' => Invoice::TYPE_INCOME,
                'status' => Invoice::STATUS_PAID,
                'total' => 3_200_000,
                'issued_at' => now()->subDays(20),
                'due_at' => now()->subDays(10),
                'description' => 'فروش شیر دوره‌ای',
                'items' => [
                    ['name' => 'شیر خام', 'category' => 'درآمد', 'quantity' => 1, 'unit' => 'دوره', 'unit_price' => 3_200_000, 'total' => 3_200_000],
                ],
            ],
            [
                'number' => 'INV-2026-0002',
                'project_id' => $main?->id,
                'type' => Invoice::TYPE_EXPENSE,
                'status' => Invoice::STATUS_PAID,
                'total' => 2_400_000,
                'issued_at' => now()->subDays(12),
                'due_at' => now()->subDays(5),
                'description' => 'خرید خوراک دام',
                'items' => [
                    ['name' => 'کنسانتره شیری', 'category' => 'خوراک', 'subcategory' => 'کنسانتره', 'quantity' => 40, 'unit' => 'کیلو', 'unit_price' => 45_000, 'total' => 1_800_000],
                    ['name' => 'یونجه', 'category' => 'خوراک', 'quantity' => 200, 'unit' => 'کیلو', 'unit_price' => 3_000, 'total' => 600_000],
                ],
            ],
            [
                'number' => 'INV-2026-0003',
                'project_id' => $main?->id,
                'type' => Invoice::TYPE_EXPENSE,
                'status' => Invoice::STATUS_UNPAID,
                'total' => 1_750_000,
                'issued_at' => now()->subDays(3),
                'due_at' => now()->addDays(7),
                'description' => 'خدمات دامپزشکی',
                'items' => [
                    ['name' => 'معاینه دوره‌ای', 'category' => 'سلامت', 'quantity' => 1, 'unit' => 'خدمت', 'unit_price' => 750_000, 'total' => 750_000],
                    ['name' => 'واکسن', 'category' => 'سلامت', 'quantity' => 12, 'unit' => 'دوز', 'unit_price' => 83_333, 'total' => 1_000_000],
                ],
            ],
            [
                'number' => 'INV-2026-0004',
                'project_id' => $second?->id,
                'type' => Invoice::TYPE_EXPENSE,
                'status' => Invoice::STATUS_PENDING,
                'total' => 950_000,
                'issued_at' => now()->subDays(2),
                'due_at' => now()->addDays(14),
                'description' => 'هزینه واکسیناسیون گله',
                'items' => [
                    ['name' => 'واکسن طیور', 'category' => 'سلامت', 'quantity' => 80, 'unit' => 'دوز', 'unit_price' => 11_875, 'total' => 950_000],
                ],
            ],
            [
                'number' => 'INV-2026-0005',
                'project_id' => $main?->id,
                'type' => Invoice::TYPE_EXPENSE,
                'status' => Invoice::STATUS_DRAFT,
                'total' => 600_000,
                'issued_at' => now(),
                'description' => 'پیش‌نویس فاکتور تعمیرات',
                'items' => [
                    ['name' => 'تعمیر آبیاری', 'category' => 'تاسیسات', 'quantity' => 1, 'unit' => 'خدمت', 'unit_price' => 600_000, 'total' => 600_000],
                ],
            ],
            [
                'number' => 'INV-2026-0006',
                'project_id' => $main?->id,
                'type' => Invoice::TYPE_INCOME,
                'status' => Invoice::STATUS_APPROVED,
                'total' => 4_100_000,
                'issued_at' => now()->subDays(8),
                'description' => 'فاکتور درآمد تایید شده',
                'items' => [
                    ['name' => 'فروش شیر', 'category' => 'درآمد', 'quantity' => 1, 'unit' => 'دوره', 'unit_price' => 4_100_000, 'total' => 4_100_000],
                ],
            ],
            [
                'number' => 'INV-2026-0007',
                'project_id' => $second?->id,
                'type' => Invoice::TYPE_EXPENSE,
                'status' => Invoice::STATUS_REJECTED,
                'total' => 1_200_000,
                'issued_at' => now()->subDays(6),
                'description' => 'فاکتور رد شده',
                'admin_reason' => 'مغایرت با قرارداد',
                'items' => [
                    ['name' => 'حمل و نقل', 'category' => 'حمل', 'quantity' => 1, 'unit' => 'سرویس', 'unit_price' => 1_200_000, 'total' => 1_200_000],
                ],
            ],
            [
                'number' => 'INV-2026-0008',
                'project_id' => $main?->id,
                'type' => Invoice::TYPE_EXPENSE,
                'status' => Invoice::STATUS_NEEDS_EDIT,
                'total' => 850_000,
                'issued_at' => now()->subDay(),
                'description' => 'نیاز به اصلاح مبلغ',
                'admin_reason' => 'مبلغ واحد را اصلاح کنید',
                'items' => [
                    ['name' => 'دارو', 'category' => 'سلامت', 'quantity' => 10, 'unit' => 'عدد', 'unit_price' => 85_000, 'total' => 850_000],
                ],
            ],
        ];

        foreach ($invoices as $data) {
            $items = $data['items'];
            unset($data['items']);

            $invoice = Invoice::firstOrCreate(
                ['number' => $data['number']],
                array_merge($data, [
                    'user_id' => $user->id,
                    'created_by' => $admin->id,
                ])
            );

            foreach ($items as $index => $item) {
                InvoiceItem::firstOrCreate(
                    [
                        'invoice_id' => $invoice->id,
                        'name' => $item['name'],
                    ],
                    $item
                );
            }

            WalletTransaction::where('tracking_code', $data['number'])->update(['invoice_id' => $invoice->id]);
        }
    }
}
