<?php

namespace App\Services\Meet;

use App\Models\Branch;
use App\Models\Member;
use App\Models\Organization;
use App\Models\User;
use Illuminate\Support\Str;

class OrganizationResolver
{
    public function resolveForUser(User $user): ?Organization
    {
        $ref = $user->ownerRef();

        $member = Member::where('user_ref', $ref)->first();
        if ($member) {
            return Organization::find($member->organization_id);
        }

        return Organization::owned($ref)->first();
    }

    public function forUser(User $user): Organization
    {
        return $this->resolveForUser($user)
            ?? throw new \RuntimeException('No organization for user.');
    }

    public function isOnboarded(User $user): bool
    {
        $organization = $this->resolveForUser($user);

        return $organization !== null
            && (bool) data_get($organization->settings, 'onboarded', false);
    }

    public function memberFor(User $user, ?Organization $organization = null): ?Member
    {
        $organization ??= $this->resolveForUser($user);
        if (! $organization) {
            return null;
        }

        return Member::where('organization_id', $organization->id)
            ->where('user_ref', $user->ownerRef())
            ->first();
    }

    public function ensureOwnerMember(User $user, Organization $organization): Member
    {
        return Member::firstOrCreate(
            [
                'organization_id' => $organization->id,
                'user_ref' => $user->ownerRef(),
            ],
            [
                'owner_ref' => $user->ownerRef(),
                'role' => 'owner',
            ],
        );
    }

    /**
     * @param  array<string, mixed>  $data
     */
    public function completeOnboarding(User $user, array $data): Organization
    {
        $ref = $user->ownerRef();

        $organization = Organization::create([
            'owner_ref' => $ref,
            'name' => $data['organization_name'],
            'slug' => Str::slug($data['organization_name']).'-'.substr($ref, 0, 6),
            'timezone' => $data['timezone'] ?? config('app.timezone', 'UTC'),
            'settings' => [
                'onboarded' => true,
                'org_type' => $data['org_type'] ?? 'business',
            ],
        ]);

        $this->ensureOwnerMember($user, $organization);

        $branch = Branch::create([
            'owner_ref' => $ref,
            'organization_id' => $organization->id,
            'name' => $data['branch_name'],
            'address' => $data['branch_address'] ?? null,
            'phone' => $data['branch_phone'] ?? null,
            'is_active' => true,
        ]);

        AuditLogger::record($ref, 'organization.created', $organization->id, $ref, Organization::class, $organization->id);
        AuditLogger::record($ref, 'branch.created', $organization->id, $ref, Branch::class, $branch->id);

        return $organization;
    }

    public function branchScope(?Member $member): ?int
    {
        if ($member === null) {
            return null;
        }

        if (in_array($member->role, ['owner', 'admin'], true)) {
            return null;
        }

        return $member->branch_id;
    }
}
