<?php

namespace App\Http\Controllers;


use Illuminate\Support\Facades\Auth;
use Alert;
use DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Http;
use Validator;
use Carbon\Carbon;
use App\Models\VisitorProduct;

use Illuminate\Http\Request;


class ZohoCrmController extends Controller
{

    public function  zoho_crm(Request $request)
    {

        $code  = $request->get('code');
        $location =   $request->get('location');
        $accounts_server  = $request->get('accounts-server');

        $zoho_crm_data =   DB::table('zoho_crm')->first();

        DB::table('zoho_crm')->where('id', $zoho_crm_data->id)->update(['code' => $code]);
        $status ='';
        $responseData = '';
        if (!empty($zoho_crm_data) && isset($code)) {
            $client_id = $zoho_crm_data->client_id;
            $client_secret = $zoho_crm_data->client_secret;
            $redirect_url = $request->url();
            // dd($client_id,$redirect_url);
            // Prepare the cURL request
            $url = "https://accounts.zoho.in/oauth/v2/token";
            $postFields = http_build_query([
                'client_id' => $client_id,
                'client_secret' => $client_secret,
                'redirect_uri' => $redirect_url,
                'code' => $code,
                'grant_type' => 'authorization_code',
            ]);

            $ch = curl_init();

            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'Content-Type: application/x-www-form-urlencoded',
            ]);

            $response = curl_exec($ch);
        
            \Log::error('cURL response from ZOHO CRM: ' . $response);
            $responseData = [];
            $status ='';
            if (curl_errno($ch)) {
                $status ='error';  
                $error_msg = curl_error($ch);                
                \Log::error('cURL Error ZOHO CRM: ' . $error_msg);
            } else {               
                // Decode the JSON response
                $responseData = json_decode($response, true);

                // Check if the access token exists in the response
                if (isset($responseData['access_token'])) {
                    $status ='success';
                    DB::table('zoho_crm')->where('id', '1')->update(['access_token' => $responseData['access_token'], 'refresh_token' => $responseData['refresh_token'] ?? '', 'server_url' => $responseData['api_domain']]);
                } else {             
                    $status ='error';     
                    \Log::error('Access token not found in ZOHO CRM response: ' . json_encode($responseData));
                }
            }


