<?php

namespace App\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Habit extends Model
{
    use HasFactory;

    protected $fillable = [
        'name',
        'user_id',
        'type',
        'value',
        'suffix',
        'schedule_value',
        'schedule_unit',
        'schedule_start',
        'goal_type',
        'goal_value',
        'goal_unit',
        'goal_start'
    ];

    public function isDueToday(): bool
    {
        // Goal - none? Not due today.
        if ($this->goal_type == 'none') {
            return false;
        }

        // Goal - if present, use its values
        if ($this->goal_type == 'custom') {
            $start = $this->goal_start;
            $unit = $this->goal_unit;
            $value = $this->goal_value;
        } else {
            $start = $this->schedule_start;
            $unit = $this->schedule_unit;
            $value = $this->schedule_value;
        }

        // Count from starting date to today - *should* there be an entry today?
        $testdate = new Carbon($start);

        while ($testdate->lt(today())) {
            $testdate = $testdate->add($unit, $value);
        }

        if ($testdate->eq(today())) {
            $entries = Entry::whereBelongsTo($this)->get();
            foreach ($entries as $entry) {
                if ($entry->date == today()->format('Y-m-d')) {
                    return false; // Entry for today already found; not due
                }
            }
            return true; // Test date == today, but no entry found yet
        }
        return false; // Test date overshot; isn't due today
    }

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

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    public function tags(): BelongsToMany
    {
        return $this->BelongsToMany(Tag::class);
    }

    public function category(): BelongsTo
    {
        return $this->belongsTo(Category::class);
    }
}
