<?php

namespace App\Services;

use App\Models\DownloadLog;
use App\Models\Order;
use App\Models\User;

class DownloadLimitService
{
    /**
     * Resolve the daily_download_limit from the order item snapshot.
     * Returns null if no limit is set (unlimited).
     *
     * Reading from order_items (not the plan) ensures that admin changes
     * to the plan never retroactively affect existing orders.
     */
    private function getLimit(Order $order): ?int
    {
        $item = $order->items
            ->where('purchasable_type', 'App\Models\PricingTier')
            ->first();

        return $item?->daily_download_limit; // null = unlimited
    }

    /**
     * Count how many files have been downloaded today for this order.
     */
    private function usedToday(User $user, Order $order): int
    {
        return DownloadLog::forUser($user->id)
            ->forOrder($order->id)
            ->today()
            ->count();
    }

    /**
     * Returns null if the plan has no limit (unlimited).
     * Returns an int (0 or more) representing remaining downloads today.
     */
    public function getRemaining(User $user, Order $order): ?int
    {
        $limit = $this->getLimit($order);

        if ($limit === null) {
            return null;
        }

        return max(0, $limit - $this->usedToday($user, $order));
    }

    /**
     * Returns false only when a limit is set AND today's count has reached or exceeded it.
     */
    public function canDownload(User $user, Order $order): bool
    {
        $limit = $this->getLimit($order);

        if ($limit === null) {
            return true;
        }

        return $this->usedToday($user, $order) < $limit;
    }

    /**
     * Write one row to download_logs.
     * Call this after the file stream has been committed successfully.
     *
     * @param  int  $mediaId       Pass 0 for zip/bulk downloads (no single media).
     * @param  int  $productFileId The ProductFile (version) the download belongs to.
     */
    public function log(User $user, Order $order, int $mediaId, int $productFileId): void
    {
        DownloadLog::create([
            'user_id'         => $user->id,
            'order_id'        => $order->id,
            'media_id'        => $mediaId ?: null,
            'product_file_id' => $productFileId,
            'downloaded_at'   => now(),
        ]);
    }
}
