<?php

namespace App\Services;

use App\Models\Branch;
use App\Models\Department;
use App\Models\TrainingType;
use App\Models\User;
use Illuminate\Support\Collection;

class MalawiTerritoryTrainingService
{
    public const COMPANY_SLUG = MalawiTerritoryRosterSync::COMPANY_SLUG;

    /** @var array<string, TrainingType> */
    private array $trainingTypes = [];

    public function seedForCompany(?User $company = null): array
    {
        $company = $company ?? $this->resolveCompany();
        $this->trainingTypes = [];

        foreach (config('malawi_territory_training.types', []) as $definition) {
            $branch = $this->resolveBranch($company, $definition['branch'] ?? null, $definition['scope'] ?? null);

            if (! $branch) {
                continue;
            }

            $trainingType = TrainingType::updateOrCreate(
                [
                    'created_by' => $company->id,
                    'name' => $definition['name'],
                ],
                [
                    'description' => $definition['description'],
                    'branch_id' => $branch->id,
                ]
            );

            $departments = $this->resolveDepartments($company, $definition);
            if ($departments->isNotEmpty()) {
                $trainingType->departments()->sync($departments->pluck('id')->all());
            }

            $this->trainingTypes[$definition['name']] = $trainingType;
        }

        return [
            'training_types' => count($this->trainingTypes),
        ];
    }

    public function trainingType(string $name, ?User $company = null): ?TrainingType
    {
        if (isset($this->trainingTypes[$name])) {
            return $this->trainingTypes[$name];
        }

        $company ??= $this->resolveCompany();

        return TrainingType::where('created_by', $company->id)
            ->where('name', $name)
            ->first();
    }

    private function resolveBranch(User $company, ?string $branchKey, ?string $scope): ?Branch
    {
        if ($scope === 'field') {
            return Branch::where('created_by', $company->id)
                ->where('name', '!=', config('malawi_territory_training.default_branch', 'THQ'))
                ->orderBy('name')
                ->first();
        }

        $branchName = $branchKey ?? config('malawi_territory_training.default_branch', 'THQ');

        return Branch::where('created_by', $company->id)
            ->where('name', $branchName)
            ->first();
    }

    /**
     * @param  array<string, mixed>  $definition
     */
    private function resolveDepartments(User $company, array $definition): Collection
    {
        if (($definition['departments'] ?? null) === 'all') {
            return Department::where('created_by', $company->id)->get();
        }

        if (($definition['scope'] ?? null) === 'field') {
            $thq = config('malawi_territory_training.default_branch', 'THQ');

            return Department::where('created_by', $company->id)
                ->whereHas('branch', fn ($q) => $q->where('name', '!=', $thq))
                ->get();
        }

        $names = $definition['departments'] ?? [];

        if ($names === []) {
            return collect();
        }

        return Department::where('created_by', $company->id)
            ->whereIn('name', $names)
            ->get();
    }

    private function resolveCompany(): User
    {
        $company = User::where('slug', self::COMPANY_SLUG)->where('type', 'company')->first();
        if (! $company) {
            throw new \RuntimeException('Malawi Territory company not found.');
        }

        return $company;
    }
}
