<?php

namespace App\Http\Controllers\Billing;

use App\Http\Controllers\BaseController;
use App\Models\Billing\BillingCommit;
use App\Models\OrganisationExternalIdentities;
use App\Repositories\OverageRepository;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

class Controller extends BaseController
{


    public function get_overage_options() {

        /**
         * Select external identities relevant to GSL - There may be more than one.
         */
        
        $ids = OrganisationExternalIdentities::where([['key', '=', 'gsl'], ['organisation_id', '=', Auth::user()->organisation_id]])->get()->pluck('identity')->toArray() ?? [];

        if(sizeof($ids) === 0) {
            return response()->json([
                'services' => [],
                'periods' => []
            ]);
        } 

        /**
         * Select from billing services
         */

        $billing_information = Http::get(env('ENDPOINT_BILLING_MICROSERVICE_URL'), [ 'key' => env('ENDPOINT_BILLING_MICROSERVICE_SECRET')  ]);

        // Only accept valid services that belong to the user...
        $ungrouped_services = collect(array_filter($billing_information['billing_ids'], function($item) use($ids) {
        
            foreach(['id', 'client_id', 'name'] as $key) {
                if(!isset($item[$key])) {
                    return false;
                }
            }

            if(array_search($item['client_id'], $ids) === false) {
                return false;
            }

            return true;
        }));

        /**
         * General grouping 
         */

        $services = [];

        foreach($ungrouped_services as $item) {

            if(str_contains($item['name'], 'IPT') ) {
                $services[] = [
                    'service_id' => $item['id'],
                    'service_name' => $item['name']
                ];
            }

        }

        $periods = [];

        for($i = 0; $i < 6; ++$i) {
            $current_period = Carbon::now()->subMonth($i);

            if($current_period->year == 2025 && $current_period->month < 12) {
                break;
            }

            $periods[] = [
                'period' => $i,
                'label' => $current_period->isoFormat('MMMM YYYY') . ( $i == 0 ? ( ' ( ' . round(($current_period->day / $current_period->daysInMonth) * 100, 0) . '% )' ) : '' )
            ];
        }

        return response()->json([
            'services' => $services,
            'periods' => $periods
        ]);

    }

    public function get_chart(Request $_r) {

        // Retrieve client_id
        $client_ids = OrganisationExternalIdentities::where([['key', '=', 'gsl'], ['organisation_id', '=', Auth::user()->organisation_id]])->select('identity')->get()->toArray() ?? [];

        // Check whether the commit is the latest one
        $valid_request = !Validator::make([
            'service_id'    => $_r->input('service_id'),
            'period'        => $_r->input('period')
        ], [
            'service_id'    => ['required', Rule::in(BillingCommit::where('whmcs_brand', '=', 'gsl')->whereIn('whmcs_client_id', $client_ids)->select('whmcs_service_id')->get()->pluck('whmcs_service_id'))],
            'period'        => ['required', 'integer']
        ])->fails();

        if($valid_request) {

            // We use this frequently, reserve.
            $now = Carbon::now();

            // This is painful, we need to get the relevant commit for a given period. The first one that's relevant for a given period, really.
            $considered_month_start = Carbon::createFromDate($now->year, $now->month, 1, 'Australia/Sydney')->setHour(0)->setMinutes(0)->setSeconds(0)->subMonths($_r->input('period'));
            
            // Exit if we're looking at a month before our start period.
            if($considered_month_start->year == 2025 && $considered_month_start->month < 12) {
                return response()->json([ 'Invalid Period Supplied' ], 400);
            }
            
            // Get the commit finally.
            $commit = BillingCommit::where([ ['whmcs_service_id', '=', $_r->input('service_id')], ['effective_at', '<=', $considered_month_start] ])->orderBy('effective_at', 'desc')->first();

            // Get time related information
            $start = Carbon::createFromDate($now->year, $now->month, $commit->billing_day, 'Australia/Sydney')->setHour(0)->setMinutes(0)->setSeconds(0)->subMonths($_r->input('period'));
            $finish = Carbon::createFromDate($now->year, $now->month, $commit->billing_day, 'Australia/Sydney')->setHour(23)->setMinutes(59)->setSeconds(59)->addMonth()->subMonths($_r->input('period'))->subDay();

            // Return graph
            $graph = (new OverageRepository())->getGraph('gsl', $commit->whmcs_client_id, $_r->input('service_id'), $commit->search_service, $start->timestamp, $finish->timestamp, $commit->commit, 0, 'USD', 2, $commit->method);

            return response()->json($graph);
        }

        return response()->json([ 'Invalid Inputs Supplied' ], 400);
    }

}