            curl_close($ch);
        }

        // dd($code,$location,$accounts_server);
        return view('settings.zoho_crm',compact('status','responseData'));
    }
    public function zoho_crm_save(Request $request)
    {
        try {

            // Validate the incoming request data
            $validatedData = $request->validate([               
                'client_id' => 'required',
                'client_secret' => 'required',
            ]);

            $server_url =   $request->server_url;
            $client_id = $request->client_id;
            $client_secret = $request->client_secret;

            $zohodata = [
                'client_id' => $client_id,
                'client_secret' => $client_secret,
            ];

            $zoho_route =  route('zoho_crm');
            // $redirect_url =  'https://accounts.zoho.com/oauth/v2/auth?response_type=code&client_id=1000.MR8GNFHXIQOAXCUZPLFTG9EUSC5ICE&scope=ZohoCRM.modules.leads.ALL&redirect_uri=https://emp.frenzinsoftwares.com/log_request.php';
            $redirect_url =  'https://accounts.zoho.com/oauth/v2/auth?response_type=code&client_id=' . $client_id . '&scope=ZohoCRM.modules.leads.ALL,ZohoCRM.files.CREATE&redirect_uri=' . $zoho_route . '&access_type=offline';

            // Check if a record already exists
            $existingRecord = DB::table('zoho_crm')->where('id', 1)->first();

            if ($existingRecord) {
                // Update only the client_id and client_secret, and set updated_at
                DB::table('zoho_crm')->where('id', 1)->update([
                    'client_id' => $client_id,
                    'client_secret' => $client_secret,
                    'updated_at' => Carbon::now('Asia/Kolkata'),
                ]);
            } else {
                // Insert new record with created_at and updated_at
                $zohodata['created_at'] = Carbon::now('Asia/Kolkata');
                DB::table('zoho_crm')->insert($zohodata);
            }
            // Alert::success('Congrats', 'Zoho Crm key generated successfully');
            // return redirect()->back();
            return redirect($redirect_url);
        } catch (\Exception $e) {
            Alert::error('Error', 'Something went Wrong while generated zoho crm key.');
            return redirect()->back();
        }
    }

    public function zohocrmVisitorLeadsCron(Request $request)
    {
        $zoho_crm_data = DB::table('zoho_crm')->first();

        if (empty($zoho_crm_data)) {
            echo 'Zoho CRM Data Not Found';
            return;
        }

        $visitors_query = DB::table('visitors')
            ->join('events', 'visitors.event_id', '=', 'events.id')->select('visitors.*',
                'visitors.id as visitor_id',
                'events.event_name'
            )->orderBy('visitors.id', 'desc');

        // if (!empty($zoho_crm_data->cronjob_date)) {
        //     $visitors_query->whereDate('visitors.updated_at', '>', $zoho_crm_data->cronjob_date);
        // }

        $visitors_query->whereNull('visitors.zoho_id');

        $visitors = $visitors_query->get()->map(function ($visitor) {
            $names = explode(' ', $visitor->name);

            $visitorData = [
                'visitor_id' => $visitor->visitor_id,
                'Company' => $visitor->company_name,
                'Last_Name' => isset($names[1]) ? implode(' ', array_slice($names, 1)) : 'last name',
                'First_Name' => $names[0],
                'Email' => $visitor->email,
                'State' => $visitor->state ?? 'state',
                'Lead_Source' => $visitor->event_name ?? '',               
                'front_image' => $visitor->front_image ?? '',
                'back_image' => $visitor->back_image ?? '',
                'Phone'=>$visitor->mobile_no2 ?? '',
                'Industry'=>$visitor->category ?? '', 
                'Secondary_Email'=> $visitor->email2 ?? '',
                'Website'=>$visitor->website ?? '',             
                'City'=>$visitor->city ?? '',
                'Country'=>$visitor->country_code ?? '',
                'Street'=>$visitor->address ?? '',
                'Zip_Code'=>$visitor->pincode ?? '',
                'Title'=>$visitor->designation ?? ''
            ];
           
            if (!empty($visitor->mobile_no)) {
                $visitorData['Mobile'] = $visitor->mobile_no;
            }

            // Product and remarks
            $Description =  '';
            $products = '';
            $visitorProducts = VisitorProduct::where('visitor_id',$visitor->visitor_id)->get();
         
            if(count($visitorProducts) > 0){
                $productNames =  [];            
                foreach($visitorProducts as $vproduct){
                    $productNames[] = $vproduct->ProductName;
                }
                $products = implode(',',$productNames);            
            }

            if (!empty($products)) {
                $Description .= "\n\nProducts: $products";
            }
            
            if (!empty($visitor->remarks)) {
                if (!empty($products)) {
                    $Description .= "\n\n";
                }
                $Description .= "Remarks: $visitor->remarks";
            }
           
            $visitorData['Description'] = $Description;
            // Product and remarks end           
            return $visitorData;
        });



        if ($visitors->isEmpty()) {
            echo 'No leads found';
            return;
        }

        $zoho_visitors =  [];

        foreach ($visitors as $v => $visitor) {

            // Images code Start here

            $images = [];

            if (!empty($visitor['front_image'])) {
                $frontImageName = basename($visitor['front_image']);
                $imagePath = public_path('../../' . config('constants.API_PROJECT_NAME') . '/public/uploads/visitor/' . $frontImageName);
                if (file_exists($imagePath)) {
                    $images[] = new \CURLFile($imagePath);
                }
            }

            if (!empty($visitor['back_image'])) {
                $backImageName = basename($visitor['back_image']);
                $imagePath = public_path('../../' . config('constants.API_PROJECT_NAME') . '/public/uploads/visitor/' . $backImageName);
                if (file_exists($imagePath)) {
                    $images[] = new \CURLFile($imagePath);
                }
            }

            $image_upload_response = "";
            if (count($images) > 0) {
                $image_upload_response = $this->uploadDynamicFilesToZoho($images, $zoho_crm_data);
            }

            if (is_array($image_upload_response) && count($image_upload_response) > 0) {
                $visitor['Record_Image'] = $image_upload_response[0]->File_Id__s;
                if (count($image_upload_response) == '2') {
                    unset($image_upload_response[0]);
                    $visitor['File_upload'] = $image_upload_response;
                }
            }

            // Images code End here
            unset($visitor['visitor_id']);
            unset($visitor['front_image']);
            unset($visitor['back_image']);
            $zoho_visitors[] = $visitor;
        }

        $data = [
            'data' => $zoho_visitors,
            "duplicate_check_fields" => [
                "Email",
            ],
            'trigger' => ['approval', 'workflow', 'blueprint']
        ];

        $response = $this->sendZohoRequest('https://www.zohoapis.in/crm/v7/Leads/upsert', $data, $zoho_crm_data->access_token);

        if (in_array($response->httpCode, [200, 201])) {
            $this->handleZohoResponse($response->data, $visitors, $zoho_crm_data);
        } elseif ($response->httpCode == 207) {
            // Call the new function to handle the 207 multi-status response
            $this->handleMultiStatusResponse($response->data, $visitors, $zoho_crm_data);
        } elseif ($response->code === 'INVALID_TOKEN') {
            $refreshResponse = $this->refreshAccessToken($zoho_crm_data);

            if (isset($refreshResponse->access_token)) {
                DB::table('zoho_crm')->where('id', $zoho_crm_data->id)->update(['access_token' => $refreshResponse->access_token]);

                $retryResponse = $this->sendZohoRequest('https://www.zohoapis.in/crm/v7/Leads', $data, $refreshResponse->access_token);
                if ($retryResponse->httpCode == 207) {
                    $this->handleMultiStatusResponse($retryResponse->data, $visitors, $zoho_crm_data);
                } else {
                    $this->handleZohoResponse($retryResponse->data, $visitors, $zoho_crm_data);
                }
            } else {
                echo $this->response($refreshResponse, 'Error');
                return;
            }
        } else {
            echo $this->response($response, 'Error');
            return;
        }
    }

    private function sendZohoRequest($url, $data, $accessToken)
    {

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Authorization: Zoho-oauthtoken ' . $accessToken
        ]);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        return (object)[
            'httpCode' => $httpCode,
            'data' => json_decode($response),
            'code' => isset(json_decode($response)->code) ? json_decode($response)->code : null
        ];
    }

    private function refreshAccessToken($zoho_crm_data)
    {
        $refreshData = [
            'client_id' => $zoho_crm_data->client_id,
            'client_secret' => $zoho_crm_data->client_secret,
            'refresh_token' => $zoho_crm_data->refresh_token,
            'grant_type' => 'refresh_token'
        ];

        $ch = curl_init('https://accounts.zoho.in/oauth/v2/token');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($refreshData));

        $refreshResponse = curl_exec($ch);
        curl_close($ch);

        return json_decode($refreshResponse);
    }

    public function response($response, $status)
    {
        echo '<pre>';
        echo  $status . ' ' . print_r($response, true);
        echo '<pre>';
        return;
    }

    private function handleZohoResponse($responseData, $visitors, $zoho_crm_data)
    {
        $approvedRecordsCount = 0;

        foreach ($responseData->data as $key => $record) {
            if ($record->code === 'SUCCESS' && isset($record->details->id)) {
                $zohoId = $record->details->id;

                // Update the visitor with the Zoho ID
                DB::table('visitors')->where('id', $visitors[$key]['visitor_id'])->update(['zoho_id' => $zohoId]);

                $approvedRecordsCount++;
            }
        }

        if ($approvedRecordsCount > 0) {
            // Update the cronjob date only if records were approved
            DB::table('zoho_crm')->where('id', $zoho_crm_data->id)->update(['cronjob_date' => Carbon::now('Asia/Kolkata')]);
        }

        echo $this->response($responseData, 'Success');
    }

    private function handleMultiStatusResponse($responseData, $visitors, $zoho_crm_data)
    {
        $approvedRecordsCount = 0;
        $failedRecords = [];

        foreach ($responseData->data as $key => $record) {
            if ($record->code === 'SUCCESS' && isset($record->details->id)) {
                $zohoId = $record->details->id;

                DB::table('visitors')->where('id', $visitors[$key]['visitor_id'])->update(['zoho_id' => $zohoId]);

                $approvedRecordsCount++;
            } else {
                $failedRecords[] = [
                    'visitor_id' => $visitors[$key]['visitor_id'],
                    'code' => $record->code,
                    'message' => $record->message,
                    'details' => isset($record->details) ? (array) $record->details : 'No details available'
                ];
            }
        }

        if (!empty($failedRecords)) {
            Log::error('Zoho CRM Lead Sync Errors', $failedRecords);
            echo 'Some records failed to sync. Check logs for details.';
        }

        if ($approvedRecordsCount > 0) {
            DB::table('zoho_crm')->where('id', $zoho_crm_data->id)->update(['cronjob_date' => Carbon::now('Asia/Kolkata')]);
        }

        echo $this->response($responseData, $approvedRecordsCount > 0 ? 'Partial Success' : 'Failed');
    }

    // Working static code
    // private function uploadStaticFilesToZoho($zoho_crm_data)
    // {
    //     // Define the Zoho API endpoint (replace with correct domain and version)
    //     $apiUrl = 'https://www.zohoapis.in/crm/v7/files'; // Adjust for your region if necessary

    //     // Define the static file paths (ensure these paths are correct and accessible)
    //     $file1Path = storage_path('app/static/connections.txt');
    //     $file2Path = storage_path('app/static/pexels-charlotte-may-5824830.jpg');

    //     // Validate if the files exist
    //     if (!file_exists($file1Path) || !file_exists($file2Path)) {
    //         return 'Error: One or more files not found.';
    //     }

    //     // Set the authorization token and headers
    //     $headers = [
    //         'Authorization' => 'Zoho-oauthtoken ' . $zoho_crm_data->access_token,
    //     ];

    //     // Prepare the request
    //     $response = Http::withHeaders($headers)
    //         ->attach('file', fopen($file1Path, 'r'), 'connections.txt') // First file
    //         ->attach('file', fopen($file2Path, 'r'), 'pexels-charlotte-may-5824830.jpg') // Second file
    //         ->post($apiUrl, [
    //             'type' => 'inline', // Optional parameter to indicate inline images
    //         ]);

    //     // Check if the request was successful
    //     if ($response->successful()) {
    //         return 'Files uploaded successfully: ' . $response->body();
    //     }

    //     // Handle error response
    //     return 'Error uploading files: ' . $response->body();
    // }

    private function uploadDynamicFilesToZoho($images, $zoho_crm_data)
    {

        $apiUrl = 'https://www.zohoapis.in/crm/v7/files';

        $headers = [
            'Authorization' => 'Zoho-oauthtoken ' . $zoho_crm_data->access_token,
        ];

        if (empty($images)) {
            return 'Error: No images to upload.';
        }

        $request = Http::withHeaders($headers);

        foreach ($images as $index => $image) {
            $request = $request->attach('file', fopen($image->getFilename(), 'r'), $image->getPostFilename());
        }

        $response = $request->post($apiUrl, [
            'type' => 'inline',
        ]);


        if ($response->successful()) {
            $responseData = $response->json();
            $fileIds = [];  // Initialize the array

            foreach ($responseData['data'] as $fileData) {
                if (isset($fileData['details']['id'])) {
                    $fileIds[] = (object)[
                        'File_Id__s' => $fileData['details']['id'],
                    ];
                }
            }
            return $fileIds;
        } else {
            $refreshResponse = $this->refreshAccessToken($zoho_crm_data);
            if (isset($refreshResponse->access_token)) {
                DB::table('zoho_crm')->where('id', $zoho_crm_data->id)->update(['access_token' => $refreshResponse->access_token]);
                $response = $this->uploadDynamicFilesToZoho($images, $zoho_crm_data);
                return $response;
            }
        }

        return 'Error uploading files: ' . $response->body();
    }
}
