<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Form extends Model
{
    protected $fillable = [
        'title',
        'description',
        'created_by',
        'is_active',
    ];

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

    public function creator(): BelongsTo
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    public function fields(): HasMany
    {
        return $this->hasMany(FormField::class)->orderBy('order');
    }

    public function topLevelFields(): HasMany
    {
        return $this->hasMany(FormField::class)->whereNull('parent_id')->orderBy('order');
    }

    /**
     * Build a nested tree of fields from the flat fields collection.
     * Each field has its `children` relation populated.
     */
    public function fieldsTree(): Collection
    {
        $all = $this->fields()->get();
        $byParent = $all->groupBy('parent_id');

        $attach = function ($parentId) use (&$attach, $byParent) {
            return ($byParent[$parentId] ?? collect())->map(function ($field) use (&$attach) {
                $field->setRelation('children', $attach($field->id));
                return $field;
            })->values();
        };

        return new Collection($attach(null)->all());
    }

    public function filiales(): BelongsToMany
    {
        return $this->belongsToMany(Filiale::class, 'form_filiale')
            ->withPivot(['due_date', 'status'])
            ->withTimestamps();
    }

    public function submissions(): HasMany
    {
        return $this->hasMany(FormSubmission::class);
    }

    public function isAssignedTo(?Filiale $filiale): bool
    {
        if ($filiale === null) {
            return false;
        }

        return $this->filiales()->whereKey($filiale->id)->exists();
    }
}
