<?php

namespace App\Reporting\Concerns;

use App\Support\Period;
use Carbon\Carbon;

/**
 * Lets a report tile compute against a chosen date range (with a preceding equal-length window
 * for comparison). Defaults to the last 30 days vs the previous 30 days when no period is set.
 */
trait HasReportingPeriod
{
    private ?Period $period = null;

    public function forPeriod(?Period $period): static
    {
        $this->period = $period;

        return $this;
    }

    protected function windowStart(): Carbon
    {
        return $this->period
            ? Carbon::parse($this->period->startDate)->startOfDay()
            : Carbon::now()->subDays(30)->startOfDay();
    }

    protected function windowEnd(): Carbon
    {
        return $this->period
            ? Carbon::parse($this->period->endDate)->endOfDay()
            : Carbon::now()->endOfDay();
    }

    protected function windowLengthDays(): int
    {
        return $this->windowStart()->diffInDays($this->windowEnd()) + 1;
    }

    protected function previousStart(): Carbon
    {
        return $this->windowStart()->copy()->subDays($this->windowLengthDays());
    }

    protected function previousEnd(): Carbon
    {
        return $this->windowStart()->copy()->subDay()->endOfDay();
    }

    protected function periodSubtitle(): string
    {
        if (!$this->period) {
            return 'last 30 days';
        }

        return Carbon::parse($this->period->startDate)->format('j M') . ' – '
            . Carbon::parse($this->period->endDate)->format('j M');
    }

    protected function previousPeriodName(): string
    {
        return $this->period ? 'prev period' : 'prev 30 d.';
    }
}
