<?php

namespace App\Domains\Identity\Actions;

use App\Domains\AI\Actions\CreateDefaultAiSettingsAction;
use App\Domains\Billing\Models\Plan;
use App\Domains\Billing\Models\Subscription;
use App\Domains\Catalog\Actions\SeedDemoCommerceAction;
use App\Domains\Channels\Actions\SeedDemoChannelAndPaymentAction;
use App\Domains\Conversations\Actions\SeedDemoInboxAction;
use App\Domains\Leads\Actions\CreateDefaultPipelineAction;
use App\Domains\Leads\Actions\SeedDemoLeadsAction;
use App\Domains\Tasks\Actions\SeedDemoTasksAction;
use App\Domains\Tenancy\Models\Branch;
use App\Domains\Tenancy\Models\Tenant;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class RegisterTenantAction
{
    public function __construct(
        protected CreateDefaultAiSettingsAction $createDefaultAiSettings,
        protected CreateDefaultRolesAction $createDefaultRoles,
        protected SeedDemoUsersAction $seedDemoUsers,
        protected CreateDefaultPipelineAction $createDefaultPipeline,
        protected SeedDemoInboxAction $seedDemoInbox,
        protected SeedDemoLeadsAction $seedDemoLeads,
        protected SeedDemoCommerceAction $seedDemoCommerce,
        protected SeedDemoTasksAction $seedDemoTasks,
        protected SeedDemoChannelAndPaymentAction $seedDemoChannelAndPayment,
    ) {
    }

    public function execute(array $data): User
    {
        return DB::transaction(function () use ($data) {
            $plan = Plan::query()->where('slug', 'starter')->first();

            $tenant = Tenant::query()->create([
                'company_name' => $data['company_name'],
                'slug' => $this->uniqueSlug($data['company_name']),
                'country_code' => $data['country'] ?? null,
                'currency_code' => 'USD',
                'timezone' => 'UTC',
                'status' => 'trial',
                'plan_id' => $plan?->getKey(),
                'trial_ends_at' => now()->addDays(14),
            ]);

            $branch = Branch::query()->create([
                'tenant_id' => $tenant->getKey(),
                'name' => 'Main Branch',
                'code' => 'MAIN',
                'phone' => $data['phone'] ?? null,
                'is_active' => true,
            ]);

            $user = User::query()->create([
                'tenant_id' => $tenant->getKey(),
                'branch_id' => $branch->getKey(),
                'full_name' => $data['full_name'],
                'email' => $data['email'],
                'phone' => $data['phone'] ?? null,
                'password' => $data['password'],
                'status' => 'active',
            ]);

            if ($plan) {
                Subscription::query()->create([
                    'tenant_id' => $tenant->getKey(),
                    'plan_id' => $plan->getKey(),
                    'status' => 'trial',
                    'starts_at' => now(),
                    'trial_ends_at' => $tenant->trial_ends_at,
                ]);
            }

            $this->createDefaultRoles->execute($tenant, $user);
            $this->seedDemoUsers->execute($tenant, $branch);
            $this->createDefaultPipeline->execute($tenant);
            $this->createDefaultAiSettings->execute($tenant);
            $this->seedDemoChannelAndPayment->execute($tenant);
            $this->seedDemoInbox->execute($tenant, $user, $branch);
            $this->seedDemoLeads->execute($tenant, $user, $branch);
            $this->seedDemoCommerce->execute($tenant, $user, $branch);
            $this->seedDemoTasks->execute($tenant, $user, $branch);

            return $user;
        });
    }

    protected function uniqueSlug(string $companyName): string
    {
        $base = Str::of($companyName)->slug()->limit(50, '');
        $slug = $base->isEmpty() ? 'tenant' : (string) $base;
        $original = $slug;
        $counter = 1;

        while (Tenant::query()->where('slug', $slug)->exists()) {
            $slug = "{$original}-{$counter}";
            $counter++;
        }

        return $slug;
    }
}
