<?php

namespace App\Models;

use App\Core\Database;
use App\Core\Cache;

/**
 * CompanySubscriptionUsage Model
 * Tracks API usage stats per company dynamically linked to active billing cycles.
 */
class CompanySubscriptionUsage extends BaseModel
{
    protected static string $table = 'company_subscription_usage';

    /**
     * Get or initialize usage record for the active billing cycle of a company
     */
    public static function getOrCreateCurrentUsage(int $companyId, array $activeSubscription): array
    {
        $billingStart = date('Y-m-d', strtotime($activeSubscription['starts_at']));
        $billingEnd = date('Y-m-d', strtotime($activeSubscription['ends_at']));

        $cacheKey = "company_usage_{$companyId}_{$billingStart}_{$billingEnd}";

        $cached = Cache::get($cacheKey);
        if ($cached) {
            return $cached;
        }

        // Check if usage record already exists in database
        $usage = Database::selectOne(
            "SELECT * FROM " . static::$table . " 
             WHERE company_id = ? AND billing_start = ? AND billing_end = ? 
             LIMIT 1",
            [$companyId, $billingStart, $billingEnd]
        );

        if (!$usage) {
            // Initialize new record
            try {
                $id = self::create([
                    'company_id' => $companyId,
                    'billing_start' => $billingStart,
                    'billing_end' => $billingEnd,
                    'request_count' => 0,
                    'voice_count' => 0,
                    'ocr_count' => 0
                ]);
                $usage = [
                    'id' => $id,
                    'company_id' => $companyId,
                    'billing_start' => $billingStart,
                    'billing_end' => $billingEnd,
                    'request_count' => 0,
                    'voice_count' => 0,
                    'ocr_count' => 0
                ];
            } catch (\Exception $e) {
                // Handle concurrent insertions gracefully
                $usage = Database::selectOne(
                    "SELECT * FROM " . static::$table . " 
                     WHERE company_id = ? AND billing_start = ? AND billing_end = ? 
                     LIMIT 1",
                    [$companyId, $billingStart, $billingEnd]
                );
                if (!$usage) {
                    throw $e;
                }
            }
        }

        // Cache usage data for 60 seconds (short TTL since usage changes frequently)
        Cache::set($cacheKey, $usage, 60);

        return $usage;
    }

    /**
     * Increment usage counts for the current billing cycle
     */
    public static function incrementUsage(int $companyId, string $type = 'request', int $amount = 1): bool
    {
        $activeSub = CompanySubscription::findActiveByCompany($companyId);
        if (!$activeSub) {
            return false;
        }

        $currentUsage = self::getOrCreateCurrentUsage($companyId, $activeSub);

        $column = 'request_count';
        if ($type === 'voice') {
            $column = 'voice_count';
        } elseif ($type === 'ocr') {
            $column = 'ocr_count';
        }

        $success = Database::execute(
            "UPDATE " . static::$table . " 
             SET {$column} = {$column} + ? 
             WHERE id = ?",
            [$amount, $currentUsage['id']]
        ) > 0;

        if ($success) {
            // Sync Redis cache with incremented values
            $cacheKey = "company_usage_{$companyId}_{$currentUsage['billing_start']}_{$currentUsage['billing_end']}";
            $cached = Cache::get($cacheKey);
            if ($cached) {
                $cached[$column] += $amount;
                Cache::set($cacheKey, $cached, 60);
            }
        }

        return $success;
    }

    /**
     * Check if a company has exceeded its plan limits for a certain action
     */
    public static function hasRemainingLimit(int $companyId, string $type = 'request'): bool
    {
        $activeSub = CompanySubscription::findActiveByCompany($companyId);
        if (!$activeSub) {
            return false; // No active subscription means no requests allowed
        }

        $usage = self::getOrCreateCurrentUsage($companyId, $activeSub);

        if ($type === 'request') {
            return $usage['request_count'] < $activeSub['max_requests'];
        } elseif ($type === 'voice') {
            return $usage['voice_count'] < $activeSub['max_voice_requests'];
        } elseif ($type === 'ocr') {
            return $usage['ocr_count'] < $activeSub['max_ocr_requests'];
        }

        return false;
    }
}
