<?php
defined('BASEPATH') or exit('No direct script access allowed');

class DocusignService
{
    protected $config;

    public function __construct()
    {
        $CI = &get_instance();
        $CI->load->config('docusign');
        $this->config = [
            'integration_key'       => $CI->config->item('integration_key'),
            'user_id'               => $CI->config->item('user_id'),
            'account_id'            => $CI->config->item('account_id'),
            'rsa_private_key_path'  => $CI->config->item('rsa_private_key_path'),
            'expires_in'            => $CI->config->item('expires_in'),
            'base_path'             => $CI->config->item('base_path'),
            'auth_server'           => $CI->config->item('auth_server'),
            'scope'                 => $CI->config->item('scope'),
        ];
    }

    public function createJWTToken()
    {
        $integrationKey = $this->config['integration_key'];
        $userId         = $this->config['user_id'];
        $authServer     = $this->config['auth_server'];
        $keyPath        = $this->config['rsa_private_key_path'];
        $scopes         = [$this->config['scope'], 'impersonation'];

        if (!file_exists($keyPath)) {
            throw new RuntimeException("Private key not found: {$keyPath}");
        }

        $privateKey = file_get_contents($keyPath);
        $base64url = function ($data) {
            return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
        };

        $header = $base64url(json_encode(['alg' => 'RS256', 'typ' => 'JWT']));
        $now = time();
        $payload = $base64url(json_encode([
            'iss' => $integrationKey,
            'sub' => $userId,
            'aud' => $authServer,
            'iat' => $now,
            'exp' => $now + $this->config['expires_in'],
            'scope' => implode(' ', $scopes)
        ]));

        $data = $header . '.' . $payload;
        if (!openssl_sign($data, $signature, $privateKey, OPENSSL_ALGO_SHA256)) {
            throw new RuntimeException('Failed to sign JWT.');
        }
        $jwt = $data . '.' . $base64url($signature);

        $url = "https://{$authServer}/oauth/token";
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => ["Content-Type: application/x-www-form-urlencoded"],
            CURLOPT_POSTFIELDS => http_build_query([
                'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
                'assertion' => $jwt
            ])
        ]);
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode < 200 || $httpCode >= 300) {
            throw new RuntimeException("JWT request failed: {$response}");
        }

        $data = json_decode($response, true);
        if (empty($data['access_token'])) {
            throw new RuntimeException("No access token returned: {$response}");
        }

        return $data['access_token'];
    }

    public function createTemplateAndReturnSenderView($accessToken, $data)
    {
        foreach (['documentBase64', 'fileName', 'returnUrl'] as $field) {
            if (empty($data[$field])) throw new RuntimeException("Missing required field: {$field}");
        }

        $accountId = $this->config['account_id'];
        $url = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates";

        $body = [
            'name' => 'Template - ' . date('YmdHis'),
            'emailSubject' => 'Please prepare template',
            'documents' => [[
                'documentBase64' => $data['documentBase64'],
                'name' => $data['fileName'],
                'fileExtension' => pathinfo($data['fileName'], PATHINFO_EXTENSION),
                'documentId' => '1'
            ]],
            //add extra feidls here if needed

            'status' => 'created'
        ];

        $response = $this->sendCurlRequest($url, $accessToken, $body);
        $templateResp = json_decode($response, true);
        if (empty($templateResp['templateId'])) throw new RuntimeException("Failed to create template: {$response}");
        $templateId = $templateResp['templateId'];

        $viewUrl = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates/{$templateId}/views/edit";
        $viewResp = $this->sendCurlRequest($viewUrl, $accessToken, ['returnUrl' => $data['returnUrl']]);
        $viewData = json_decode($viewResp, true);

        return ['templateId' => $templateId, 'senderViewUrl' => $viewData['url'] ?? ''];
    }


    /**
     * Clone an existing template (with fields) and open optimized sender view
     *
     * @param string $accessToken
     * @param string $templateId
     * @param string $returnUrl
     * @return array ['templateId' => new template ID, 'senderViewUrl' => sender view URL]
     * @throws RuntimeException
     */
    public function cloneTemplateWithFields(string $accessToken, string $templateId, string $returnUrl = null): array
    {
        $accountId = $this->config['account_id'];

        // 1 Fetch base template metadata
        $url = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates/{$templateId}";
        $response = $this->sendCurlRequest($url, $accessToken, null, 'GET');
        $templateData = json_decode($response, true);

        if (empty($templateData['templateId'])) {
            throw new RuntimeException("Failed to fetch template metadata: {$response}");
        }

        // 2 Fetch and encode documents
        $newDocuments = [];
        if (!empty($templateData['documents'])) {
            foreach ($templateData['documents'] as $doc) {
                $docId = $doc['documentId'];
                $docUrl = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates/{$templateId}/documents/{$docId}";
                $docContent = $this->sendCurlRequest($docUrl, $accessToken, null, 'GET', true);

                $newDocuments[] = [
                    'documentId'     => $docId,
                    'name'           => $doc['name'],
                    'fileExtension'  => pathinfo($doc['name'], PATHINFO_EXTENSION),
                    'documentBase64' => base64_encode($docContent)
                ];
            }
        }

        // Sanitize helper (fixes DocuSign localePolicy issue)
        $sanitizeTabs = function (&$tabs) {
            foreach ($tabs as $tabType => &$tabList) {
                if (is_array($tabList)) {
                    foreach ($tabList as &$tab) {
                        if (isset($tab['localePolicy']) && is_array($tab['localePolicy'])) {
                            if (empty($tab['localePolicy'])) {
                                unset($tab['localePolicy']);
                            } else {
                                $tab['localePolicy'] = (object)$tab['localePolicy'];
                            }
                        }
                    }
                }
            }
        };

        // 3 Fetch and clean recipient tabs
        $newRecipients = ['signers' => []];
        if (!empty($templateData['recipients']['signers'])) {
            foreach ($templateData['recipients']['signers'] as $signer) {
                $recipientId = $signer['recipientId'];
                $tabsUrl = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates/{$templateId}/recipients/{$recipientId}/tabs";
                $tabsResponse = $this->sendCurlRequest($tabsUrl, $accessToken, null, 'GET');
                $tabs = json_decode($tabsResponse, true);

                $sanitizeTabs($tabs);

                $newRecipients['signers'][] = [
                    'roleName'     => $signer['roleName'] ?? 'Signer',
                    'recipientId'  => $recipientId,
                    'routingOrder' => $signer['routingOrder'] ?? '1',
                    'tabs'         => $tabs
                ];
            }
        }

        // 4 Create the cloned template
        $newTemplateBody = [
            'name'         => 'Cloned Template - ' . date('YmdHis'),
            'emailSubject' => $templateData['emailSubject'] ?? 'Please prepare this template',
            'documents'    => $newDocuments,
            'recipients'   => $newRecipients,
            'status'       => 'created'
        ];

        $createUrl = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates";
        $createResponse = $this->sendCurlRequest($createUrl, $accessToken, $newTemplateBody);
        $newTemplateData = json_decode($createResponse, true);

        if (empty($newTemplateData['templateId'])) {
            throw new RuntimeException("Failed to create cloned template: {$createResponse}");
        }

        $newTemplateId = $newTemplateData['templateId'];


        return [
            'success' => 1,
            'message' => 'Fresh template created ',
            'data' => [
                'template_id' => $newTemplateId,
            ]
        ];
    }

    public function createFreshTemplateFromExisting($templateId)
    {
        $accountId = $this->config['account_id'];
        $accessToken = $this->createJWTToken();

        $docUrl = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates/{$templateId}/documents/1";
        $docResponse = $this->sendCurlRequest($docUrl, $accessToken, null, true);
        if (!$docResponse) {
            return [
                'success' => 0,
                'message' => "Failed to download template document"
            ];
        }
        $documentBase64 = base64_encode($docResponse);

        $url = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates";

        $body = [
            'name' => 'FreshTemplate_' . time(),
            'emailSubject' => 'Please sign',
            'documents' => [[
                'documentBase64' => $documentBase64,
                'name' => 'template.pdf',
                'fileExtension' => 'pdf',
                'documentId' => '1'
            ]],
            // 'recipients' => [
            //     'signers' => [[
            //         'recipientId' => '1',
            //         'roleName' => 'Client',
            //         'routingOrder' => '1'
            //     ]]
            // ],
            'status' => 'created'
        ];

        $createResp = $this->sendCurlRequest($url, $accessToken, $body);
        $createData = json_decode($createResp, true);
        $template_id = $createData['templateId'] ?? '';

        if (empty($createData['templateId'])) {
            return [
                'success' => 0,
                'message' => 'Failed to create fresh template',
                'data' => $createData
            ];
        }

        return [
            'success' => 1,
            'message' => 'Fresh template created ✅',
            'data' => [
                'template_id' => $template_id,
            ]
        ];
    }






    // public function cloneTemplateWithFields(string $accessToken, string $templateId, string $returnUrl): array
    // {
    //     $accountId = $this->config['account_id'];

    //     // 1️⃣ Fetch basic template info
    //     $url = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates/{$templateId}";
    //     $response = $this->sendCurlRequest($url, $accessToken, null, 'GET');
    //     $templateData = json_decode($response, true);

    //     if (empty($templateData['templateId'])) {
    //         throw new RuntimeException("Failed to fetch template metadata: {$response}");
    //     }

    //     // 2️⃣ Fetch and Base64 encode all documents
    //     $newDocuments = [];
    //     if (!empty($templateData['documents'])) {
    //         foreach ($templateData['documents'] as $doc) {
    //             $docId = $doc['documentId'];
    //             $docUrl = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates/{$templateId}/documents/{$docId}";
    //             $docContent = $this->sendCurlRequest($docUrl, $accessToken, null, 'GET', true);

    //             $newDocuments[] = [
    //                 'documentId'     => $docId,
    //                 'name'           => $doc['name'],
    //                 'fileExtension'  => pathinfo($doc['name'], PATHINFO_EXTENSION),
    //                 'documentBase64' => base64_encode($docContent)
    //             ];
    //         }
    //     }

    //     // Helper function to sanitize tabs
    //     $sanitizeTabs = function (&$tabs) {
    //         foreach ($tabs as $tabType => &$tabList) {
    //             if (is_array($tabList)) {
    //                 foreach ($tabList as &$tab) {
    //                     if (isset($tab['localePolicy']) && is_array($tab['localePolicy'])) {
    //                         // Fix: localePolicy must be object, not array
    //                         if (empty($tab['localePolicy'])) {
    //                             unset($tab['localePolicy']);
    //                         } else {
    //                             $tab['localePolicy'] = (object)$tab['localePolicy'];
    //                         }
    //                     }
    //                 }
    //             }
    //         }
    //     };

    //     // 3️⃣ Fetch recipients and their tabs separately
    //     $newRecipients = ['signers' => []];
    //     if (!empty($templateData['recipients']['signers'])) {
    //         foreach ($templateData['recipients']['signers'] as $signer) {
    //             $recipientId = $signer['recipientId'];
    //             $tabsUrl = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates/{$templateId}/recipients/{$recipientId}/tabs";
    //             $tabsResponse = $this->sendCurlRequest($tabsUrl, $accessToken, null, 'GET');
    //             $tabs = json_decode($tabsResponse, true);

    //             // 🔧 Sanitize malformed localePolicy fields
    //             $sanitizeTabs($tabs);

    //             $newRecipients['signers'][] = [
    //                 'roleName'     => $signer['roleName'] ?? 'Signer',
    //                 'recipientId'  => $recipientId,
    //                 'routingOrder' => $signer['routingOrder'] ?? '1',
    //                 'tabs'         => $tabs
    //             ];
    //         }
    //     }

    //     // 4️⃣ Create new cloned template
    //     $newTemplateBody = [
    //         'name'         => 'Cloned Template - ' . date('YmdHis'),
    //         'emailSubject' => $templateData['emailSubject'] ?? 'Please prepare this template',
    //         'documents'    => $newDocuments,
    //         'recipients'   => $newRecipients,
    //         'status'       => 'created'
    //     ];

    //     $createUrl = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates";
    //     $createResponse = $this->sendCurlRequest($createUrl, $accessToken, $newTemplateBody);
    //     $newTemplateData = json_decode($createResponse, true);

    //     if (empty($newTemplateData['templateId'])) {
    //         throw new RuntimeException("Failed to create cloned template: {$createResponse}");
    //     }

    //     $newTemplateId = $newTemplateData['templateId'];

    //     // 5️⃣ Generate sender view URL
    //     $viewUrl = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates/{$newTemplateId}/views/edit";
    //     $viewResp = $this->sendCurlRequest($viewUrl, $accessToken, ['returnUrl' => $returnUrl]);
    //     $viewData = json_decode($viewResp, true);

    //     if (empty($viewData['url'])) {
    //         throw new RuntimeException("Failed to get sender view URL: {$viewResp}");
    //     }

    //     return [
    //         'templateId'    => $newTemplateId,
    //         'senderViewUrl' => $viewData['url']
    //     ];
    // }


    public function createEnvelopeFromTemplate($accessToken, $params)
    {
        $accountId = $this->config['account_id'];
        $url = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/envelopes";

        // 🔥 CRITICAL: When using compositeTemplates, you MUST provide tab values
        $body = [
            'status' => 'sent',
            'compositeTemplates' => [
                [
                    'serverTemplates' => [
                        [
                            'sequence' => '1',
                            'templateId' => $params['templateId']
                        ]
                    ],
                    'inlineTemplates' => [
                        [
                            'sequence' => '1',
                            'recipients' => [
                                'signers' => [
                                    [
                                        'email'        => $params['email'],
                                        'name'         => $params['name'],
                                        'roleName'     => $params['roleName'] ?? 'Client',
                                        'recipientId'  => '1',
                                        'clientUserId' => $params['clientUserId'] ?? '1234',
                                        //  FIX: Explicitly populate tab values
                                        'emailAddress' => $params['email'], // Add this
                                        'tabs' => [
                                            // Only populate emailTabs if they exist in template
                                            'emailTabs' => [
                                                [
                                                    'tabLabel' => '', // Empty = match first email tab
                                                    'value' => $params['email']
                                                ]
                                            ],
                                            'fullNameTabs' => [
                                                [
                                                    'tabLabel' => '', // Empty = match first fullname tab
                                                    'value' => $params['name']
                                                ]
                                            ]
                                        ]
                                    ]
                                ]
                            ]
                        ]
                    ]
                ]
            ]
        ];

        $response = $this->sendCurlRequest($url, $accessToken, $body);
        return json_decode($response, true);
    }
    // public function createEnvelopeFromTemplate($accessToken, $params)
    // {
    //     $accountId = $this->config['account_id'];
    //     $url = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/envelopes";

    //     // 🔹 Envelope request body using an existing template
    //     $body = [
    //         'status' => 'sent', // send immediately
    //         'compositeTemplates' => [
    //             [
    //                 'serverTemplates' => [
    //                     [
    //                         'sequence' => '1',
    //                         'templateId' => $params['templateId']
    //                     ]
    //                 ],
    //                 'inlineTemplates' => [
    //                     [
    //                         'sequence' => '1',
    //                         'recipients' => [
    //                             'signers' => [
    //                                 [
    //                                     'email'        => $params['email'],
    //                                     'name'         => $params['name'],
    //                                     'roleName'     => $params['roleName'] ?? '',
    //                                     'recipientId'  => '1',
    //                                     'clientUserId' => $params['clientUserId'] ?? '1234'
    //                                 ]
    //                             ]
    //                         ]
    //                     ]
    //                 ]
    //             ]
    //         ]
    //     ];

    //     // 🔹 Send the request to DocuSign API
    //     $response = $this->sendCurlRequest($url, $accessToken, $body);
    //     return json_decode($response, true);
    // }


    //method when we are merging,,.. enable when we need it
    // public function createEnvelopeFromTemplate($accessToken, $params)
    // {
    //     $accountId = $this->config['account_id'];
    //     $url = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/envelopes";

    //     // If a templateId is provided, build compositeTemplates so template tabs are applied
    //     if (!empty($params['templateId'])) {
    //         // $body = [
    //         //     'status' => 'sent',
    //         //     'compositeTemplates' => [
    //         //         [
    //         //             'serverTemplates' => [
    //         //                 [
    //         //                     'sequence' => '1',
    //         //                     'templateId' => $params['templateId']
    //         //                 ]
    //         //             ],
    //         //             'inlineTemplates' => [
    //         //                 [
    //         //                     'sequence' => '1',
    //         //                     'recipients' => [
    //         //                         'signers' => [
    //         //                             [
    //         //                                 'email' => $params['email'],
    //         //                                 'name' => $params['name'],
    //         //                                 'roleName' => $params['roleName'] ?? 'user',
    //         //                                 'recipientId' => '1',
    //         //                                 'clientUserId' => $params['clientUserId'] ?? '1234'
    //         //                             ]
    //         //                         ]
    //         //                     ]
    //         //                 ]
    //         //             ],
    //         //             'document' => [
    //         //                 'documentBase64' => $params['documentBase64'],
    //         //                 'name' => $params['fileName'] ?? 'Agreement.pdf',
    //         //                 'fileExtension' => pathinfo($params['fileName'] ?? 'Agreement.pdf', PATHINFO_EXTENSION),
    //         //                 // must match the template's documentId
    //         //                 'documentId' => '1'
    //         //             ]
    //         //         ]
    //         //     ]
    //         // ];
    //         $body = [
    //             'status' => 'sent',
    //             'compositeTemplates' => [
    //                 [
    //                     'serverTemplates' => [
    //                         [
    //                             'sequence' => '1',
    //                             'templateId' => $params['templateId']
    //                         ]
    //                     ],
    //                     'inlineTemplates' => [
    //                         [
    //                             'sequence' => '1',
    //                             'recipients' => [
    //                                 'signers' => [
    //                                     [
    //                                         'email' => $params['email'],
    //                                         'name' => $params['name'],
    //                                         'roleName' => $params['roleName'] ?? 'Client',
    //                                         'recipientId' => '1',
    //                                         'clientUserId' => $params['clientUserId'] ?? '1234'
    //                                     ]
    //                                 ]
    //                             ]
    //                         ]
    //                     ]
    //                 ]
    //             ]
    //         ];
    //     }
    //     // print_r($body);
    //     // exit;
    //     $response = $this->sendCurlRequest($url, $accessToken, $body);
    //     return json_decode($response, true);
    // }



    //method when we are merging,,.. enable when we need it
    // public function createEnvelopeFromTemplate($accessToken, $params)
    // {
    //     $accountId = $this->config['account_id'];
    //     $url = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/envelopes";

    //     // If a templateId is provided, build compositeTemplates so template tabs are applied
    //     if (!empty($params['templateId'])) {
    //         // $body = [
    //         //     'status' => 'sent',
    //         //     'compositeTemplates' => [
    //         //         [
    //         //             'serverTemplates' => [
    //         //                 [
    //         //                     'sequence' => '1',
    //         //                     'templateId' => $params['templateId']
    //         //                 ]
    //         //             ],
    //         //             'inlineTemplates' => [
    //         //                 [
    //         //                     'sequence' => '1',
    //         //                     'recipients' => [
    //         //                         'signers' => [
    //         //                             [
    //         //                                 'email' => $params['email'],
    //         //                                 'name' => $params['name'],
    //         //                                 'roleName' => $params['roleName'] ?? 'user',
    //         //                                 'recipientId' => '1',
    //         //                                 'clientUserId' => $params['clientUserId'] ?? '1234'
    //         //                             ]
    //         //                         ]
    //         //                     ]
    //         //                 ]
    //         //             ],
    //         //             'document' => [
    //         //                 'documentBase64' => $params['documentBase64'],
    //         //                 'name' => $params['fileName'] ?? 'Agreement.pdf',
    //         //                 'fileExtension' => pathinfo($params['fileName'] ?? 'Agreement.pdf', PATHINFO_EXTENSION),
    //         //                 // must match the template's documentId
    //         //                 'documentId' => '1'
    //         //             ]
    //         //         ]
    //         //     ]
    //         // ];
    //         $body = [
    //             'status' => 'sent',
    //             'compositeTemplates' => [
    //                 [
    //                     'serverTemplates' => [
    //                         [
    //                             'sequence' => '1',
    //                             'templateId' => $params['templateId']
    //                         ]
    //                     ],
    //                     'inlineTemplates' => [
    //                         [
    //                             'sequence' => '1',
    //                             'recipients' => [
    //                                 'signers' => [
    //                                     [
    //                                         'email' => $params['email'],
    //                                         'name' => $params['name'],
    //                                         'roleName' => $params['roleName'] ?? 'Client',
    //                                         'recipientId' => '1',
    //                                         'clientUserId' => $params['clientUserId'] ?? '1234'
    //                                     ]
    //                                 ]
    //                             ]
    //                         ]
    //                     ]
    //                 ]
    //             ]
    //         ];
    //     }
    //     // print_r($body);
    //     // exit;
    //     $response = $this->sendCurlRequest($url, $accessToken, $body);
    //     return json_decode($response, true);
    // }


    public function createRecipientView($accessToken, $params)
    {
        $accountId = $this->config['account_id'];
        $url = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/envelopes/{$params['envelopeId']}/views/recipient";

        $body = [
            'returnUrl' => $params['returnUrl'],
            'authenticationMethod' => 'none',
            'email' => $params['email'] ?? 'client@example.com',
            'userName' => $params['name'] ?? 'Default Client',
            'clientUserId' => '1234',
            // 🔥 FORCE DESKTOP MODE
            "messageOptions" => [
                "brandingFormat" => "classic"
            ]

        ];

        $response = $this->sendCurlRequest($url, $accessToken, $body);
        return json_decode($response, true);
    }

    public function sendCurlRequest($url, $accessToken, $body = null, $method = 'POST', $raw = false)
    {
        $ch = curl_init($url);

        $headers = [
            "Authorization: Bearer {$accessToken}",
            "Content-Type: application/json"
        ];

        $method = strtoupper($method);

        if ($method === 'POST') {
            curl_setopt($ch, CURLOPT_POST, true);
            if (!empty($body)) {
                curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
            }
        } elseif ($method === 'PUT') {
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
            if (!empty($body)) {
                curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
            }
        } elseif ($method === 'GET') {
            curl_setopt($ch, CURLOPT_HTTPGET, true);
        }

        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER     => $headers
        ]);

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

        if ($httpCode < 200 || $httpCode >= 300) {
            throw new RuntimeException("DocuSign API Error [{$httpCode}]: {$response}");
        }

        return $raw ? $response : $response;
    }

    // protected function sendCurlRequest($url, $accessToken, $body = null, $method = 'POST')
    // {
    //     $ch = curl_init($url);

    //     $headers = [
    //         "Authorization: Bearer {$accessToken}",
    //         "Content-Type: application/json"
    //     ];

    //     if (strtoupper($method) === 'POST') {
    //         curl_setopt($ch, CURLOPT_POST, true);
    //         if (!empty($body)) {
    //             curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
    //         }
    //     } else { // default to GET
    //         curl_setopt($ch, CURLOPT_HTTPGET, true);
    //     }

    //     curl_setopt_array($ch, [
    //         CURLOPT_RETURNTRANSFER => true,
    //         CURLOPT_HTTPHEADER     => $headers
    //     ]);

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

    //     if ($httpCode < 200 || $httpCode >= 300) {
    //         throw new RuntimeException("DocuSign API Error [{$httpCode}]: {$response}");
    //     }

    //     return $response;
    // }


    //method to update LawFirm

    public function notifyDocumentStatus($docId, $isSuccess, $errorMessage = null, $template_id = null, $mycase_doc_id = null)
    {
        $payload = [
            'collection' => 'LawFirm',
            'docId' => $docId,
            'data' => [
                'myCaseLawId' => $mycase_doc_id ?? null,
                'templateId' => $template_id
            ]
        ];
        if (!$isSuccess && $errorMessage) {
            $payload['data']['errorMessage'] = $errorMessage;
        }

        // $ch = curl_init('https://us-central1-freeme-6e63a.cloudfunctions.net/widgetsforusa/documents/update');
        $ch = curl_init('https://us-central1-duepro-2cf60.cloudfunctions.net/widgetsforusa/documents/update');
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
            CURLOPT_POSTFIELDS => json_encode($payload)
        ]);
        curl_exec($ch);
        curl_close($ch);
    }

    //method to update QuoteAler
    public function notifyEnvelopeStatus($docId, $isSuccess, $errorMessage = null, $template_id = '', $attorney_type = '')
    {
        // Case 1: When attorney_type is provided
        if (!empty($attorney_type)) {

            if ($attorney_type == "Immigration") {
                // Immigration → save imigrationtemplated_id
                $payload = [
                    'collection' => 'QuoteAlert',
                    'docId'      => $docId,
                    'data'       => [
                        'isEnvelopSign'        => $isSuccess,
                        'imigrationtemplated_id' => $template_id
                    ]
                ];
            } else {
                // Any other type → save template_id
                $payload = [
                    'collection' => 'QuoteAlert',
                    'docId'      => $docId,
                    'data'       => [
                        'isEnvelopSign' => $isSuccess,
                        'template_id'   => $template_id
                    ]
                ];
            }
        } else {
            // Case 2: No attorney_type → save template_id
            $payload = [
                'collection' => 'QuoteAlert',
                'docId'      => $docId,
                'data'       => [
                    'isEnvelopSign' => $isSuccess,
                    'template_id'   => $template_id
                ]
            ];
        }

        // Add error message if needed
        if (!$isSuccess && $errorMessage) {
            $payload['data']['errorMessage'] = $errorMessage;
        }

        // CURL request
        // $ch = curl_init('https://us-central1-freeme-6e63a.cloudfunctions.net/widgetsforusa/documents/update');
        $ch = curl_init('https://us-central1-duepro-2cf60.cloudfunctions.net/widgetsforusa/documents/update');

        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
            CURLOPT_POSTFIELDS => json_encode($payload)
        ]);

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

        return $response;
    }


    public function getEnvelopeStatus($accessToken, $envelopeId)
    {
        $accountId = $this->config['account_id'];
        $url = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/envelopes/{$envelopeId}";

        $response = $this->sendCurlRequest($url, $accessToken, null, 'GET');
        return json_decode($response, true);
    }

    public function getFreshSenderView($accessToken, $templateId, $returnUrl)
    {
        try {
            $accountId = $this->config['account_id'];

            $url = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates/{$templateId}/views/edit";

            $body = [
                'returnUrl' => $returnUrl
            ];

            $response = $this->sendCurlRequest($url, $accessToken, $body);
            $result   = json_decode($response, true);

            if (!empty($result['url'])) {
                return $result['url'];
            }

            return null; // Return proper null if URL missing
        } catch (Exception $e) {
            return null; // Return null on error
        }
    }


    public function getSignedDocumentForEmail($accessToken, $envelopeId)
    {
        $accountId = $this->config['account_id'];
        $url = $this->config['base_path'] . "/v2.1/accounts/{$accountId}/envelopes/{$envelopeId}/documents/combined";

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => [
                "Authorization: Bearer {$accessToken}",
                "Accept: application/pdf"
            ]
        ]);

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

        if ($httpCode === 200 && $pdfData) {
            return $pdfData; // Return raw PDF binary
        }

        throw new Exception("Failed to download signed document. HTTP {$httpCode}");
    }

    public function sendCompletionEmail($recipients, $subject, $message, $pdfData)
    {
        $CI = &get_instance();
        $CI->load->library('email');

        $CI->email->from('no-reply@example.com', 'DocuSign System');
        $CI->email->to($recipients);
        $CI->email->subject($subject);
        $CI->email->message($message);

        // Attach PDF from memory
        $CI->email->attach($pdfData, 'attachment', 'signed_document.pdf', 'application/pdf');

        return $CI->email->send()
            ? ['success' => true, 'sent_to' => $recipients]
            : ['success' => false, 'error' => $CI->email->print_debugger()];
    }

    public function handleEnvelopeCompletion($docId, $envelopeId, $userEmail, $attorneyEmail)
    {
        $accessToken = $this->createJWTToken();
        $status = $this->getEnvelopeStatus($accessToken, $envelopeId);

        if (!empty($status['status']) && strtolower($status['status']) === 'completed') {
            $pdfData = $this->getSignedDocument($accessToken, $envelopeId);
            $recipients = array_filter([$userEmail, $attorneyEmail]);

            $this->sendCompletionEmail(
                $recipients,
                'Signed Document Completed',
                'Hello, please find the signed document attached.',
                $pdfData
            );

            $this->notifyEnvelopeStatus($docId, true);

            return ['success' => true, 'status' => 'completed', 'message' => 'Envelope completed and email sent.'];
        }

        $this->notifyEnvelopeStatus($docId, false, $status['status'] ?? 'Unknown');
        return ['success' => false, 'status' => $status['status'] ?? 'unknown', 'message' => 'Envelope not completed yet.'];
    }

    /**
     * Fetches a template's document as Base64
     *
     * @param string $accessToken
     * @param string $templateId
     * @param int    $documentId Optional: default 1
     * @return string Base64 encoded PDF
     * @throws RuntimeException
     */
    public function getTemplateDocumentBase64(string $templateId, int $documentId = 1): string
    {
        $accountId = $this->config['account_id'];
        $url = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates/{$templateId}/documents/{$documentId}";

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => [
                "Authorization: Bearer {$this->createJWTToken()}",
                "Accept: application/pdf"
            ]
        ]);

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

        if ($httpCode !== 200 || !$pdfData) {
            throw new RuntimeException("Failed to fetch template document. HTTP Code: {$httpCode}");
        }

        return base64_encode($pdfData);
    }

    public function downloadTemplatePdf($templateId)
    {
        $accessToken = $this->createJWTToken();
        $accountId   = $this->config['account_id'];

        // Always document "1"
        $url = $this->config['base_path'] . "/v2.1/accounts/{$accountId}/templates/{$templateId}/documents/1";

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => [
                "Authorization: Bearer {$accessToken}",
                "Accept: application/pdf"
            ]
        ]);

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

        if ($httpCode == 200 && $pdf) {
            return $pdf; // Raw PDF
        }

        return false;
    }
}
