<?php

namespace App\Models;

use Config\Lookups;

/**
 * `category` is validated against App\Config\Lookups::$folioCategories,
 * a plain open-ended string set — see the migration comment for why.
 */
class FolioLineItemModel extends TenantModel
{
    protected $table            = 'folio_line_items';
    protected $primaryKey       = 'id';
    protected $useAutoIncrement = true;
    protected $returnType       = 'object';
    protected $useTimestamps    = true;

    protected $allowedFields = [
        'folio_id',
        'description',
        'amount',
        'category',
        'item_date',
        'created_by',
    ];

    public function __construct()
    {
        parent::__construct();

        $categories = (new Lookups())->folioCategoryKeys();

        $this->validationRules = [
            'folio_id'    => 'required|integer',
            'description' => 'required|max_length[255]',
            'amount'      => 'required|decimal',
            'category'    => 'permit_empty|in_list[' . implode(',', $categories) . ']',
            'item_date'   => 'required|valid_date[Y-m-d]',
        ];
    }

    public function forFolio(int $folioId): array
    {
        return $this->where('folio_id', $folioId)->orderBy('item_date', 'asc')->orderBy('id', 'asc')->findAll();
    }

    /**
     * Charges posted on a single day, regardless of category — the
     * dashboard's "Revenue Today" figure. Deliberately what was CHARGED
     * (item_date), not what was PAID (folio_payments.paid_at): a guest
     * checking out today pays off charges that may span their whole stay,
     * so "revenue" here means the room/F&B/event activity that happened
     * today, matching how the category breakdown below reads.
     */
    public function totalOn(string $date): string
    {
        return $this->totalBetween($date, $date);
    }

    public function totalBetween(string $startDate, string $endDate): string
    {
        $result = $this->where('item_date >=', $startDate)->where('item_date <=', $endDate)->selectSum('amount')->first();

        return $result->amount ?? '0.00';
    }

    /**
     * @return array<string, string> category => summed amount
     */
    public function byCategoryOn(string $date): array
    {
        return $this->byCategoryBetween($date, $date);
    }

    /** @return array<string, string> category => summed amount */
    public function byCategoryBetween(string $startDate, string $endDate): array
    {
        $rows = $this->select('category, SUM(amount) as total')
            ->where('item_date >=', $startDate)
            ->where('item_date <=', $endDate)
            ->groupBy('category')
            ->findAll();

        $out = [];

        foreach ($rows as $row) {
            $out[$row->category] = $row->total;
        }

        return $out;
    }
}
