<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Http;
use Illuminate\Http\Request;
use App\Models\Education;
use App\Models\NextOfKin;
use App\Models\Guarantor;
use App\Models\Deployment;
use App\Models\BranchOffice;
use App\Models\Unit;
use App\Models\Imprest;
use App\Models\User;
use Illuminate\Support\Str;

class AdminController extends Controller
{
    public function dashboard(Request $request)
    {
        $users = User::paginate(100);
        $imprests = Imprest::paginate(100);
        $totalUser = User::count();
        $totalImprest = Imprest::count();
        $totalClient = User::where('type', '=', 'client')->count();
        $totalStusent = User::where('type', '=', 'student')->count();
        $theUnits = Unit::get();
        $theBranchs = BranchOffice::get();
        return view('admin.index', ["users" => $users, "theUnits" => $theUnits, "theBranchs" => $theBranchs, "imprests" => $imprests, "totalImprest" => $totalImprest, "totalUser" => $totalUser, "totalClient" => $totalClient, "totalStusent" => $totalStusent]);
    }

    public function users(Request $request)
    {
        $users = User::paginate(100);
        $totalUser = User::count();
        $totalClient = User::where('type', '=', 'client')->count();
        $totalStaff = User::where('type', '=', 'staff')->count();
        $totalStusent = User::where('type', '=', 'student')->count();
        $theUnits = Unit::get();
        $theBranchs = BranchOffice::get();
        return view('admin.users', ["users" => $users, "theUnits" => $theUnits, "theBranchs" => $theBranchs, "totalUser" => $totalUser, "totalClient" => $totalClient, "totalStaff" => $totalStaff, "totalStusent" => $totalStusent]);
    }
    public function deployments(Request $request)
    {
        $credentials = $request->validate([
            'userID' => ['required'],
            'branchId' => ['required'],
            'unitId' => ['required'],
            'positions' => ['required'],
        ]);

        $user = User::where('id', '=', $credentials["userID"])->where("type", "=", "staff")->first();
        if (!$user) {
            return back()->withErrors([
                'userId' => 'Users details do not match our records.',
            ])->withInput();
        }
        $branchOffice = BranchOffice::where('id', '=', $credentials["branchId"])->first();
        if (!$branchOffice) {
            return back()->withErrors([
                'userId' => 'Branch  details do not match our records.',
            ])->withInput();
        }

        $unit = Unit::where('id', '=', $credentials["unitId"])->first();
        if (!$unit) {
            return back()->withErrors([
                'userId' => 'Unit details do not match our records.',
            ])->withInput();
        }

        $clientDetails = User::where('id', '=', $unit->client_id)->where("type", "=", "client")->first();
        if (!$clientDetails) {
            return back()->withErrors([
                'userId' => 'Client details do not match our records.',
            ])->withInput();
        }

        // check if user has already been assigned to a unit

        $checkAsigned = Deployment::where('id', '=', $unit->id)->where("user_id", "=", $user->id)->count();
        if ($checkAsigned>0) {
            return back()->withErrors([
                'userId' => 'Staff already deployed, please undeploy this staff to redeploy',
            ])->withInput();
        }

        $deployment = new Deployment();
        $deployment->user_id = $user->id;
        $deployment->branch_id = $branchOffice->id;
        $deployment->client_id = $unit->client_id;
        $deployment->unit_id = $unit->id;
        $deployment->position = $credentials["positions"];
        $deployment->save();

        // send sms notification to clint and staff

        $dataClient = array(
            "api_key" => config('app.TERMII_API_KEY'),
            "to" => $clientDetails->phone,
            "from" => "N-Alert",
            "sms" => "Hello  " . $clientDetails->firstName . "!  SPS are pleased to inform you that ". $user->firstName. " has just been deployed to your unit . ",
            "type" => "plain",
            "channel" => "dnd"
        );
        $response = Http::post('https://v3.api.termii.com/api/sms/send', $dataClient);
        $response->json();

        $dataStaff = array(
            "api_key" => config('app.TERMII_API_KEY'),
            "to" =>  $user->phone,
            "from" => "N-Alert",
            "sms" => "Hello  " .  $user->firstName . "! SPS new deployment Add: " .$unit->address. " Phone: ".$unit->phone,
            "type" => "plain",
            "channel" => "dnd"
        );
        $response = Http::post('https://v3.api.termii.com/api/sms/send', $dataStaff);
        $response->json();

        $message = "Deployment successfull.";
        return back()->with('message', $message);

    }
    public function approveUser(Request $request)
    {
        $credentials = $request->validate([
            'userId' => ['required'],
        ]);
        $user = User::where('id', '=', $credentials["userId"])->first();
        if (!$user) {
            return back()->withErrors([
                'userId' => 'Users details do not match our records.',
            ])->withInput();
        }

        User::where('id', '=',  $user->id)->update([
            "status" => "active",
            'updated_at' => Carbon::now()
        ]);

        // send email notification to user for active account

        $message = "Account approved successfully";
        return back()->with('message', $message);
    }
    public function userProfile($groupId)
    {
        $user = User::where('id', '=', $groupId)->first();
        $education = Education::where('user_id', '=', $groupId)->get();
        $nextOfKin = NextOfKin::where('user_id', '=', $groupId)->first();
        $guarantor = Guarantor::where('user_id', '=', $groupId)->get();

        return view('admin.userProfile', ["user" => $user, "educations" => $education, "nextOfKin" => $nextOfKin, "guarantor" => $guarantor]);
    }

