<?php

namespace App\Models;

use App\Models\Concerns\BelongsToOwner;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;

class Practitioner extends Model
{
    use BelongsToOwner, SoftDeletes;

    protected $table = 'care_practitioners';

    protected $fillable = [
        'owner_ref', 'organization_id', 'branch_id', 'department_id', 'member_id',
        'user_ref', 'name', 'specialty', 'room', 'is_active',
    ];

    protected function casts(): array
    {
        return ['is_active' => 'boolean'];
    }

    public function organization(): BelongsTo
    {
        return $this->belongsTo(Organization::class, 'organization_id');
    }

    public function branch(): BelongsTo
    {
        return $this->belongsTo(Branch::class, 'branch_id');
    }

    /**
     * Explicitly assigned branches (telemedicine may include several). Empty = unassigned.
     */
    public function branches(): BelongsToMany
    {
        return $this->belongsToMany(Branch::class, 'care_practitioner_branch', 'practitioner_id', 'branch_id')
            ->withTimestamps();
    }

    public function department(): BelongsTo
    {
        return $this->belongsTo(Department::class, 'department_id');
    }

    public function member(): BelongsTo
    {
        return $this->belongsTo(Member::class, 'member_id');
    }

    public function schedules(): HasMany
    {
        return $this->hasMany(PractitionerSchedule::class, 'practitioner_id');
    }

    public function appointments(): HasMany
    {
        return $this->hasMany(Appointment::class, 'practitioner_id');
    }

    /**
     * Specialty dropdown options. Preserves a legacy/custom value when editing.
     *
     * @return list<string>
     */
    public static function specialtyOptions(?string $current = null): array
    {
        $options = array_values(array_filter(
            config('care.practitioner_specialties', []),
            fn ($label) => is_string($label) && $label !== '',
        ));

        if ($current !== null && $current !== '' && ! in_array($current, $options, true)) {
            $options[] = $current;
        }

        return $options;
    }

    /**
     * Select option label — includes branch context when available.
     */
    public function labelForSelect(): string
    {
        $branchNames = [];
        if ($this->relationLoaded('branches') && $this->branches->isNotEmpty()) {
            $branchNames = $this->branches->pluck('name')->filter()->values()->all();
        } elseif ($this->relationLoaded('branch') && $this->branch?->name) {
            $branchNames = [$this->branch->name];
        } elseif ($this->branch_id) {
            $name = $this->branch()?->value('name');
            if ($name) {
                $branchNames = [$name];
            }
        }

        if ($branchNames === []) {
            return (string) $this->name;
        }

        return $this->name.' — '.implode(', ', $branchNames);
    }

    /**
     * @return list<int>
     */
    public function assignedBranchIds(): array
    {
        $ids = $this->relationLoaded('branches')
            ? $this->branches->pluck('id')->all()
            : $this->branches()->pluck('care_branches.id')->all();

        if ($ids === [] && $this->branch_id) {
            return [(int) $this->branch_id];
        }

        return array_values(array_unique(array_map('intval', $ids)));
    }

    /**
     * @param  list<int|string>  $branchIds
     */
    public function syncAssignedBranches(array $branchIds): void
    {
        if (! \Illuminate\Support\Facades\Schema::hasTable('care_practitioner_branch')) {
            $ids = array_values(array_unique(array_filter(array_map('intval', $branchIds))));
            $this->forceFill(['branch_id' => $ids[0] ?? null])->save();

            return;
        }

        $ids = array_values(array_unique(array_filter(array_map('intval', $branchIds))));
        $this->branches()->sync($ids);
        $this->forceFill([
            'branch_id' => $ids[0] ?? null,
        ])->save();
    }
}
