<?php

namespace App\Http\Controllers\V1\Admin;

use App\Http\Controllers\Controller;
use App\Models\Countries;
use App\Models\Currency;
use App\Models\Organization;
use App\Models\PoDetails;
use App\Models\POTaxInvoice;
use App\Models\PoGrn;
use App\Models\PurchaseOrder;
use App\Models\Quotation;
use App\Models\QuotChallan;
use App\Models\QuotOc;
use App\Models\RequestForQuotation;
use App\Models\User;
use App\Models\QuotProformaInvoice;
use App\Models\PoInward;
use App\Models\POReceiptVoucher;
use App\Models\ReceiptVoucher;
use App\Models\QuotTaxInvoice;
use App\Models\QuotTaxInvoiceProduct;
use App\Models\POTaxInvoiceProductsDetails;
use App\Models\ClientAddress;
use App\Models\PoInwardDetails;
use App\Models\PoGrnDetails;
use Carbon\CarbonPeriod;
use App\SchemaMetadata;
use App\Models\ReleventProduct;
use App\Models\products;
use Carbon\Carbon;
use DB;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Image;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;

class MetadataController extends Controller
{
    public function getSchemaMetadataByModuleName(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'module_name' => 'required|string|exists:schema_metadata,module_name',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getMetadata = SchemaMetadata::query()->where('module_name', $request->module_name)->first();

            return $this->sendResponse($getMetadata, 'Data fetch successfully', true);

        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function saveFile($image, $productName)
    {
        $imageName = $productName . '-' . rand(100, 9999) . '.webp';

        $destinationPath = public_path('poimage\\' . $imageName);
        if (env('APP_ENV') == 'prod') {
            $destinationPath = public_path('poimage/' . $imageName);
        }
        $img = Image::make(file_get_contents($image))
            ->resize(300, null)
            ->save($destinationPath, 80, 'webp');

        return '/poimage/' . $imageName;
    }
    public function getAllRole(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = Role::query();
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getRole = $query->orderBy('id', 'DESC')->get();
            if (count($getRole) > 0) {
                return $this->sendResponse(["role" => $getRole, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No role are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllPermission(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = Permission::query();
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getPermission = $query->orderBy('id', 'DESC')->get();
            if (count($getPermission) > 0) {
                return $this->sendResponse(["Permission" => $getPermission, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No Permission are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function assignPermissionsToRole(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'role' => 'required|string|exists:roles,name',
                'permissions' => 'required|array',
                'permissions.*' => 'required|string|exists:permissions,name'
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $role = Role::where('name', $request->role)->with('permissions')->first();
            $listAllPermissions = $role->permissions->pluck('name');
            $list1 = (array)$request->permissions;
            foreach ($list1 as $eachValue) {
                echo $eachValue;
                $listAllPermissions[] = $eachValue;
            }
            $response = $role->syncPermissions($listAllPermissions);
            return $this->sendResponse($response, 'Permission assinged successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllPermissionsByRole(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'role' => 'required|string|exists:roles,name',

            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $role = Role::where('name', $request->role)->with('permissions')->first();
            $listAllPermissions = $role->permissions->pluck('name');

            $response = $role->syncPermissions($listAllPermissions);
            return $this->sendResponse($response, 'Data fetch successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    // public function addQuotpayment(Request $request): JsonResponse
    // {

    //     try {
    //         $validator = Validator::make($request->all(), [
    //             'quotation_id' => 'required|numeric|exists:quotation,id',
    //             'amount_recived' => 'required',
    //             'quot_invoice_id' => 'required|numeric|exists:quot_invoice,id',
    //         ]);
    //         if ($validator->fails()) {
    //             return $this->sendError('Validation Error.', $validator->errors());
    //         }
    //         $newQuotpayment = new Quotpayment();
    //         $newQuotpayment->quotation_id = $request->quotation_id;
    //         $newQuotpayment->amount_recived = $request->amount_recived;
    //         $newQuotpayment->quot_invoice_id = $request->quot_invoice_id;
    //         $newQuotpayment->save();
    //         return $this->sendResponse([], 'Quotation payment created successfully', true);
    //     } catch (Exception $e) {
    //         return $this->sendError('Something went wrong', $e->getTrace(), 413);
    //     }
    // }
    // public function editQuotpayment(Request $request): JsonResponse
    // {

    //     try {
    //         $validator = Validator::make($request->all(), [
    //             'quotation_id' => 'required|numeric|exists:quotation,id',
    //             'amount_recived' => 'required|numeric|gt:0',
    //             'quot_invoice_id' => 'required|numeric|exists:quot_invoice,id',
    //         ]);
    //         if ($validator->fails()) {
    //             return $this->sendError('Validation Error.', $validator->errors());
    //         }
    //         $editQuotpayment = Quotpayment::query()->where('id', $request->id)->first();

    //         if ($request->has('quotation_id')) {
    //             $editQuotpayment->quotation_id = $request->quotation_id;
    //         }
    //         if ($request->has('quot_invoice_id')) {
    //             $editQuotpayment->quot_invoice_id = $request->quot_invoice_id;
    //         }

    //         $editQuotpayment->save();
    //         return $this->sendResponse([], 'Quotation payment updated successfully');
    //     } catch (Exception $e) {
    //         return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
    //     }
    // }

    // public function getAllQuotpayment(Request $request): JsonResponse
    // {
    //     try {
    //         $validator = Validator::make($request->all(), [
    //             'limit' => 'numeric',
    //             'pageNo' => 'numeric',
    //         ]);
    //         if ($validator->fails()) {
    //             return $this->sendError('Validation Error.', $validator->errors());
    //         }
    //         $query = Quotpayment::query()->with(['quotation','quot_invoice']);
    //         $count = $query->count();
    //         if ($request->has('pageNo') && $request->has('limit')) {
    //             $limit = $request->limit;
    //             $pageNo = $request->pageNo;
    //             $skip = $limit * $pageNo;
    //             $query = $query->skip($skip)->limit($limit);
    //         }

    //         $getQuotpayment = $query->orderBy('id', 'DESC')->get();
    //         if (count($getQuotpayment) > 0) {
    //             return $this->sendResponse(["quot_payments" => $getQuotpayment, 'count' => $count], 'Data fetch successfully');
    //         } else {
    //             return $this->sendResponse([], 'No quotation payment address are available', false);
    //         }
    //     } catch (Exception $e) {
    //         return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
    //     }
    // }

    // public function deleteQuotpaymentById(Request $request): JsonResponse

    // {
    //     try {
    //         $validator = Validator::make($request->all(), [
    //             'id' => 'required|integer|exists:quot_payment,id',
    //         ]);
    //         if ($validator->fails()) {
    //             return $this->sendError('Validation Error.', $validator->errors());
    //         }
    //         $deleteQuotpayment = Quotpayment::query()
    //         ->where('id', $request->id)->first();
    //         $deleteQuotpayment->delete();
    //         return $this->sendResponse([], 'Quotation payment deleted successfully', true);
    //     } catch (Exception $e) {
    //         return $this->sendError('Something went wrong', $e->getMessage(), 413);
    //     }
    // }
    // public function getQuotpaymentById(Request $request): JsonResponse
    // {
    //     try {
    //         $validator = Validator::make($request->all(), [
    //             'id' => 'required|integer|exists:quot_payment,id',
    //         ]);
    //         if ($validator->fails()) {
    //             return $this->sendError('Validation Error.', $validator->errors());
    //         }
    //         $getQuotpayment = Quotpayment::query()->where('id', $request->id)->with(['quotation','quot_invoice'])->first();
    //         return $this->sendResponse($getQuotpayment, 'Data fetch successfully', true);
    //     } catch (Exception $e) {
    //         return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
    //     }
    // }
    public function getTransactionDate(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'quotation_id' => 'numeric|exists:quotation,id',
                'purchase_order_id' => 'numeric|exists:purchase_order,id',
                'rfq_id' => 'numeric|exists:request_for_quotations,id',
                'challan_id' => 'numeric|exists:quot_challan,id',
                'type' => ['required', Rule::in(['quotation', 'purchase_order', 'request_for_quotation','challan','quotation_tax_invoice'])],
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $list=[];
            $arrayId = [];
            $list1=[];
            $list2=[];
            $challanlist=[];
            if ($request->type == 'quotation') {
                $arrayId = Quotation::where('id', $request->quotation_id)->first();
                if (!is_null($arrayId)) {
                    $response['quotation_create_date'] = $arrayId['created_at'];
                    $response['quotation_id'] = $arrayId['id'];
                    //$arrayId=Quotation::where('parent_quot',$request->quotation_id)->get();
                    if (isset($arrayId['id'])) {
                        $data = Quotation::query()->where('parent_quot', $arrayId['id'])->get();
                       // echo $data;
                        if ($data->isEmpty()) {
                            $getParentData = Quotation::query()
                                ->where('id', $request->quotation_id)
                                ->first();

                             $parentid = $getParentData->parent_quot;
                             $parentid = $getParentData->parent_quot;

                             if ($parentid === null) {
                                $response['parent_quot_version'] = null;

                             } else {
                                 $parentdata = Quotation::query()
                                     ->where(function ($query) use ($parentid) {
                                         $query->where('id', $parentid)
                                             ->orWhere('parent_quot', $parentid);
                                     })
                                     ->get();



                            foreach ($parentdata as $data) {
                                $data['parent_quot_id'] = $data['id'];
                                $data['parent_quot_created_date'] = $data['created_at'];
                                $data['parent_quot_created_date'] = $data['quot_status_id'];
                                array_push($list, [
                                    'quotation_id' => $data['id'],
                                    'quotation_create_date' => $data['created_at'],
                                    'quotation_status_id'=>$data['quot_status_id'],
                                ]);
                            }

                            $response['parent_quot_version1'] = $list;
                        }
                            if (count($list) === 0) {
                                $response['parent_quot_version'] = null;
                            }
                        }

                        else{
                        foreach ($data as $data1) {
                            $data1['parent_quot_id']=$data1['id'];
                            $data1['parent_quot_created_date'] = $data1['created_at'];
                            $data['quotation_status_id'] = $data1['quot_status_id'];
                         //   array_push($list,['quot_id' => $data1['parent_quot_id']=$data1['id'],$data1['parent_quot_created_date'] =$data1['created_at'])];
                            array_push($list, [
                                'quotation_id' => $data1['id'],
                                'quotation_create_date' => $data1['created_at'],
                                'quotation_status_id'=>$data1['quot_status_id'],
                            ]);
                        }
                        $response['parent_quot_version'] = $list;
                        if (count($list) === 0) {
                            $response['parent_quot_version'] = null;
                        }
                    }
                }
                } else {
                    $response['quotation_create_date'] = null;
                    $response['quotation_id'] = null;
                }
                $arrayId = QuotOc::where('quotation_id', $request->quotation_id)->first();
                if (!is_null($arrayId)) {
                    $response['quotation_confirm_date'] = $arrayId['created_at'];
                    $response['quotation_confirm_id'] = $arrayId['id'];
                } else {
                    $response['quotation_confirm_date'] = null;
                    $response['quotation_confirm_id'] = null;
                }
                $arrayId = QuotTaxInvoice::where('quotation_id', $request->quotation_id)->first();
                if (!is_null($arrayId)) {
                    $response['quotation_invoice_date'] = $arrayId['created_at'];
                    $response['quotation_invoice_id'] = $arrayId['id'];
                } else {
                    $response['quotation_invoice_date'] = null;
                    $response['quotation_invoice_id'] = null;
                }
                $arrayId = QuotChallan::where('quotation_id', $request->quotation_id)->get();
                if (!is_null($arrayId)) {

                    foreach($arrayId as $data){
                        $data['challan_create_date'] = $data['created_at'];
                        $data['challan_create_id'] = $data['id'];
                        array_push($challanlist, [
                            'challan_create_id' => $data['id'],
                            'challan_create_date' => $data['created_at'],
                        ]);

                        }
                        $response['challan_version'] = $challanlist;
                    if (count($challanlist) === 0) {
                        $response['challan_version'] = null;
                    }
                } else {
                    $response['challan_create_date'] = null;
                    $response['challan_create_id'] = null;
                }
                $arrayId = ReceiptVoucher::where('quotation_id', $request->quotation_id)->first();
                if (!is_null($arrayId)) {
                    $response['receipt_voucher_create_date'] = $arrayId['created_at'];
                    $response['receipt_voucher_id'] = $arrayId['id'];
                } else {
                    $response['receipt_voucher_create_date'] = null;
                    $response['receipt_voucher_id'] = null;
                }
                $arrayId = QuotProformaInvoice::where('quotation_id', $request->quotation_id)->first();
                if (!is_null($arrayId)) {
                    $response['quot_proforma_invoice_create_date'] = $arrayId['created_at'];
                    $response['quot_proforma_invoice_id'] = $arrayId['id'];
                } else {
                    $response['quot_proforma_invoice_create_date'] = null;
                    $response['quot_proforma_invoice_id'] = null;
                }
            }
            if ($request->type == 'purchase_order') {
                $arrayId = PurchaseOrder::where('id', $request->purchase_order_id)->first();
                if (!is_null($arrayId)) {
                    $response['purchase_order_create_date'] = $arrayId['created_at'];
                    $response['purchase_order_id'] = $arrayId['id'];
                } else {
                    $response['purchase_order_create_date'] = null;
                    $response['purchase_order_id'] = null;
                }
                $arrayId = PoInward::where('purchase_order_id', $request->purchase_order_id)->get();
                if (!is_null($arrayId)) {
                    foreach($arrayId as $data){
                    $data['po_inward_create_date'] = $data['created_at'];
                    $data['po_inward_id'] = $data['id'];
                    array_push($list, [
                        'po_inward_id' => $data['id'],
                        'po_inward_create_date' => $data['created_at'],
                    ]);

                    }
                    $response['po_inward_version'] = $list;
                    if (count($list) === 0) {
                        $response['po_inward_version'] = null;
                    }
                } else {
                    $response['po_inward_create_date'] = null;
                    $response['po_inward_id'] = null;
                }
                $arrayId = POReceiptVoucher::where('purchase_order_id', $request->purchase_order_id)->get();
                if (!is_null($arrayId)) {
                    foreach($arrayId as $data){
                    $data['po_receipt_voucher_create_date'] = $data['created_at'];
                    $data['po_receipt_voucher_id'] = $data['id'];
                    array_push($list1, [
                        'po_receipt_voucher_id' => $data['id'],
                        'po_receipt_voucher_create_date' => $data['created_at'],
                    ]);
                }
                   $response['po_receipt_voucher_version'] = $list1;
                   if (count($list1) === 0) {
                    $response['po_receipt_voucher_version'] = null;
                }
                } else {
                    $response['po_receipt_voucher_create_date'] = null;
                    $response['po_receipt_voucher_id'] = null;
                }
                $arrayId = PoGrn::where('purchase_order_id', $request->purchase_order_id)->get();
                if (!is_null($arrayId)) {
                    foreach($arrayId as $data){
                    $data['po_grn_create_date'] = $data['created_at'];
                    $data['po_grn_id'] = $data['id'];
                    array_push($list2, [
                        'po_grn_id' => $data['id'],
                        'po_grn_create_date' => $data['created_at'],
                    ]);
                    $response['po_grn_version'] = $list2;
                    if (count($list2) === 0) {
                        $response['po_grn_version'] = null;
                    }
                    }
                } else {
                    $response['po_grn_create_date'] = null;
                    $response['po_grn_id'] = null;
                }
                $arrayId = POTaxInvoice::where('purchase_order_id', $request->purchase_order_id)->first();
                if (!is_null($arrayId)) {
                    $response['po_tax_invoice_create_date'] = $arrayId['created_at'];
                    $response['po_tax_invoice_id'] = $arrayId['id'];
                } else {
                    $response['po_tax_invoice_create_date'] = null;
                    $response['po_tax_invoice_id'] = null;
                }
            }
            if ($request->type == 'request_for_quotation') {
                $arrayId = RequestForQuotation::where('id', $request->rfq_id)->first();
                if (!is_null($arrayId)) {
                    $response['request_for_quotation_create_date'] = $arrayId['created_at'];
                } else {
                    $response['request_for_quotation_create_date'] = null;
                }
            }
            return $this->sendResponse($response, 'Data Fatch successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getTrace(), 413);
        }
    }
    public function getUserData(Request $request)
    {
        try {
            $validater = Validator::make($request->all(), [
                'user_id' => 'required|integer|existes:users,id'
            ]);
            $getUserData = User::query()
                ->where('id', $request->user_id)
                ->with(['store', 'store.store_location'])
                ->first();
            return $this->sendResponse($getUserData, 'Data fatch Successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getTrace(), 413);
        }
    }
    public function addOrganization(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'name' => 'required|string',
                'billing_address_id' => 'required|exists:client_address,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newOrganization = new Organization();
            $newOrganization->name = $request->name;
            $newOrganization->billing_address_id = $request->billing_address_id;
            $newOrganization->save();
            return $this->sendResponse([], 'Organization added successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Somthing went wrong', $e->getMessage(), 413);
        }
    }
    public function editOrganization(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:organizations,id',
                'name' => 'required|string',
                'billing_address_id' => 'required|exists:client_address,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $editOrganization = Organization::query()->where('id', $request->id)->first();
            if ($request->has('name')) {
                $editOrganization->name = $request->name;
            }
            if ($request->has('billing_address_id')) {
                $editOrganization->billing_address_id = $request->billing_address_id;
            }
            $editOrganization->save();
            return $this->sendResponse([], 'Organization updated successfully');
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllOrganization(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = Organization::query()->with(['billing_address']);
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getProducts = $query->orderBy('id', 'DESC')->get();
            if (count($getProducts) > 0) {
                return $this->sendResponse(["organizations" => $getProducts, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No organization are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteOrganizationById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:organizations,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $deleteOrganization = Organization::query()->where('id', $request->id)->first();

            $deleteOrganization->delete();
            return $this->sendResponse([], 'Organization deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getOrganizationById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:organizations,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getOrganization = Organization::query()
                ->where('id', $request->id)
                ->with(['billing_address'])->first();
            return $this->sendResponse($getOrganization, 'Data fetch successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function addCurrency(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'name' => 'required|string|unique:currency',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newCurrency = new Currency();
            $newCurrency->name = $request->name;
            if ($request->symbol != "") {
                if (!str_contains($request->symbol, "http")) {
                    $newCurrency->symbol = $this->saveImage($request->symbol, $request->client_id);
                }
            }
            $newCurrency->save();
            return $this->sendResponse([], 'Currency added successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getTrace(), 413);
        }
    }
    public function saveImage($image, $productName)
    {
        $imageName = $productName . '-' . rand(100, 9999) . '.webp';
        $destinationPath = public_path('productimage\\' . $imageName);
        if (env('APP_ENV') == 'prod') {
            $destinationPath = public_path('productimage/' . $imageName);
        }
        $img = Image::make(file_get_contents($image))
            ->resize(300, null)
            ->save($destinationPath, 80, 'webp');
        return '/productimage/' . $imageName;
    }
    public function editCurrency(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:currency,id',
                'name' => 'string|unique:payment_status',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $editCurrency = Currency::query()->where('id', $request->id)->first();
            if ($request->has('name')) {
                $editCurrency->name = $request->name;
            }
            if ($request->symbol != "") {
                if (!str_contains($request->symbol, "http")) {
                    $editCurrency->symbol = $this->saveImage($request->symbol, $request->client_id);
                }
            }
            $editCurrency->save();
            return $this->sendResponse([], 'Currency updated successfully');
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllCurrency(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = Currency::query();
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getCurrency = $query->orderBy('id', 'DESC')->get();
            if (count($getCurrency) > 0) {
                return $this->sendResponse(["currency" => $getCurrency, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No currency are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteCurrencyById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:payment_status,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $deleteCurrency = Currency::query()->where('id', $request->id)->first();
            $deleteCurrency->delete();
            return $this->sendResponse([], 'Currency deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getCurrencyById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:logistic_details,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getCurrency = Currency::query()->where('id', $request->id)->first();
            return $this->sendResponse(["currency" => $getCurrency], 'Data fetch successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function addCountries(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'name' => 'required|string|unique:countries',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newCountries = new Countries();
            $newCountries->name = $request->name;
            $newCountries->save();
            return $this->sendResponse([], 'Countries added successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getTrace(), 413);
        }
    }
    public function editCountries(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:countries,id',
                'name' => 'string|unique:payment_status',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $editCountries = Countries::query()->where('id', $request->id)->first();
            if ($request->has('name')) {
                $editCountries->name = $request->name;
            }
            $editCountries->save();
            return $this->sendResponse([], 'Countries updated successfully');
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllCountries(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = Countries::query();
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getCountries = $query->orderBy('id', 'DESC')->get();
            if (count($getCountries) > 0) {
                return $this->sendResponse(["countries" => $getCountries, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No countries are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteCountriesById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:countries,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $deleteCountries = Countries::query()->where('id', $request->id)->first();
            $deleteCountries->delete();
            return $this->sendResponse([], 'Countries deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getCountriesById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:countries,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getCountries = Countries::query()->where('id', $request->id)->first();
            return $this->sendResponse(["Countries" => $getCountries], 'Data fetch successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function addStates(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'name' => 'required|string|unique:states',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newStates = new States();
            $newStates->name = $request->name;
            $newStates->save();
            return $this->sendResponse([], 'States added successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getTrace(), 413);
        }
    }
    public function editStates(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:states,id',
                'name' => 'string|unique:payment_status',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $editStates = States::query()->where('id', $request->id)->first();
            if ($request->has('name')) {
                $editStates->name = $request->name;
            }
            $editStates->save();
            return $this->sendResponse([], 'States updated successfully');
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllStates(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = States::query();
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getStates = $query->orderBy('id', 'DESC')->get();
            if (count($getStates) > 0) {
                return $this->sendResponse(["States" => $getStates, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No States are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteStatesById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:states,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $deleteStates = States::query()->where('id', $request->id)->first();
            $deleteStates->delete();
            return $this->sendResponse([], 'States deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getStatesById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:states,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getStates = States::query()->where('id', $request->id)->first();

            return $this->sendResponse(["states" => $getStates], 'Data fetch successfully', true);

        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    // public function getReceivableAmountAndData(Request $request): JsonResponse
    // {
    //     try {
    //         $validator = Validator::make($request->all(), [
    //             'limit' => 'numeric',
    //             'pageNo' => 'numeric',
    //         ]);
    //         if ($validator->fails()) {
    //             return $this->sendError('Validation Error.', $validator->errors());
    //         }
    //         $query = QuotInvoice::query()->with(['quotation', 'reviewed_by_user', 'payment_mode']);
    //         $receivables_count = $query->count();
    //         if ($request->has('pageNo') && $request->has('limit')) {
    //             $limit = $request->limit;
    //             $pageNo = $request->pageNo;
    //             $skip = $limit * $pageNo;
    //             $query = $query->skip($skip)->limit($limit);
    //         }
    //         $getQuotInvoice = $query->orderBy('id', 'DESC')->get();
    //         if (count($getQuotInvoice) > 0) {
    //             $groupByMonth = $getQuotInvoice->groupBy(function ($item, $key) {
    //                 return Carbon::parse($item->payment_date)->format('F Y');
    //             })->map(function ($item, $key) {

    //                 return [
    //                     // 'data' => $item,
    //                     'month' => $key,
    //                     'sum' => $item->sum('amount'),
    //                 ];

    //             })->sortBy(function ($item, $key) {
    //                  Carbon::parse($item['month']);
    //             });
    //             $totalReceivables = $getQuotInvoice->sum('amount');
    //             $query = POTaxInvoice::query()->with(['delivery_address', 'purchase_order', 'payment_terms']);
    //             $getPaybel_count = $query->count();

    //             $getPOTaxInvoice = $query->orderBy('id', 'DESC')->get();
    //             if (count($getPOTaxInvoice) > 0) {
    //                 $getPaybel = $getPOTaxInvoice->groupBy(function ($item, $key) {
    //                     return Carbon::parse($item->payment_date)->format('F Y');
    //                 })->map(function ($item, $key) {
    //                     return [
    //                         // 'data' => $item,
    //                         'month' => $key,
    //                         'sum' => $item->sum('amount'),
    //                     ];
    //                 })->sortBy(function ($item, $key) {
    //                      Carbon::parse($item['month']);
    //                 });
    //                 $totalpayable = $getPOTaxInvoice->sum('amount');
    //             }
    //             return $this->sendResponse(['receivables' => $groupByMonth,'paybel' => $getPaybel], 'Data fetch successfully');
    //         } else {
    //             return $this->sendResponse([], 'No quotation invoice are available', false);
    //         }
    //     } catch (Exception $e) {
    //         return $this->sendError('Something Went Wrong', $e->getTrace(), 413);
    //     }
    // }
public function getChartData(Request $request): JsonResponse
{
    try {
        $validator = Validator::make($request->all(), [
            'limit' => 'numeric',
            'pageNo' => 'numeric',
        ]);
        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors());
        }

        // Receivable data
        $query = QuotTaxInvoice::query()->with(['quotation', 'reviewed_by_user', 'payment_mode']);
        $receivables_count = $query->count();

        // Payable data
        $query = POTaxInvoice::query()->with(['delivery_address', 'purchase_order', 'payment_terms']);
        $getPayable_count = $query->count();

        // Paid data
        $query = POReceiptVoucher::query();
        $getPaid_count = $query->count();

        // Received data
        $query = ReceiptVoucher::query();
        $getReceived_count = $query->count();

       // Get data for the last 6 months and the next 6 months
       $startMonth = Carbon::now()->subMonths(6)->format('Y-m-d');
       $endMonth = Carbon::now()->addMonths(6)->format('Y-m-d');

       $groupByMonth = QuotTaxInvoice::query()
           ->whereBetween('payment_date', [$startMonth, $endMonth])
           ->get()
           ->groupBy(function ($item, $key) {
               return Carbon::parse($item->payment_date)->format('Y-m');
           })
           ->map(function ($item, $key) {
               return $item->sum('amount');
           });

       $getPayable = POTaxInvoice::query()
           ->whereBetween('payment_date', [$startMonth, $endMonth])
           ->get()
           ->groupBy(function ($item, $key) {
               return Carbon::parse($item->payment_date)->format('Y-m');
           })
           ->map(function ($item, $key) {
               return $item->sum('amount');
           });

       $getPaid = POReceiptVoucher::query()
           ->whereBetween('payment_date', [$startMonth, $endMonth])
           ->get()
           ->groupBy(function ($item, $key) {
               return Carbon::parse($item->payment_date)->format('Y-m');
           })
           ->map(function ($item, $key) {
               return $item->sum('total_amount');
           });

       $getReceived = ReceiptVoucher::query()
           ->whereBetween('payment_date', [$startMonth, $endMonth])
           ->get()
           ->groupBy(function ($item, $key) {
               return Carbon::parse($item->payment_date)->format('Y-m');
           })
           ->map(function ($item, $key) {
               return $item->sum('total_amount');
           });

       $data = [];

       // Generate data for each month
       $currentMonth = Carbon::now()->format('Y-m');
       $monthsToFetch = CarbonPeriod::create($startMonth, '1 month', $endMonth);

       foreach ($monthsToFetch as $month) {
           $yearMonth = $month->format('Y-m');
           $monthName = $month->format('M Y');

           $data[$monthName] = [
               'receivable' => $groupByMonth->has($yearMonth) ? $groupByMonth[$yearMonth] : 0,
               'payable' => $getPayable->has($yearMonth) ? $getPayable[$yearMonth] : 0,
               'paid' => $getPaid->has($yearMonth) ? $getPaid[$yearMonth] : 0,
               'received' => $getReceived->has($yearMonth) ? $getReceived[$yearMonth] : 0,
               'month' => $monthName
           ];
       }

        // Sort the data by month
        $formattedData = [];
        foreach ($data as $yearMonth => $values) {
            $formattedData[] = $values;
        }

        // Sort the data by month
        ksort($formattedData);

        $data = $formattedData;

        return $this->sendResponse($data, 'Data fetched successfully');
   } catch (Exception $e) {
       return $this->sendError('Something Went Wrong', $e->getTrace(), 413);
   }
}
    public function getPaybelAmountAndData(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = POTaxInvoice::query()->with(['delivery_address', 'purchase_order', 'payment_terms']);
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getPOTaxInvoice = $query->orderBy('id', 'DESC')->get();
            if (count($getPOTaxInvoice) > 0) {
                $groupByMonth = $getPOTaxInvoice->groupBy(function ($item, $key) {
                    return Carbon::parse($item->payment_date)->format('F Y');
                })->map(function ($item, $key) {
                    return [
                        'data' => $item,
                        'month' => $key,
                        'sum' => $item->sum('amount'),
                    ];
                })->sortBy(function ($item, $key) {
                    return Carbon::parse($item['month']);
                });
                $totalpayable = $groupByMonth->sum('amount');
                return $this->sendResponse(['data' => $groupByMonth, 'count' => $count, 'total_payable' => $totalpayable], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No quotation invoice are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllUsers(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = User::query()->with(['roles.permissions']);
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $users = $query->orderBy('id', 'DESC')->get();
            if ($users->isNotEmpty()) {
                return $this->sendResponse(["users" => $users, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No users are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }

    public function getPichartData(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);

            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }

            $query = QuotTaxInvoice::query()
                ->with(['quotation.client']);

            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }

            $response = $query->orderBy('id', 'DESC')->get();
            $users = $response;

            if (!empty($users)) {
                $mappedUsers = $users->map(function ($user) {
                    $companyName = optional($user->quotation)->client->company_name ?? null;
                    $totalAmount = $user->amount;

                    return [
                        'company_name' => $companyName,
                        'total_amount' => $totalAmount,
                    ];
                });

                $summedUsers = $mappedUsers->groupBy('company_name')
                    ->map(function ($company, $key) {
                        return [
                            'company_name' => $key,
                            'total_amount' => $company->sum('total_amount'),
                            'color' => '#' . substr(md5($key), 0, 6)
                        ];
                    })
                    ->values();

                $query = POTaxInvoice::query()
                    ->with(['purchase_order.client']);

                $response = $query->orderBy('id', 'DESC')->get();
                $users = $response;

                if (!empty($users)) {
                    $mappedUsers = $users->map(function ($user) {
                        $companyName = optional($user->purchase_order)->client->company_name ?? null;
                        $totalAmount = $user->amount;

                        return [
                            'company_name' => $companyName,
                            'total_amount' => $totalAmount,
                        ];
                    });

                    $poSummedUsers = $mappedUsers->groupBy('company_name')
                        ->map(function ($company, $key) {
                            return [
                                'company_name' => $key,
                                'total_amount' => $company->sum('total_amount'),
                                'color' => '#' . substr(md5($key), 0, 6)
                            ];
                        })
                        ->values();

                    return $this->sendResponse(['receiveble' => $summedUsers, 'payable' => $poSummedUsers], 'Data fetch successfully');
                } else {
                    return $this->sendResponse([], 'No users are available', false);
                }
            } else {
                return $this->sendResponse([], 'No users are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }

public function getReceiveblePichartData(Request $request): JsonResponse
{
    try {
        $validator = Validator::make($request->all(), [
            'limit' => 'numeric',
            'pageNo' => 'numeric',
        ]);
        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors());
        }

        $query = QuotTaxInvoice::query()
        ->with(['quotation' => function ($query) {
            $query->with(['client']);
        }]);

        if ($request->has('pageNo') && $request->has('limit')) {
            $limit = $request->limit;
            $pageNo = $request->pageNo;
            $skip = $limit * $pageNo;
            $query = $query->skip($skip)->limit($limit);
        }
        $response = $query->orderBy('id', 'DESC')->get();
        $users = $response;

        if (!empty($users)) {
            $mappedUsers = $users->map(function ($user) {
                return [
                    'company_name' => $user->quotation->client->company_name,
                    'amount_paid' => $user->amount,
                    'document_amount' => $user->quotation->total_amount,
                ];
            });
            $summedUsers = $mappedUsers->groupBy('company_name')
                ->map(function ($company, $key) {
                    return [
                        'company_name' => $key,
                        'amount_paid' => $company->sum('amount_paid'),
                        'document_amount' => $company->sum('document_amount'),
                    ];
                })
                ->values();

            return $this->sendResponse(['receiveble'=>$summedUsers], 'Data fetch successfully');
        } else {
            return $this->sendResponse([], 'No users are available', false);
        }

    } catch (Exception $e) {
        return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
    }
}
public function getPaybelPichartData(Request $request): JsonResponse
{
    try {
        $validator = Validator::make($request->all(), [
            'limit' => 'numeric',
            'pageNo' => 'numeric',
        ]);
        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors());
        }
         $query = POTaxInvoice::query()
        ->with(['purchase_order' => function ($query) {
            $query->with(['client']);
        }]);
        if ($request->has('pageNo') && $request->has('limit')) {
            $limit = $request->limit;
            $pageNo = $request->pageNo;
            $skip = $limit * $pageNo;
            $query = $query->skip($skip)->limit($limit);
        }
        $response = $query->orderBy('id', 'DESC')->get();
        $users = $response;
        if (!empty($users)) {
            $mappedUsers = $users->map(function ($user) {
                return [
                    'company_name' => $user->purchase_order->client->company_name,
                    'amount_paid' => $user->amount,
                    'document_amount'=>$user->purchase_order->total_amount,
                ];
            });
            $poSummedUsers = $mappedUsers->groupBy('company_name')
                ->map(function ($company, $key) {
                    return [
                        'company_name' => $key,
                        'amount_paid' => $company->sum('amount_paid'),
                        'document_amount'=>$company->sum('document_amount')
                    ];
                })
                ->values();
            return $this->sendResponse(['payable'=>$poSummedUsers], 'Data fetch successfully');
        } else {
            return $this->sendResponse([], 'No users are available', false);
        }

    } catch (Exception $e) {
        return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
    }
}


    public function createRole(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'name' => 'required|string|unique:roles',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newRole = new Role();
            $newRole->name = $request->name;
            $newRole->guard_name = 'api';
            $newRole->save();
            return $this->sendResponse([], 'Role created successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getTrace(), 413);
        }
    }
    public function createPermission(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'name' => 'required|string|unique:permissions',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newPermission = new Permission();
            $newPermission->name = $request->name;
            $newPermission->guard_name = 'api';
            $newPermission->save();
            return $this->sendResponse([], 'Permission created successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getTrace(), 413);
        }
    }
    public function getCardData(Request $request): JsonResponse
{
    try {
        $validator = Validator::make($request->all(), [
            'limit' => 'numeric',
            'pageNo' => 'numeric',
        ]);
        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors());
        }
        //receipt due in 7 dayes
        $query = QuotTaxInvoice::query()->with(['quotation', 'reviewed_by_user', 'payment_mode']);
        if ($request->has('pageNo') && $request->has('limit')) {
            $limit = $request->limit;
            $pageNo = $request->pageNo;
            $skip = $limit * $pageNo;
            $query = $query->skip($skip)->limit($limit);
        }
        $getQuotInvoice = $query->orderBy('id', 'DESC')->get();
        $dueInSevenDay = collect();
        foreach ($getQuotInvoice as $invoice) {
            $paymentDate = Carbon::parse($invoice->payment_date);
            $dueDate = $paymentDate->addDays(7);
            $now = Carbon::now();
            if ($now->lt($dueDate) && $now->diffInDays($dueDate, false) <= 7) {
                $dueInSevenDay->push($invoice);
            }
        }
        $receipt_due_in_seven_days_count = $dueInSevenDay->count();
        $receiptDueInSevendays = $dueInSevenDay->sum('amount');
        //receipt over due
        $query = QuotTaxInvoice::query()->with(['quotation', 'reviewed_by_user', 'payment_mode'])
        ->where('payment_date', '<', Carbon::now()->format('Y-m-d'));
        $receiptOverDue_count = $query->count();
        $getQuotInvoice1 = $query->orderBy('id','DESC')->get();
        $receiptOverDue = $getQuotInvoice1->sum('amount');
        //payment due in 7 days
        $query=POTaxInvoice::query();
        $getPoTaxdeutosevenDays=$query->orderBy('id','DESC')->get();
        $dueInSevenDay = collect();
        foreach ($getPoTaxdeutosevenDays as $invoice) {
            $paymentDate = Carbon::parse($invoice->payment_date);
            $dueDate = $paymentDate->addDays(7);
            $now = Carbon::now();
            if ($now->lt($dueDate) && $now->diffInDays($dueDate, false) <= 7) {
                $dueInSevenDay->push($invoice);
            }
        }
        $poReceiptdueinsevendays=$dueInSevenDay->sum('amount');
        $poreceipt_count = $dueInSevenDay->count();
        //payment over due
        $query=POTaxInvoice::query()
        ->where('payment_date', '<', Carbon::now()->format('Y-m-d'));
        $poreceiptOverDue_count = $query->count();
        $getPoReceiptoverdue = $query->orderBy('id','DESC')->get();
        $poReceiptOverDue = $getPoReceiptoverdue->sum('amount');
        return $this->sendResponse( [['name'=>'Receipt Overdue','companies' => $receiptOverDue_count,'value'=>$receiptOverDue],
        ['name'=>'Receipts Due in 7 Days','companies' => $receipt_due_in_seven_days_count,'value'=>$receiptDueInSevendays],
        ['name'=>'Payments Overdue','companies' => $poreceiptOverDue_count,'value'=>$poReceiptOverDue],
        ['name'=>'Payments Due in 7 Days','companies' => $poreceipt_count,'value'=>$poReceiptdueinsevendays]], 'Data fetch successfully');
    } catch (Exception $e) {
        return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
    }
}
public function getReceiptOverDueData(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'pageNo' => 'numeric',
                'limit' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors(), 400);
            }
            $query = QuotTaxInvoice::query()->with(['quotation','quotation.client'
            ,'quotation.created_by_user','quotation.tnc','quotation.payment_status','quotation.indirect_tax'
            ,'quotation.quot_status','quotation.bank_details','quotation.delivery_address','quotation.client_address'])
            ;
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }

            $getQuotInvoice = $query->orderBy('id', 'DESC')->get();
            $dueInSevenDay = collect();

            foreach ($getQuotInvoice as $invoice) {
                $paymentDate = Carbon::parse($invoice->payment_date);
                $dueDate = $paymentDate->addDays(7);
                $now = Carbon::now();

                if ($now->gt($dueDate)) {
                    $dueInSevenDay->push($invoice);
                }
            }

            $count = $dueInSevenDay->count();

            if ($count > 0) {
                $response['receipt_over_due_date'] = $dueInSevenDay;
                $response['count'] = $count;
                return $this->sendResponse($response, 'Data Fetched Successfully', true);
            } else {
                return $this->sendResponse('No Data Available', [], false);
            }
        } catch (Exception $e) {
            return $this->sendError($e->getMessage(), $e->getTrace(), 500);
        }
    }

    public function getReceiptDueInSevenDays(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'pageNo' => 'numeric',
                'limit' => 'numeric',
            ]);

            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors(), 400);
            }

            $query = QuotTaxInvoice::query()->with([
                'quotation', 'quotation.client', 'quotation.created_by_user',
                'quotation.tnc', 'quotation.payment_status', 'quotation.indirect_tax',
                'quotation.quot_status', 'quotation.bank_details', 'quotation.delivery_address',
                'quotation.client_address'
            ]);

            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }

            $getQuotInvoice = $query->orderBy('id', 'DESC')->get();
            $dueInSevenDay = collect();

            $now = Carbon::now();

            foreach ($getQuotInvoice as $invoice) {
                $paymentDate = Carbon::parse($invoice->payment_date);
                $dueDate = $paymentDate->addDays(7);
                //echo $dueDate;
                if ($now->lte($dueDate) && $now->diffInDays($dueDate) <= 7) {
                    $dueInSevenDay->push($invoice);
                }
            }

            $count = $dueInSevenDay->count();

            if ($count > 0) {
                $response['receipt_due_in_seven_days'] = $dueInSevenDay;
                $response['count'] = $count;
                return $this->sendResponse($response, 'Data Fetched Successfully', true);
            } else {
                return $this->sendResponse('No Data Available', [], false);
            }
        } catch (Exception $e) {
            return $this->sendError($e->getMessage(), $e->getTrace(), 500);
        }
    }
    public function getPaymentDueInSevenDaysData(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'pageNo' => 'numeric',
                'limit' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors(), 400);
            }
            $query = POTaxInvoice::query()->with(['delivery_address', 'purchase_order', 'payment_terms']);
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getQuotInvoice = $query->orderBy('id', 'DESC')->get();
            $dueInSevenDay = collect();
            foreach ($getQuotInvoice as $invoice) {
                $paymentDate = Carbon::parse($invoice->payment_date);
                $dueDate = $paymentDate->addDays(7);
                $now = Carbon::now();
                if ($now->lt($dueDate) && $now->diffInDays($dueDate, false) <= 7) {
                    $dueInSevenDay->push($invoice);
                }
            }
            $count = $dueInSevenDay->count();
            if (count($getQuotInvoice) > 0) {
                $response['po_tax_invoice'] = $dueInSevenDay;
                $response['count'] = $count;
                return $this->sendResponse($response, 'Data Fetched Successfully', true);
            } else {
                return $this->sendResponse('No Data Available', [], false);
            }
        } catch (Exception $e) {
            return $this->sendError($e->getMessage(), $e->getTrace(), 500);
        }
    }
      public function getPaymentOverDueData(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'pageNo' => 'numeric',
                'limit' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors(), 400);
            }
            $query = POTaxInvoice::query()->with(['delivery_address', 'purchase_order', 'payment_terms','purchase_order.client',
            'purchase_order.created_by_user','purchase_order.reviewed_by_user','purchase_order.client_address','purchase_order.logistic_details',
            'purchase_order.tnc','purchase_order.buyer_address','purchase_order.payment_status','purchase_order.indirect_tax'])
            ->where('payment_date', '<', Carbon::now()->format('Y-m-d'));
            $POTaxInvoice = $query->orderBy('id','DESC')->get();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
             $count = $query->count();
            if (count($POTaxInvoice) > 0) {
                $response['payment_over_due_data'] = $POTaxInvoice;
                $response['count'] = $count;
                return $this->sendResponse($response, 'Data Fetched Successfully', true);
            } else {
                return $this->sendResponse('No Data Available', [], false);
            }
        } catch (Exception $e) {
            return $this->sendError($e->getMessage(), $e->getTrace(), 500);
        }
    }
    public function getTransaction(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'pageNo' => 'numeric',
                'limit' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors(), 400);
            }
            $query = POTaxInvoice::query()->with(['delivery_address', 'purchase_order', 'payment_terms'])
            ->where('payment_date', '<', Carbon::now()->format('Y-m-d'));
            $POTaxInvoice = $query->orderBy('id','DESC')->get();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
             $count = $query->count();
            if (count($POTaxInvoice) > 0) {
                $response['po_tax_invoice'] = $POTaxInvoice;
                $response['count'] = $count;
                return $this->sendResponse($response, 'Data Fetched Successfully', true);
            } else {
                return $this->sendResponse('No Data Available', [], false);
            }
        } catch (Exception $e) {
            return $this->sendError($e->getMessage(), $e->getTrace(), 500);
        }
    }
    public function getAllSalePersons(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = User::query()->whereHas(
                'roles', function ($q) {
                $q->where('name', 'Sales Staff');
            })->with(['roles' => function ($query) {
                $query->where('name', '=', 'Sales Staff');
            }]);
            if($request->has('pageNo') && $request->has('limit')){
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit*$pageNo;
                $query= $query->skip($skip)->limit($limit);
            }
            $count = $query->count();
         $getAllSalesPersons= $query->orderBy('id','DESC')->get();
            if (count($getAllSalesPersons) > 0) {
                return $this->sendResponse(["allSalePersons" => $getAllSalesPersons, 'count' => $count], 'Sales persons fetched successfully');
            } else {
                return $this->sendResponse([], 'No sale person available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
public function getPaybelLineChartData(Request $request): JsonResponse
{
    try {
        $validator = Validator::make($request->all(), [
            'limit' => 'numeric',
            'pageNo' => 'numeric',
        ]);

        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors());
        }
        // Paybel data
        $query = POTaxInvoice::query()->with(['delivery_address', 'purchase_order', 'payment_terms']);
        $getPaybel_count = $query->count();
        $getPOTaxInvoice = $query->orderBy('id', 'DESC')->get();
        if ($request->has('pageNo') && $request->has('limit')) {
            $limit = $request->limit;
            $pageNo = $request->pageNo;
            $skip = $limit * $pageNo;
            $query = $query->skip($skip)->limit($limit);
        }
        if (count($getPOTaxInvoice) > 0) {
            $getPaybel = $getPOTaxInvoice->groupBy(function ($item, $key) {
                return Carbon::parse($item->payment_date)->format('Y-m');
            })->map(function ($item, $key) {
                return $item->sum('amount');
            });
            $totalPayable = $getPaybel->sum();
        }
        $data = [];
        $now = Carbon::now();
        // Previous month sum
        $previousMonth = $now->subMonth()->format('M Y');
        $previousMonthSum = 0;
        foreach ($getPaybel as $key => $amount) {
        $monthYear = Carbon::parse($key)->format('M Y');
        if ($monthYear === $previousMonth) {
        $previousMonthSum = $amount;
        break;
        }
        }
        // Next three months data
        $nextThreeMonthsData = [];
        for ($i = 1; $i <= 3; $i++) {
    $nextMonth = $now->addMonth()->format('M Y');
    $amount = $getPaybel->has($nextMonth) ? $getPaybel[$nextMonth] : 0;

    $nextThreeMonthsData[] = [

        'month' => $nextMonth,
        'amount' => $amount,
    ];
}

    $data[] = [
        'earlier' => [
        'amount' => $previousMonthSum,
    ],
        'next_three_months' => $nextThreeMonthsData,
    ];
    return $this->sendResponse($data, 'Data fetch successfully');
    } catch (Exception $e) {
        return $this->sendError('Something Went Wrong', $e->getTrace(), 413);
    }
}


public function bulkAddReleventProducts(Request $request):JsonResponse
    {
        try{
            $validator=Validator::make($request->all(),[
                'data'=>'required|array',
                'data.*.product_code'=>'required|string|exists:products,product_code',
                'data.*.relevant_product_code'=>'required|string|exists:products,product_code',
            ]);
            if($validator->fails()){
                return $this->sendError("Validation failed",$validator->errors());
            }
            foreach($request->data as $prod){
                $productData = Products::query()->where('product_code',$prod['product_code'])->first();
                $getProd = Products::query()->where('product_code',$prod['relevant_product_code'])->first();
                if($getProd){
                    $getRelvent = ReleventProduct::query()->where('parent_product',$productData->id)->where('child_product',$getProd->id)->first();
                    if(!$getRelvent){
                        $newReleventProduct = new ReleventProduct;
                        $newReleventProduct->parent_product = $productData->id;
                        $newReleventProduct->child_product = $getProd->id;
                        $newReleventProduct->save();
                    }
                }
            }
            return $this->sendResponse([],'Relevent products added successfully',true);
        }catch(Exception $e){
            return $this->sendError("Something went wrong",$e->getMessage(),413);
        }
    }

public function getLastThreeMonthTopSellingProduct(Request $request): JsonResponse
{
    try {
        $validator = Validator::make($request->all(), [
            'pageNo' => 'numeric',
            'limit' => 'numeric',
        ]);

        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors(), 400);
        }
        //top 5 selling product
        $query = QuotTaxInvoice::query()->with('quotation');

        if ($request->has('pageNo') && $request->has('limit')) {
            $limit = $request->limit;
            $pageNo = $request->pageNo;
            $skip = $limit * $pageNo;
            $query = $query->skip($skip)->limit($limit);
        }

        // Get invoices for the last three months
        $startDate = Carbon::now()->subMonths(3)->startOfMonth();
        $endDate = Carbon::now()->endOfMonth();
        $query->whereBetween('payment_date', [$startDate, $endDate]);

        $getQuotInvoice = $query->orderBy('id', 'DESC')->get();

        foreach ($getQuotInvoice as $invoice) {
            if ($invoice->id != null) {
                $product = QuotTaxInvoiceProduct::query()
                    ->where('quot_tax_invoice_id', $invoice->id)
                    ->with('products')
                    ->get();

                $invoice->quotation_details = $product;
            }
        }
        $topSellingProducts = $getQuotInvoice->flatMap(function ($invoice) {
            return $invoice->quotation_details->map(function ($quotationDetail) {
                return [
                    'product_id' => $quotationDetail->product_id,
                    'product_name' => $quotationDetail->products->name,
                    'total_sales' => $quotationDetail->modified_amount,
                ];
            });
        })->groupBy('product_id')
            ->map(function ($group) {
                return [
                    'product_id' => $group[0]['product_id'],
                    'product_name' => $group[0]['product_name'],
                    'total_sales' => $group->sum('total_sales'),
                    'invoice_count' => $group->count(),
                ];
            })
            ->sortByDesc('total_sales')
            ->values();

        $count = $topSellingProducts->count();

        //top 5 purchase products
        $query = POTaxInvoice::query()->with('purchase_order');
        // Get invoices for the last three months
        $startDate = Carbon::now()->subMonths(3)->startOfMonth();
        $endDate = Carbon::now()->endOfMonth();
        $query->whereBetween('payment_date', [$startDate, $endDate]);

        $getQuotInvoice = $query->orderBy('id', 'DESC')->get();

        foreach ($getQuotInvoice as $invoice) {
            if ($invoice->id != null) {
                $product = POTaxInvoiceProductsDetails::query()
                    ->where('po_tax_invoice_id', $invoice->id)
                    ->with('products')
                    ->get();

                $invoice->quotation_details = $product;
            }
        }

        $topPurchaseProducts = $getQuotInvoice->flatMap(function ($invoice) {
            return $invoice->quotation_details->map(function ($quotationDetail) {
                return [
                    'product_id' => $quotationDetail->product_id,
                    'product_name' => $quotationDetail->products->name,
                    'total_sales' => $quotationDetail->modified_amount,
                ];
            });
        })->groupBy('product_id')
            ->map(function ($group) {
                return [
                    'product_id' => $group[0]['product_id'],
                    'product_name' => $group[0]['product_name'],
                    'total_sales' => $group->sum('total_sales'),
                    'invoice_count' => $group->count(),
                ];
            })
            ->sortByDesc('total_sales')
            ->values();

        $count = $topPurchaseProducts->count();


        if ($count > 0) {
            $response['top_selling_products'] = $topSellingProducts;
            $response['top_purchase_products'] = $topPurchaseProducts;
            $response['count'] = $count;
            return $this->sendResponse($response, 'Data Fetched Successfully', true);
        } else {
            return $this->sendResponse('No Data Available', [], false);
        }
    } catch (Exception $e) {
        return $this->sendError($e->getMessage(), $e->getTrace(), 500);
    }
}
    public function getPaybelLineChartDatabyGroup(Request $request): JsonResponse
{
    try {
        $validator = Validator::make($request->all(), [
            'limit' => 'numeric',
            'pageNo' => 'numeric',
            'type' => [Rule::in(['group', 'ungroup'])]
        ]);

        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors());
        }
        // Paybel data
        $query = POTaxInvoice::query()->with(['delivery_address', 'purchase_order', 'payment_terms']);
        $getPaybel_count = $query->count();
        $getPOTaxInvoice = $query->orderBy('id', 'DESC')->get();

        if ($request->has('pageNo') && $request->has('limit')) {
            $limit = $request->limit;
            $pageNo = $request->pageNo;
            $skip = $limit * $pageNo;
            $query = $query->skip($skip)->limit($limit);
        }
        if (count($getPOTaxInvoice) > 0) {
            $getPaybel = $getPOTaxInvoice->groupBy(function ($item, $key) {
                return Carbon::parse($item->payment_date)->format('Y-m');
            });

            $totalPayable = $getPaybel->map(function ($item) {
                return $item->sum('amount');
            })->flatten()->sum();
        }
        $data = [];
        $now = Carbon::now();
        // Previous month sum
        $previousMonth = $now->subMonth()->format('M Y');
        $previousMonthSum = 0;
        foreach ($getPaybel as $key => $items) {
            if ($request->input('type', 'group') === 'group') {
                foreach ($items->groupBy('company_id') as $companyItems) {
                    $monthYear = Carbon::parse($key)->format('M Y');
                    if ($monthYear === $previousMonth) {
                        $previousMonthSum += $companyItems->sum('amount');
                        break;
                    }
                }
            } else {
                $monthYear = Carbon::parse($key)->format('M Y');
                if ($monthYear === $previousMonth) {
                    $previousMonthSum = $items->sum('amount');
                    break;
                }
            }
        }
        // Next three months data
        $nextThreeMonthsData = [];
        for ($i = 1; $i <= 3; $i++) {
            $nextMonth = $now->addMonth()->format('M Y');
            if ($request->input('type', 'group') === 'group') {
                $companyData = $getPaybel->map(function ($months) use ($nextMonth) {
                    return $months->groupBy('company_id')->map(function ($items) use ($nextMonth) {
                        return $items->sum('amount');
                    })->get($nextMonth, 0);
                });
                $nextThreeMonthsData[] = [
                    'month' => $nextMonth,
                    'amount' => $companyData,
                ];
            } else {
                $amount = $getPaybel->map(function ($months) use ($nextMonth) {
                    return $months->sum('amount');
                })->get($nextMonth, 0);

                $nextThreeMonthsData[] = [
                    'month' => $nextMonth,
                    'amount' => $amount,
                ];
            }
        }
        $data[] = [
            'earlier' => [
                'amount' => $previousMonthSum,
            ],
            'next_three_months' => $nextThreeMonthsData,
        ];
        return $this->sendResponse($data, 'Data fetch successfully');
    } catch (Exception $e) {
        return $this->sendError('Something Went Wrong', $e->getTrace(), 413);
    }
}


public function getInventoryPerformance(Request $request): JsonResponse
{
    try {
        $validator = Validator::make($request->all(), [
            'type' => [Rule::in(['week_on_week', 'month_on_month'])]
        ]);

        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors());
        }

        if ($request->type == 'week_on_week') {
            $query = PoInward::query()->with(['purchase_order']);

            // Filter data for the last 12 weeks
            $startOfWeek = Carbon::now()->subWeeks(12)->startOfWeek();
            $endOfWeek = Carbon::now()->endOfWeek();
            $query->whereBetween('created_at', [$startOfWeek, $endOfWeek]);

            $getPoInward = $query->orderBy('id', 'DESC')->get();
            $getGrn = PoGrn::query()->with(['purchase_order']);
        $getGrn->whereBetween('created_at', [$startOfWeek, $endOfWeek]);
        $getgrndata = $getGrn->orderBy('id', 'DESC')->get();

        $weeklyGrnAmounts = []; // Array to store weekly GRN amounts

        foreach ($getgrndata as $user) {
            if ($user['id'] != null) {
                $product = PoGrnDetails::query()->where('po_grn_id', $user['id'])->get();
                $user['po_grn_details'] = $product;

                if ($user['purchase_order_id'] != null) {
                    $poDetails = PoDetails::query()->where('purchase_order_id', $user['purchase_order_id'])->get();
                    $user['po_details'] = $poDetails;

                    // Calculate GRN amount for each week
                    $grnAmount = 0;
                    foreach ($user['po_grn_details'] as $grnDetail) {
                        foreach ($user['po_details'] as $poDetail) {
                            if ($grnDetail['product_id'] == $poDetail['product_id']) {
                                $grnAmount += $grnDetail['accepted_qty'] * $poDetail['modified_amount'];
                            }
                        }
                    }

                    // Get the week's start date
                    $weekStartDate = Carbon::parse($user['created_at'])->startOfWeek()->format('Y-m-d');

                    // Add the GRN amount to the respective week's total
                    if (isset($weeklyGrnAmounts[$weekStartDate])) {
                        $weeklyGrnAmounts[$weekStartDate] += $grnAmount;
                    } else {
                        $weeklyGrnAmounts[$weekStartDate] = $grnAmount;
                    }
                }
            }
        }
            $weeklySum = $getPoInward->groupBy(function ($poInward) {
                return Carbon::parse($poInward->created_at)->startOfWeek()->format('Y-m-d');
            })->map(function ($group) {
                return $group->sum(function ($poInward) {
                    return $poInward->purchase_order->total_amount ?? 0;
                });
            });
            $allWeeks = Carbon::now()->subWeeks(12)->startOfWeek()->toPeriod(Carbon::now()->endOfWeek(), '1 week');
            $weekDates = iterator_to_array($allWeeks->map(function ($week) use ($weeklySum, $weeklyGrnAmounts) {
                $formattedDate = $week->startOfWeek()->format('F d');
                $totalAmount = $weeklySum[$week->format('Y-m-d')] ?? 0;
                $grnAmount = $weeklyGrnAmounts[$week->format('Y-m-d')] ?? 0;
                return [
                    'date' => $formattedDate,
                    'inward_amount' => $totalAmount,
                    'grn_amount' => $grnAmount,
                ];
            }));
            return $this->sendResponse([
                'data' => $weekDates,
            ], 'Data fetched successfully');
        }
        if ($request->type == 'month_on_month') {
            $query = PoInward::query()->with(['purchase_order']);
            $startOfMonth = Carbon::now()->subMonths(12)->startOfMonth();
            $endOfMonth = Carbon::now()->endOfMonth();
            $query->whereBetween('created_at', [$startOfMonth, $endOfMonth]);
            $getPoInward = $query->orderBy('id', 'DESC')->get();
            $getGrn = PoGrn::query()->with(['purchase_order']);
            $getGrn->whereBetween('created_at', [$startOfMonth, $endOfMonth]);
            $getgrndata = $getGrn->orderBy('id', 'DESC')->get();

            $monthlyGrnAmounts = [];

            foreach ($getgrndata as $user) {
                if ($user['id'] != null) {
                    $product = PoGrnDetails::query()->where('po_grn_id', $user['id'])->get();
                    $user['po_grn_details'] = $product;

                    if ($user['purchase_order_id'] != null) {
                        $poDetails = PoDetails::query()->where('purchase_order_id', $user['purchase_order_id'])->get();
                        $user['po_details'] = $poDetails;


                        $grnAmount = 0;
                        foreach ($user['po_grn_details'] as $grnDetail) {
                            foreach ($user['po_details'] as $poDetail) {
                                if ($grnDetail['product_id'] == $poDetail['product_id']) {
                                    $grnAmount += $grnDetail['accepted_qty'] * $poDetail['modified_amount'];
                                }
                            }
                        }

                        $weekStartDate = Carbon::parse($user['created_at'])->startOfWeek()->format('Y-m-d');


                        if (isset($weeklyGrnAmounts[$weekStartDate])) {
                            $monthlyGrnAmounts[$weekStartDate] += $grnAmount;
                        } else {
                            $monthlyGrnAmounts[$weekStartDate] = $grnAmount;
                        }
                    }
                }
            }

            $monthlySum = $getPoInward->groupBy(function ($poInward) {
                return Carbon::parse($poInward->created_at)->startOfMonth()->format('Y-m-d');
            })->map(function ($group) {
                return $group->sum(function ($poInward) {
                    return $poInward->purchase_order->total_amount ?? 0;
                });
            });

            $allMonths = Carbon::now()->subMonths(12)->startOfMonth()->toPeriod(Carbon::now()->endOfMonth(), '1 month');

            $monthDates = iterator_to_array($allMonths->map(function ($month) use ($monthlySum, $monthlyGrnAmounts) {
                $formattedDate = $month->startOfMonth()->format('F Y');
                $totalAmount = $monthlySum[$month->format('Y-m-d')] ?? 0;
                $grnAmount = $monthlyGrnAmounts[$month->format('Y-m-d')] ?? 0;
                return [
                    'date' => $formattedDate,
                    'inward_amount' => $totalAmount,
                    'grn_amount' => $grnAmount,
                ];
            }));

            return $this->sendResponse([
                'data' => $monthDates,
            ], 'Data fetched successfully');
        }

        return $this->sendError('Invalid type.', 'Type should be either "week_on_week" or "month_on_month".');
    } catch (Exception $e) {
        return $this->sendError('Something Went Wrong', $e->getTrace(), 413);
    }
}

public function addDeliverLocationAddress(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'address_line_1' => 'nullable|string',
                'address_line_2' => 'nullable',
                'pincode' => 'nullable|string',
                'state' => 'nullable|string',
                'city' => 'nullable|string',
                'country' => 'nullable|string',
                'client_id' => 'nullable|numeric|exists:clients,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newAddress = new ClientAddress();
            $newAddress->address_line_1 = $request->address_line_1;
            $newAddress->address_line_2 = $request->address_line_2;
            $newAddress->pincode = $request->pincode;
            $newAddress->state = $request->state;
            $newAddress->city = $request->city;
            $newAddress->country = $request->country;
            //$newAddress->client_id = $request->client_id;
            $newAddress->address_for='organization';
            $newAddress->save();

            return $this->sendResponse([], 'Delivery address added successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function addBillingAddress(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'address_line_1' => 'nullable|string',
                'address_line_2' => 'nullable',
                'pincode' => 'nullable|string',
                'state' => 'nullable|string',
                'city' => 'nullable|string',
                'country' => 'nullable|string',
                'client_id' => 'nullable|numeric|exists:clients,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newAddress = new ClientAddress();
            $newAddress->address_line_1 = $request->address_line_1;
            $newAddress->address_line_2 = $request->address_line_2;
            $newAddress->pincode = $request->pincode;
            $newAddress->state = $request->state;
            $newAddress->city = $request->city;
            $newAddress->country = $request->country;
            //$newAddress->client_id = $request->client_id;
            $newAddress->address_for='organization';
            $newAddress->save();

            return $this->sendResponse([], 'Billing address added successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }





}