    public function imprest(Request $request)
    {
        $countInvoice = Imprest::count();
        $approvedInvoice = Imprest::where('status', '=', "approved")->orwhere('status', '=', "paid")->count();
        $pendingInvoice = Imprest::where('status', '=', "pending")->count();
        $canceledInvoice = Imprest::where('status', '=', "canceled")->count();
        $loadedInvoice = Imprest::get();

        return view('admin.Imprest', ["invoices" => $loadedInvoice, "countInvoice" => $countInvoice, "approvedInvoice" => $approvedInvoice, "pendingInvoice" => $pendingInvoice, "canceledInvoice" => $canceledInvoice]);
    }

    public function approveImprest(Request $request)
    {
        $credentials = $request->validate([
            'invoiceId' => ['required'],
        ]);

        $getInvoice = Imprest::where('status', '=', "pending")->where('id', '=',  $credentials["invoiceId"])->first();
        if (!$getInvoice) {
            return back()->withErrors([
                'invoce' => 'The provided details do not match our records.',
            ])->withInput();
        }
        Imprest::where('id', '=',  $getInvoice->id)->update([
            "status" => "approved",
            "approved_id" => Auth::id(),
            'updated_at' => Carbon::now()
        ]);
        // send to finace to pay or cancle request
        $message = "Imprest approved successfully. Pending payment";
        return back()->with('message', $message);
    }
    public function approveImprestPayout(Request $request)
    {
        $credentials = $request->validate([
            'invoiceId' => ['required'],
        ]);

        $getInvoice = Imprest::where('status', '=', "approved")->where('id', '=',  $credentials["invoiceId"])->first();
        if (!$getInvoice) {
            return back()->withErrors([
                'invoce' => 'The provided details do not match our records.',
            ])->withInput();
        }
        Imprest::where('id', '=',  $getInvoice->id)->update([
            "status" => "paid",
            "paid_id" => Auth::id(),
            'updated_at' => Carbon::now()
        ]);

        // create transaction recore 

        $ref = "securepoint_" . Str::random(8);
        $narration = "Transfer of ₦" . number_format($getInvoice->amount / 100) . " to " . $getInvoice->accountNumber . " " . $getInvoice->accountName;
        $data = array(
            "account_number" => $getInvoice->accountNumber,
            "account_bank" =>  $getInvoice->bankCode,
            "amount" =>  $getInvoice->amount / 100,
            "narration" =>  $narration,
            "currency" =>  "NGN",
            "reference" =>  $ref,
            "debit_currency" =>  "NGN",
        );
        $response = Http::withHeaders([
            'Authorization' =>  config('app.FLW_TOKEN'),
            'Content-Type' => 'application/json'
        ])->post('https://api.flutterwave.com/v3/transfers', $data);
        $responseData = $response->json();
        if ($responseData["status"] === "success") {
            Imprest::where('id', '=',  $getInvoice->id)->update([
                "meta" => json_encode($responseData["data"]),
                'updated_at' => Carbon::now()
            ]);
        }
        $message = "Transfer Queued Successfully";
        return back()->with('message', $message);
    }
    public function cancelImprest(Request $request)
    {
        $credentials = $request->validate([
            'invoiceId' => ['required'],
        ]);

        $getInvoice = Imprest::where('id', '=',  $credentials["invoiceId"])->first();
        if (!$getInvoice) {
            return back()->withErrors([
                'invoce' => 'The provided details do not match our records.',
            ])->withInput();
        }
        Imprest::where('id', '=',  $getInvoice->id)->update([
            "status" => "canceled",
            'updated_at' => Carbon::now()
        ]);

        $message = "Imprest canceled successfully.";
        return back()->with('message', $message);
    }

