<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        if (! Schema::hasTable('tenants') || ! Schema::hasTable('branches')) {
            return;
        }

        DB::table('tenants')
            ->select(['id', 'address', 'phone'])
            ->orderBy('id')
            ->get()
            ->each(function ($tenant): void {
                $defaultBranchId = $this->defaultBranchIdForTenant($tenant);

                if (! $defaultBranchId) {
                    return;
                }

                foreach (['users', 'customers', 'loans', 'expenses'] as $table) {
                    if (! Schema::hasTable($table) || ! Schema::hasColumn($table, 'branch_id')) {
                        continue;
                    }

                    DB::table($table)
                        ->where('tenant_id', $tenant->id)
                        ->whereNull('branch_id')
                        ->update([
                            'branch_id' => $defaultBranchId,
                            'updated_at' => now(),
                        ]);
                }
            });
    }

    public function down(): void
    {
        // Existing records are intentionally left assigned to their default branch.
    }

    private function defaultBranchIdForTenant(object $tenant): ?int
    {
        $activeBranches = DB::table('branches')
            ->where('tenant_id', $tenant->id)
            ->where('is_active', true)
            ->orderBy('id')
            ->get();

        if ($activeBranches->count() === 1) {
            return (int) $activeBranches->first()->id;
        }

        $headOffice = $activeBranches->firstWhere('code', 'HQ')
            ?: $activeBranches->firstWhere('name', 'Head Office');

        if ($headOffice) {
            return (int) $headOffice->id;
        }

        $existingHeadOffice = DB::table('branches')
            ->where('tenant_id', $tenant->id)
            ->where('code', 'HQ')
            ->first();

        if ($existingHeadOffice) {
            DB::table('branches')
                ->where('id', $existingHeadOffice->id)
                ->update([
                    'name' => $existingHeadOffice->name ?: 'Head Office',
                    'is_active' => true,
                    'updated_at' => now(),
                ]);

            return (int) $existingHeadOffice->id;
        }

        return (int) DB::table('branches')->insertGetId([
            'tenant_id' => $tenant->id,
            'name' => 'Head Office',
            'code' => 'HQ',
            'address' => $tenant->address,
            'phone' => $tenant->phone,
            'is_active' => true,
            'created_at' => now(),
            'updated_at' => now(),
        ]);
    }
};
