<?php

namespace OtomaticAi\Models\Usages;

use OtomaticAi\Vendors\Carbon\Carbon;
use OtomaticAi\Vendors\Carbon\CarbonPeriod;
use OtomaticAi\Vendors\Illuminate\Database\Capsule\Manager as Database;
use OtomaticAi\Vendors\Illuminate\Support\Arr;

class StabilityAIUsage extends Usage
{
    static private $prices = [
        "stable-diffusion-xl-1024-v0-9" => 0.016,
        "stable-diffusion-xl-1024-v1-0" => 0.016,
        "stable-diffusion-xl-beta-v2-2-2" => 0.016,
        "stable_image_core" => 0.03,
        "stable_image_sd3_medium" => 0.035,
        "stable_image_sd3_turbo" => 0.04,
        "stable_image_sd3_large_turbo" => 0.04,
        "stable_image_sd3" => 0.065,
        "stable_image_sd3_large" => 0.065,
        "stable_image_sd3_5_large_turbo" => 0.04,
        "stable_image_sd3_5_large" => 0.065,
        "stable_image_ultra" => 0.08,
    ];

    /**
     * Get a new query builder for the model's table.
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function newQuery()
    {
        return $this->registerGlobalScopes($this->newQueryWithoutScopes())
            ->where('provider', 'stability_ai');
    }

    static public function monthly(int $months = 12, int $diff = 0)
    {
        $start = Carbon::now()->subMonth($months - 1)->startOfMonth();
        $stop = Carbon::now()->subMonth($diff)->endOfMonth();
        $usages = self::query()
            ->select([
                Database::raw("DATE_FORMAT(created_at, '%Y-%m') as 'month_date'"),
                Database::raw("JSON_UNQUOTE(JSON_EXTRACT(payload, '$.engine')) as 'engine'"),
                Database::raw("SUM(JSON_UNQUOTE(JSON_EXTRACT(payload, '$.artifacts'))) as 'artifacts'"),
            ])
            ->groupBy([
                Database::raw("DATE_FORMAT(created_at, '%Y-%m')"),
                'engine'
            ])
            ->whereBetween('created_at', [$start, $stop])
            ->get();

        $usages = $usages->groupBy(['month_date', 'engine']);

        $output = [];
        $period = CarbonPeriod::since($start)->month()->until($stop);
        foreach ($period as $date) {
            $date = $date->format('Y-m');

            $o = [
                "amount" => 0,
                "details" => [],
            ];

            if ($usages->has($date)) {
                foreach ($usages->get($date) as $engine => $usagesForEngine) {
                    if (!isset($o["details"][$engine])) {
                        $o["details"][$engine] = 0;
                    }

                    foreach ($usagesForEngine as $usage) {
                        $o["details"][$engine] += self::calculateCosts($engine, $usage->artifacts);
                    }
                    $o["amount"] += $o["details"][$engine];
                }
            }

            $output[$date] = $o;
        }

        return $output;
    }

    static private function calculateCosts($engine, $artifacts)
    {
        $pricePerArtifact = Arr::get(self::$prices, $engine, 0);

        return $artifacts * $pricePerArtifact;
    }
}