    public function units(Request $request)
    {
        $countUnit = Unit::count();
        $approvedInvoice = Imprest::where('status', '=', "approved")->orwhere('status', '=', "paid")->count();
        $pendingInvoice = Imprest::where('status', '=', "pending")->count();
        $canceledInvoice = Imprest::where('status', '=', "canceled")->count();
        $loadedInvoice = Imprest::get();

        // return view('admin.Imprest', ["invoices" => $loadedInvoice, "countInvoice" => $countInvoice, "approvedInvoice" => $approvedInvoice, "pendingInvoice" => $pendingInvoice, "canceledInvoice" => $canceledInvoice]);
    }
    public function settingsUnit(Request $request)
    {
        $units = Unit::get();
        $branchs = BranchOffice::get();
        return view('admin.settings-unit', ["units" => $units, "branchs" => $branchs]);
    }
    public function settings(Request $request)
    {
        $branchs = BranchOffice::get();

        return view('admin.settings', ["branchs" => $branchs]);
    }
    public function unitCreate(Request $request)
    {
        $credentials = $request->validate([
            'name' => ['required'],
            'address' => ['required'],
            'email' => ['required'],
            'phone' => ['required'],
            'branchId' => ['required'],
            'client' => ['required'],
        ]);

        // send email notification 
        // etc

        $newPhone = $credentials["client"];
        if (substr($newPhone, 0, 1) == 0) {
            $newPhone = "234" . substr($newPhone, 1);
        }

        $clientDetails = User::where('email', '=', $credentials["client"])->orWhere('phone', '=', $newPhone)->first();
        if (!$clientDetails) {
            return back()->withErrors([
                'client' => 'Client details not found.',
            ])->withInput();
        }
        $branchOffice = BranchOffice::where('id', '=', $credentials["branchId"])->first();
        if (!$branchOffice) {
            return back()->withErrors([
                'client' => 'Branch details not found.',
            ])->withInput();
        }
        $unit = new Unit();
        $unit->name = $credentials["name"];
        $unit->email = $credentials["email"];
        $unit->phone = $credentials["phone"];
        $unit->status = "pending";
        $unit->address = $credentials["address"];
        $unit->branch_id =  $branchOffice->id;
        $unit->client_id = $clientDetails->id;
        $unit->save();
        $message = "Unit created successfully.";
        return back()->with('message', $message);
    }

    public function branchCreate(Request $request)
    {
        $credentials = $request->validate([
            'name' => ['required'],
            'address' => ['required'],
            'country' => ['required'],
            'state' => ['required'],
            'lga' => ['required'],
        ]);

        $branchOffice = new BranchOffice();
        $branchOffice->name = $credentials["name"];
        $branchOffice->address = $credentials["address"];
        $branchOffice->lga = $credentials["lga"];
        $branchOffice->state = $credentials["state"];
        $branchOffice->country = $credentials["country"];
        $branchOffice->save();
        $message = "Branch office created successfully.";
        return back()->with('message', $message);
    }
    public function approveBranch(Request $request)
    {
        $credentials = $request->validate([
            'branchId' => ['required'],
        ]);
        BranchOffice::where('id', '=',  $credentials["branchId"])->where("status", "=", "pending")->update([
            "status" => "operational",
            'updated_at' => Carbon::now()
        ]);

        $message = "Branch office approved successfully.";
        return back()->with('message', $message);
    }
}
