<?php

namespace App\Development\Billing;

use Illuminate\Http\Client\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Http;
use Random\Engine\PcgOneseq128XslRr64;
use Random\Randomizer;

class Routes
{

    // Billing directory - the customers/services catalogue an org's overage options are drawn from.
    public function list(array $params, Request $request)
    {
        return Http::response(json_decode(file_get_contents(app_path('Development/Billing/Directory.json')), true), 200);
    }

    /*
     * Usage chart for an overage service over a period. Seeded on service+window so a given
     * circuit renders identically across reloads (deterministic, not random). Emits four
     * circuits plus an aggregate; /v{n} paths use in/out keys, the legacy path bw_in/bw_out.
     */
    public function graph(array $params, Request $request)
    {

        $engine = new PcgOneseq128XslRr64(crc32($params['start'] . $params['finish'] . $params['service']));

        $randomizer = new Randomizer($engine);

        $charts = [];

        $start = Carbon::parse($params['start'])->unix();
        $finish = Carbon::parse($params['finish'])->unix();
        $step = floor($finish-$start) / 360;

        $in_key = str_contains($request->url(), '/v') ? 'in' : 'bw_in';
        $out_key = str_contains($request->url(), '/v') ? 'out' : 'bw_out';

        $aggregate_formatted = [];
        $aggregate_quantile = 0;

        for($chart_i = 0; $chart_i < 4; ++$chart_i) {

            $data_formatted = [];
            $data_raw = [];

            for($data_i = $start; $data_i < $finish; $data_i += $step) {
                $size = $randomizer->getInt(1, 5);
                $x = $randomizer->getFloat(0, 5 % $size ? 5 % $size : $size);
                $y = $randomizer->getFloat(-5 % -$size ? -5 % -$size : -$size, 0);

                $data_raw[] = $x;
                $data_raw[] = $y * -1;

                $data_formatted[$data_i] = [
                    'key' => Carbon::parse($data_i)->format('Y-m-d H:i:s'),
                    'points' => [
                        [ 'category' => $in_key, 'value' => $y ],
                        [ 'category' => $out_key, 'value' => $x ]
                    ]
                ];

                if(isset($aggregate_formatted[$data_i])) {
                    foreach($aggregate_formatted[$data_i]['points'] as $key => $point) {
                        if($point['category'] == $in_key) {
                            $aggregate_formatted[$data_i]['points'][$key]['value'] += $y;
                        }
                        else {
                            $aggregate_formatted[$data_i]['points'][$key]['value'] += $x;
                        }
                    }
                }
                else {
                    $aggregate_formatted[$data_i] = [
                        'key' => Carbon::parse($data_i)->format('Y-m-d H:i:s'),
                        'points' => [
                            [ 'category' => $in_key, 'value' => $y ],
                            [ 'category' => $out_key, 'value' => $x ]
                        ]
                    ];
                }
            }

            sort($data_raw);
            $quantile = $data_raw[(int) floor(sizeof($data_raw) * 0.95)];
            $aggregate_quantile += $quantile;

            $charts[] = [
                '95th' => $quantile,
                'captioning' => [
                    'circuit_id' => "EXAMPLE-$chart_i",
                    'friendly_name' => "Example Chart #$chart_i",
                    'cost' =>  max(0, $quantile - $params['commit']) * $params['price'] . ' ' . $params['unit'],
                    'overrage' => max(0, $quantile - $params['commit'])
                ],
                'categories' => [
                    [ 'name' => $in_key ],
                    [ 'name' => $out_key ]
                ],
                'data' => $data_formatted
            ];

        }

        $charts[] = [
            '95th' => $aggregate_quantile,
            'captioning' => [
                'circuit_id' => "AGGREGATE",
                'friendly_name' => "Aggregate",
                'cost' =>  max(0, $aggregate_quantile - $params['commit']) * $params['price'] . ' ' . $params['unit'],
                'overrage' => max(0, $aggregate_quantile - $params['commit'])
            ],
            'categories' => [
                [ 'name' => $in_key ],
                [ 'name' => $out_key ]
            ],
            'data' => $aggregate_formatted
        ];

        return Http::response($charts, 200);
    }

    // Acknowledges an overage invoice pushed to the billing microservice.
    public function invoice(array $params, Request $request)
    {
        return Http::response([ 'Success' ], 200);
    }

}
