<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreContractRequest;
use App\Http\Requests\UpdateContractRequest;
use App\Models\Client;
use App\Models\Contract;
use App\Models\ContractIprsService;
use App\Models\ContractIprsServiceGroup;
use App\Models\CustomSpatiePermission;
use App\Models\IprsNewService;
use App\Models\IprsNewServiceGroup;
use App\Models\Tokens;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Carbon;
use Illuminate\View\View;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
use Spatie\Permission\PermissionServiceProvider;
use Illuminate\Support\Facades\Http;

class ContractController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        $contracts = Contract::all();
        $services =IprsNewService::all();
        $tokens = Tokens::all();
        //return view
        return view('contract.contract', ['contracts' => $contracts, 'services' => $services, 'token' => $tokens]);
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create(): View
    {
        $contractPermissions =Permission::where("permission_type", "Contract")->get();
        //dd($contractPermissions);
        return view('contract.contractForm', ['contractPermissions'=>$contractPermissions ]);
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(StoreContractRequest $request)
    {
        $validated = $request->validated();
        $payment_type = match ($validated['payment_type'] ?? '') {
            "Post-paid" => 1,
            "Pre-paid" => 2,
            "Free" => 3,
            default => 0
        };

        $client_name = Client::where('rid', $validated['client_id'])->select('rid', 'name_sh')->first();
        // store the data
        $contract = Contract::create([
            'CLIENT_RID' => $validated['client_id'],
            'D_DOC' => $validated['issue_date'],
            'D_BGN' => $validated['begin_date'],
            'D_END' => $validated['expire_date'],
            'MANAGER_SURN' => $validated['surname'],
            'MANAGER_NAME' => $validated['name'],
            'MANAGER_OTHNAM' => $validated['other_name'],
            'MANAGER_POST' => $validated['post'],
            'MANAGER_PHONE' => $validated['phone'],
            'MANAGER_CELL' => $validated['cell'],
            'MANAGER_EMAIL' => $validated['email'],
            'IN_USE' => 1,
            'PAYMENT_TYPE' => $payment_type,
            'POSTED_BY_INTERNET' => ($request->filled("internet") && $validated['internet'] == "on") ? 1 : 0,
            //'POSTED_BY_EMAIL' => $validated[''],
            //'POSTED_BY_SMS' => $validated[''],
            'POSTED_BY_SERVICE' => ($request->filled("api") && $validated['api'] == "on") ? 1 : 0,
        ]);


        if($validated['api'] == 'on'){
            $apiStatus= $this->apiContract(str_replace(' ', '_', $client_name->name_sh), (int)$request->api_tokens,$contract['RID']);
        }
         //get RID
        $contract_role='CID-'.$contract['RID'];
        $servicePerm=$request['permissions'];

        //create role
        $role = Role::create(['name' => $contract_role, 'for_contract' => true]);
        //assign permissions
        $role->syncPermissions($servicePerm);

       // $currentTimestamp=Carbon::now();
        //save to contract group
        /*foreach ($serviceGroups as $serviceGroup) {
            $serviceGroupData[] = [
                'service_group_id' => $serviceGroup,
                'contract_id' => $contract_id,
                'created_at' => $currentTimestamp,
                'updated_at' => $currentTimestamp,
            ];
        }*/
        //Mass insert "insert"
        //ContractIprsServiceGroup::insert($serviceGroupData);

        // return a response to the user and redirect
        return redirect()->route('contract.index')->with("success", "Contract created successfully!");
    }

    /**
     * Display the specified resource.
     */
    public function show(Contract $contract)
    {
        $tokens = Tokens::with('contract')->get();
        //dd($tokens);
        return view('contract.contractDetails', ['contract' => $contract, 'token' => $tokens]);
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(Contract $contract)
    {
        $contractPermissions =Permission::where("permission_type", "Contract")->get();
        $serviceGroups =IprsNewServiceGroup::all();
        $services =IprsNewService::all();
        //
        return view('contract.contractEdit', ['contract' => $contract, 'contractPermissions'=>$contractPermissions , 'services'=> $services, 'serviceGroups'=>$serviceGroups ]);
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(UpdateContractRequest $request, Contract $contract)
    {
        // get the validated data
        $validated = $request->validated();
        $payment_type = match ($validated['payment_type'] ?? '') {
            "Post-paid" => 1,
            "Pre-paid" => 2,
            "Free" => 3,
            default => 0
        };

        $client_name = Client::where('rid', $validated['client_id'])->select('rid', 'name_sh')->first();
        // update the contract table
        Contract::query()->where('rid', $contract->rid)->update([
            'client_rid' => $validated['client_id'],
            'd_doc' => $validated['issue_date'],
            'd_bgn' => $validated['begin_date'],
            'd_end' => $validated['expire_date'],
            'manager_surn' => $validated['surname'],
            'manager_name' => $validated['name'],
            'manager_othnam' => $validated['other_name'],
            'manager_post' => $validated['post'],
            'manager_phone' => $validated['phone'],
            'manager_cell' => $validated['cell'],
            'manager_email' => $validated['email'],
            'payment_type' => $payment_type,
            'in_use' => $validated['in_use'],
            'posted_by_internet' => ($request->filled("internet") && $validated['internet'] == "on") ? 1 : 0,
            //'POSTED_BY_EMAIL' => $validated[''],
            //'POSTED_BY_SMS' => $validated[''],
            'posted_by_service' => ($request->filled("api") && $validated['api'] == "on") ? 1 : 0,
        ]);

      /* if($validated['api'] == 'on'){
            $apiStatus= $this->apiContract(str_replace(' ', '_',$client_name->name_sh), (int)$request->api_tokens, $contract->rid);
        }*/

        //get RID
        $contract_role='CID-'.$contract->rid;
        $servicePerm=$request['permissions'];
        //create role
        $role = Role::firstOrCreate(
            ['name' => $contract_role],
            ['for_contract' => true]);

        //assign permissions
        $role->syncPermissions($servicePerm);
        // return a response to the user and redirect
        return redirect()->route('contract.index')->with("success", "Contract updated successfully!");
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(Contract $contract)
    {
        //
    }

    private function apiContract($consumerName,$tokens, $cid): JsonResponse
    {
        $api_gateway= config('services.api_gateway.api_gateway_host').':'.
                      config('services.api_gateway.api_gateway_port').'/'.
                      config('services.api_gateway.api_gateway_admin').'/consumers';
        $response = Http::withHeaders([
            'X-API-KEY' => env('API_GATEWAY_APIKEY')
        ])->put($api_gateway, [
            "username" => $consumerName,
            "plugins" => [
                "jwt-auth" => [
                    "key" => base64_encode($consumerName),
                    "secret" => $consumerName,
                    "exp" => 172800
                ],
                "search-quota-redis" => [
                    "redis_host" => env('REDIS_HOST'),
                    "redis_port" => (int)env('REDIS_PORT'),
                    "redis_password" => env('REDIS_PASSWORD'),
                    "default_max_queries" => 0
                ]
            ]
        ]);

        if ($response->successful()) {
            //save it locally
            /*$tokens = Tokens::create([
                'TOTAL_TOKENS' => $tokens,
                'contract_id' => $cid,
            ]);*/
            return response()->json(["message" => "Consumer created successfully.", "data" => $response->json()]);
        } else {
            return response()->json(["error" => "Failed to create consumer.", "details" => $response->body()], $response->status());
        }
    }
}
