<?php

namespace Database\Seeders;

use App\Models\Account;
use App\Support\QuickBooksChartOfAccounts;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class QboChartOfAccountsSeeder extends Seeder
{
    public function run(): void
    {
        $companies = DB::table('companies')->whereNull('deleted_at')->get(['id']);

        foreach ($companies as $company) {
            $this->seedForCompany($company->id);
        }
    }

    private function seedForCompany(int $companyId): void
    {
        $this->resetChartOfAccounts($companyId);

        $inserted = [];
        foreach (QuickBooksChartOfAccounts::systemAccounts() as $sortOrder => $acc) {
            $parentId = null;
            $depth = 0;
            $path = null;

            if (!empty($acc['parent']) && isset($inserted[$acc['parent']])) {
                $parent = Account::withoutGlobalScopes()->find($inserted[$acc['parent']]);
                $parentId = $parent?->id;
                $depth = ($parent?->depth ?? 0) + 1;
                $path = $parent?->path ? $parent->path . '/' . $parent->id : (string) $parent?->id;
            }

            $account = Account::withoutGlobalScopes()->updateOrCreate(
                ['company_id' => $companyId, 'code' => $acc['code']],
                [
                    'company_id'  => $companyId,
                    'parent_id'   => $parentId,
                    'name'        => $acc['name'],
                    'type'        => $acc['type'],
                    'sub_type'    => $acc['sub_type'],
                    'detail_type' => $acc['detail_type'] ?? null,
                    'is_group'    => $acc['is_group'] ?? false,
                    'is_system'   => $acc['is_system'] ?? false,
                    'is_bank'     => $acc['is_bank'] ?? false,
                    'is_cash'     => $acc['is_cash'] ?? false,
                    'is_active'   => true,
                    'sort_order'  => $sortOrder + 1,
                    'depth'       => $depth,
                    'path'        => $path,
                ]
            );

            $inserted[$acc['code']] = $account->id;
        }

        $this->command->info("Company {$companyId}: " . count($inserted) . ' system accounts seeded');
    }

    private function resetChartOfAccounts(int $companyId): void
    {
        $accountIds = Account::withoutGlobalScopes()
            ->where('company_id', $companyId)
            ->pluck('id');

        if ($accountIds->isEmpty()) {
            return;
        }

        $hasActivity = DB::table('ledger_entries')->whereIn('account_id', $accountIds)->exists()
            || DB::table('voucher_lines')->whereIn('account_id', $accountIds)->exists()
            || DB::table('bank_accounts')->whereIn('account_id', $accountIds)->exists();

        if ($hasActivity) {
            $this->command->warn("Company {$companyId}: existing accounts have activity; system accounts merged without deleting historical accounts.");
            return;
        }

        Account::withoutGlobalScopes()
            ->where('company_id', $companyId)
            ->forceDelete();
    }
}
