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

use GuzzleHttp\Client;

class DocusignController extends CI_Controller
{
    protected $docusignService;
    protected $docusignConfig;

    public function __construct()
    {
        parent::__construct();
        header("Access-Control-Allow-Origin: *");
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
        header("Access-Control-Allow-Headers: Authorization, Content-Type");

        $this->load->config('docusign');
        $this->load->library('DocuSignMailer');
        $this->docusignMailer = $this->docusignmailer;
        $this->load->library('AgreementPdfGenerator');
        $this->pdfGenerator = $this->agreementpdfgenerator;




        $this->docusignConfig = [
            'integration_key'       => $this->config->item('integration_key'),
            'user_id'               => $this->config->item('user_id'),
            'account_id'            => $this->config->item('account_id'),
            'rsa_private_key_path'  => $this->config->item('rsa_private_key_path'),
            'expires_in'            => $this->config->item('expires_in'),
            'base_path'             => $this->config->item('base_path'),
            'auth_server'           => $this->config->item('auth_server'),
            'scope'                 => $this->config->item('scope'),
        ];

        // Load service
        require_once APPPATH . 'Services/DocusignService.php';
        $this->docusignService = new DocusignService();
    }

    protected function getAccessToken()
    {
        $authHeader = $this->input->get_request_header('Authorization', TRUE);
        if (!$authHeader || stripos($authHeader, 'Bearer ') !== 0) {
            show_error('Missing or invalid Authorization header', 401);
        }
        return trim(substr($authHeader, 7));
    }
    public function token()
    {
        try {
            $token = $this->docusignService->createJWTToken();
            echo json_encode(['success' => 1, 'message' => 'Token created', 'access_token' => $token]);
        } catch (Exception $e) {
            echo json_encode(['success' => 0, 'message' => 'Error: ' . $e->getMessage(), 'access_token' => null]);
        }
    }
    /*
    // function used for APIS
    //
    */
    public function createTemplate()
    {
        try {
            $accessToken = $this->getAccessToken();

            $returnUrl = $this->input->post('returnUrl');
            $templateId = $this->input->post('template_id') ?? null;


            // 🧩 CASE 1: If template_id provided → open for editing
            if (!empty($templateId)) {
                $result = $this->docusignService->cloneTemplateWithFields($accessToken, $templateId, $returnUrl);

                echo json_encode([
                    'success' => 1,
                    'message' => 'Template cloned and opened for editing',
                    'data'    => $result
                ]);
                return;
            }



            $documentBase64 = trim($this->input->post('document'));

            // Check if Base64 is provided
            if (empty($documentBase64)) {
                echo json_encode([
                    'success' => 0,
                    'message' => 'Document upload failed',
                    'data'    => null
                ]);
                return;
            }

            // Decode Base64 to binary for MIME detection
            $documentBinary = base64_decode($documentBase64, true);
            if ($documentBinary === false) {
                echo json_encode([
                    'success' => 0,
                    'message' => 'Invalid Base64 string',
                    'data'    => null
                ]);
                return;
            }

            // Detect MIME type
            $finfo = new finfo(FILEINFO_MIME_TYPE);
            $mimeType = $finfo->buffer($documentBinary);

            $extensions = [
                'application/pdf'  => 'pdf',
                'application/msword' => 'doc',
                'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',
                'application/zip'  => 'zip',
                'image/png'        => 'png',
                'image/jpeg'       => 'jpg',
            ];

            $extension = $extensions[$mimeType] ?? 'bin';
            $fileName  = 'document_' . time() . '.' . $extension;

            $docId     = $this->input->post('attorneyId');

            // Send document to Docusign
            $result = $this->docusignService->createTemplateAndReturnSenderView($accessToken, [
                'documentBase64' => $documentBase64,
                'fileName'       => $fileName,
                'returnUrl'      => $returnUrl
            ]);

            $this->docusignService->notifyDocumentStatus($docId, true);

            echo json_encode([
                'success' => 1,
                'message' => 'Template created',
                'data'    => $result
            ]);
        } catch (Exception $e) {
            $this->docusignService->notifyDocumentStatus(null, false, $e->getMessage());
            echo json_encode([
                'success' => 0,
                'message' => 'Error: ' . $e->getMessage(),
                'data'    => null
            ]);
        }
    }

    public function createEnvelopeAndRecipientView()
    {
        try {
            $accessToken    = $this->getAccessToken();
            $templateId     = $this->input->post('templateId');
            $returnUrl      = $this->input->post('returnUrl');
            $name           = $this->input->post('name') ?? '';
            $email          = $this->input->post('email') ?? '';
            $doc_id         = $this->input->post('doc_id') ?? '';
            $attorney_email = $this->input->post('attorney_email') ?? "";

            // 🔹 1️⃣ Create envelope directly from the uploaded DocuSign template
            $envelope = $this->docusignService->createEnvelopeFromTemplate($accessToken, [
                'templateId'   => $templateId,
                'name'         => $name,
                'email'        => $email,
                'roleName'     => 'Client',
                'clientUserId' => '1234'
            ]);

            $envelopeId = $envelope['envelopeId'] ?? null;
            if (!$envelopeId) {
                echo json_encode([
                    'success' => 0,
                    'message' => 'Envelope creation failed',
                    'data'    => $envelope
                ]);
                return;
            }

            // 🔹 2️⃣ Prepare return URL with extra parameters
            $returnUrlWithParams = $returnUrl
                . '?doc_id=' . urlencode($doc_id)
                . '&envelopeId=' . urlencode($envelopeId)
                . '&user_email=' . urlencode($email)
                . '&attorney_email=' . urlencode($attorney_email);

            // 🔹 3️⃣ Create embedded signing view for recipient
            $recipientView = $this->docusignService->createRecipientView($accessToken, [
                'envelopeId'   => $envelopeId,
                'returnUrl'    => $returnUrlWithParams,
                'name'         => $name,
                'email'        => $email,
                'clientUserId' => '1234',
            ]);

            // 🔹 4️⃣ Return success response
            echo json_encode([
                'success' => 1,
                'message' => 'Envelope and recipient view created',
                'data'    => [
                    'envelope'      => $envelope,
                    'recipientView' => $recipientView
                ]
            ]);
        } catch (Exception $e) {
            echo json_encode([
                'success' => 0,
                'message' => 'Error: ' . $e->getMessage()
            ]);
        }
    }


    //method when we are emergng  documents
    // public function createEnvelopeAndRecipientView()
    // {
    //     try {
    //         $accessToken    = $this->getAccessToken();
    //         $templateId     = $this->input->post('templateId');
    //         $returnUrl      = $this->input->post('returnUrl');
    //         $name           = $this->input->post('name') ?? 'Default Client';
    //         $email          = $this->input->post('email') ?? 'client@example.com';
    //         $doc_id         = $this->input->post('doc_id') ?? '';
    //         $attorney_email = $this->input->post('attorney_email') ?? "softwar.se152@gmail.com";
    //         $otherData      = json_decode($this->input->post('otherdata'), true);

    //         // 1 Generate PDF as string
    //         // $pdfString = $this->pdfGenerator->generate($otherData, "Client Agreement", true);
    //         //  $agreementBase64 = base64_encode($pdfString);

    //         // 2 Get template PDF (base64) from DocuSign
    //         $templateBase64 = $this->docusignService->getTemplateDocumentBase64($templateId);

    //         // 3 Merge both PDFs
    //         // $finalBase64 = $templateBase64
    //         //     ? $this->mergeBase64PDFsAPI($templateBase64, $agreementBase64)
    //         //     : $agreementBase64;

    //         // 4 Create envelope with merged PDF
    //         // $envelope = $this->docusignService->createEnvelopeFromTemplate($accessToken, [
    //         //     'name'           => $name,
    //         //     'email'          => $email,
    //         //     'roleName'       => 'Client',
    //         //     'documentBase64' => $finalBase64,
    //         //     'fileName'       => 'FinalAgreement.pdf'
    //         // ]);
    //         // pass templateId and clientUserId (keep clientUserId consistent everywhere)
    //         $envelope = $this->docusignService->createEnvelopeFromTemplate($accessToken, [
    //             'templateId'      => $templateId,
    //             'name'            => $name,
    //             'email'           => $email,
    //             'roleName'        => 'Client',
    //             'documentBase64'  => $templateBase64,
    //             'fileName'        => 'FinalAgreement.pdf',
    //             'clientUserId'    => '1234'
    //         ]);


    //         $envelopeId = $envelope['envelopeId'] ?? null;
    //         if (!$envelopeId) {
    //             echo json_encode(['success' => 0, 'message' => 'Envelope creation failed', 'data' => $envelope]);
    //             return;
    //         }

    //         // 5 Recipient signing view
    //         $returnUrlWithParams = $returnUrl
    //             . '?doc_id=' . urlencode($doc_id)
    //             . '&envelopeId=' . urlencode($envelopeId)
    //             . '&user_email=' . urlencode($email)
    //             . '&attorney_email=' . urlencode($attorney_email);

    //         $recipientView = $this->docusignService->createRecipientView($accessToken, [
    //             'envelopeId' => $envelopeId,
    //             'returnUrl'  => $returnUrlWithParams,
    //             'name'       => $name,
    //             'email'      => $email,
    //             'clientUserId' => '1234'

    //         ]);

    //         echo json_encode([
    //             'success' => 1,
    //             'message' => 'Envelope and recipient view created',
    //             'data'    => ['envelope' => $envelope, 'recipientView' => $recipientView]
    //         ]);
    //     } catch (Exception $e) {
    //         echo json_encode(['success' => 0, 'message' => 'Error: ' . $e->getMessage()]);
    //     }
    // }

    // public function signingCallback()
    // {
    //     $docId       = $this->input->get('doc_id');
    //     $envelopeId  = $this->input->get('envelopeId');
    //     $userEmail   = $this->input->get('user_email');
    //     $attorneyEmail = $this->input->get('attorney_email');


    //     if (!$docId || !$envelopeId) {
    //         $this->load->view('docusign/error', [
    //             'message' => 'Missing docId or envelopeId',
    //             'status'  => 'Unknown'
    //         ]);
    //         return;
    //     }

    //     try {
    //         $accessToken = $this->docusignService->createJWTToken();
    //         $status      = $this->docusignService->getEnvelopeStatus($accessToken, $envelopeId);


    //         if (!empty($status['status']) && strtolower($status['status']) === 'completed') {
    //             // Envelope signed
    //             $this->docusignService->notifyEnvelopeStatus($docId, true, null, '');

    //             // Fetch signed PDF and send email (in-memory)
    //             try {
    //                 $pdfData    = $this->docusignService->getSignedDocumentForEmail($accessToken, $envelopeId);


    //                 $userEmailResult     = $this->docusignMailer->sendUserEmail($userEmail, $pdfData);
    //                 // print_r($userEmailResult);
    //                 // die;

    //                 $attorneyEmailResult = $this->docusignMailer->sendAttorneyEmail($attorneyEmail, $pdfData);
    //                 // echo "<pre>";
    //                 // print_r($attorneyEmailResult);
    //                 // echo "</pre>";
    //                 // die;
    //             } catch (Exception $e) {
    //                 log_message('error', 'Email sending failed: ' . $e->getMessage());
    //             }

    //             // Load success view
    //             $this->load->view('docusign/success', [
    //                 'message' => 'Thank you, your document is signed!',
    //                 'status'  => $status['status']
    //             ]);
    //         } else {
    //             // Envelope not signed yet
    //             $this->docusignService->notifyEnvelopeStatus($docId, false, $status['status'] ?? 'Unknown');

    //             $this->load->view('docusign/error', [
    //                 'message' => 'Document not signed yet.',
    //                 'status'  => $status['status'] ?? 'Unknown'
    //             ]);
    //         }
    //     } catch (Exception $e) {
    //         // General failure
    //         log_message('error', 'Signing callback failed: ' . $e->getMessage());
    //         $this->load->view('docusign/error', [
    //             'message' => 'An error occurred while processing the envelope.',
    //             'status'  => 'Error'
    //         ]);
    //     }
    // }

    public function signingCallback()
    {
        $docId       = $this->input->get('doc_id');
        $envelopeId  = $this->input->get('envelopeId');
        $userEmail   = $this->input->get('user_email');
        $attorneyEmail = $this->input->get('attorney_email');
        $webUrl        = $this->input->get('webUrl') ?? '';



        if (!$docId || !$envelopeId) {
            $this->load->view('docusign/error', [
                'message' => 'Missing docId or envelopeId',
                'status'  => 'Unknown'
            ]);
            return;
        }

        try {
            $accessToken = $this->docusignService->createJWTToken();
            $status      = $this->docusignService->getEnvelopeStatus($accessToken, $envelopeId);


            if (!empty($status['status']) && strtolower($status['status']) === 'completed') {
                // Envelope signed
                $this->docusignService->notifyEnvelopeStatus($docId, true);

                // Fetch signed PDF and send email (in-memory)
                try {
                    $pdfData    = $this->docusignService->getSignedDocumentForEmail($accessToken, $envelopeId);


                    $userEmailResult     = $this->docusignMailer->sendUserEmail($userEmail, $pdfData);
                    // print_r($userEmailResult);
                    // die;

                    $attorneyEmailResult = $this->docusignMailer->sendAttorneyEmail($attorneyEmail, $pdfData);
                    // echo "<pre>";
                    // print_r($attorneyEmailResult);
                    // echo "</pre>";
                    // die;
                } catch (Exception $e) {
                    log_message('error', 'Email sending failed: ' . $e->getMessage());
                }

                // 🔹 If webUrl provided → redirect
                if (!empty($webUrl)) {
                    redirect($webUrl);
                    return;
                }

                // Load success view
                $this->load->view('docusign/success', [
                    'message' => 'Thank you, your document is signed!',
                    'status'  => $status['status']
                ]);
            } else {
                // Envelope not signed yet
                $this->docusignService->notifyEnvelopeStatus($docId, false, $status['status'] ?? 'Unknown');

                $this->load->view('docusign/error', [
                    'message' => 'Document not signed yet.',
                    'status'  => $status['status'] ?? 'Unknown'
                ]);
            }
        } catch (Exception $e) {
            // General failure
            log_message('error', 'Signing callback failed: ' . $e->getMessage());
            $this->load->view('docusign/error', [
                'message' => 'An error occurred while processing the envelope.',
                'status'  => 'Error'
            ]);
        }
    }


    public function getSignedDocument()
    {
        // Try JSON first
        $input = json_decode(file_get_contents('php://input'), true);
        $envelopeId = $input['envelopeId'] ?? null;

        // Fallback to POST
        if (empty($envelopeId)) {
            $envelopeId = $this->input->post('envelopeId') ?? null;
        }

        // Fallback to GET
        if (empty($envelopeId)) {
            $envelopeId = $this->input->get('envelopeId') ?? null;
        }
        // echo "<pre>";
        // print_r($_POST);
        // echo "</pre>";
        // die;

        // $envelopeId = $this->input->post('envelopeId');
        if (empty($envelopeId)) {
            echo json_encode(['success' => 0, 'message' => 'envelopeId is required']);
            return;
        }
        try {


            $accessToken = $this->getAccessToken();
            $accountId   = $this->docusignConfig['account_id'];
            $url = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/envelopes/{$envelopeId}/documents/1";

            $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) {
                header('Content-Type: application/pdf');
                header('Content-Disposition: attachment; filename="signed_document.pdf"');
                echo $pdfData;
            } else {
                echo json_encode(['success' => 0, 'message' => "Failed to fetch document. HTTP {$httpCode}"]);
            }
        } catch (Exception $e) {
            echo json_encode(['success' => 0, 'message' => 'Error: ' . $e->getMessage()]);
        }
    }

    public function getFreshSenderViewEndpoint()
    {
        try {
            $accessToken = $this->getAccessToken();
            $templateId  = trim($this->input->post_get('templateId')); // works for POST or GET
            $returnUrl   = trim($this->input->post_get('returnUrl'));

            if (empty($templateId) || empty($returnUrl)) {
                $response = [
                    'success' => 0,
                    'message' => 'templateId and returnUrl are required',
                    'senderViewUrl' => null
                ];
            } else {
                // Get fresh sender view URL
                $senderViewUrl = $this->docusignService->getFreshSenderView($accessToken, $templateId, $returnUrl);

                if (empty($senderViewUrl) || $senderViewUrl === 'error') {
                    $response = [
                        'success' => 0,
                        'message' => 'Failed to generate sender view URL',
                        'senderViewUrl' => null
                    ];
                } else {
                    $response = [
                        'success' => 1,
                        'message' => 'Fresh sender view URL generated',
                        'senderViewUrl' => $senderViewUrl
                    ];
                }
            }
        } catch (Exception $e) {
            $response = [
                'success' => 0,
                'message' => 'Error: ' . $e->getMessage(),
                'senderViewUrl' => null
            ];
        }

        // Always output JSON in CI3
        $this->output
            ->set_content_type('application/json')
            ->set_output(json_encode($response));
    }
    /**
     * Merge two Base64 PDFs using PDF.co
     */
    private function mergeBase64PDFsAPI($base64Doc1, $base64Doc2)
    {
        $client = new \GuzzleHttp\Client();
        $apiKey = 'hammadkhanhk152@gmail.com_TSsmuPD4haZPEJZUjGBx1my4ho88RsdwMghM8C1U6OfIXaDtcRuKaRmd4xyfFfgj';

        // 1️⃣ Upload both Base64 PDFs to get URLs
        $url1 = $this->uploadBase64PDF($base64Doc1, $client, $apiKey);
        $url2 = $this->uploadBase64PDF($base64Doc2, $client, $apiKey);

        // 2️⃣ Merge PDFs using URLs
        $response = $client->post('https://api.pdf.co/v1/pdf/merge', [
            'headers' => [
                'x-api-key' => $apiKey,
                'Content-Type' => 'application/json'
            ],
            'json' => [
                'url' => "$url1,$url2",
                'name' => 'merged_document.pdf',
                'async' => false
            ]
        ]);

        $result = json_decode($response->getBody(), true);

        if (!isset($result['url'])) {
            throw new \Exception('PDF merge failed: ' . ($result['message'] ?? 'Unknown error'));
        }

        // Download merged PDF and return Base64
        $mergedPdfBinary = file_get_contents($result['url']);
        return base64_encode($mergedPdfBinary);
    }

    /**
     * Upload a Base64 PDF to PDF.co and get the file URL
     */
    private function uploadBase64PDF($base64Pdf, $client, $apiKey)
    {
        $response = $client->post('https://api.pdf.co/v1/file/upload/base64', [
            'headers' => [
                'x-api-key' => $apiKey,
                'Content-Type' => 'application/json'
            ],
            'json' => [
                'file' => $base64Pdf
            ]
        ]);

        $result = json_decode($response->getBody(), true);

        if (!isset($result['url'])) {
            throw new \Exception('Base64 PDF upload failed: ' . ($result['message'] ?? 'Unknown error'));
        }

        return $result['url'];
    }

    public function testEmail()
    {
        $this->load->library('email');

        $this->email->from('info@duepro.com', 'DuePro System');
        $this->email->to('softwar.se152@gmail.com');
        $this->email->subject('Test GoDaddy SMTP');
        $this->email->message('This is a test email from CodeIgniter using GoDaddy SMTP.');

        if ($this->email->send()) {
            echo 'Email sent successfully!';
        } else {
            echo $this->email->print_debugger();
        }
    }
    public function downloadTemplatePdf()
    {
        $templateId = $this->input->get('template_id');

        if (!$templateId) {
            echo json_encode([
                'success' => 0,
                'message' => 'template_id is required'
            ]);
            return;
        }

        $pdf = $this->docusignService->downloadTemplatePdf($templateId);

        if (!$pdf) {
            echo json_encode([
                'success' => 0,
                'message' => 'Failed to download template PDF'
            ]);
            return;
        }

        // 🔹 Return Base64 inside JSON
        echo json_encode([
            'success' => 1,
            'message' => 'Template PDF downloaded successfully',
            'pdfBase64'  => base64_encode($pdf)

        ]);
    }

    /*
    ->method for adding fields to template via canvas
    ->method for web
    */
    public function getTemplateDocument()
    {
        try {
            // $accessToken = $this->getAccessToken();
            $accessToken = $this->docusignService->createJWTToken();
            $input = json_decode(file_get_contents('php://input'), true) ?: $_POST;
            $templateId = $input['template_id'] ?? null;

            if (!$templateId) {
                echo json_encode(['success' => 0, 'message' => 'template_id required']);
                return;
            }

            $accountId = $this->docusignConfig['account_id'];
            $url = "https://na4.docusign.net/restapi/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"
                ]
            ]);

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

            if ($httpCode !== 200 || !$pdfData) {
                echo json_encode(['success' => 0, 'message' => 'Failed to fetch template document']);
                return;
            }

            echo json_encode([
                'success' => 1,
                'fileBase64' => base64_encode($pdfData)
            ]);
        } catch (Exception $e) {
            echo json_encode(['success' => 0, 'message' => 'Error: ' . $e->getMessage()]);
        }
    }

    public function duplicateTemplate()
    {
        $input = json_decode(file_get_contents('php://input'), true) ?: $_POST ?: $_GET;

        $templateId = $input['template_id'] ?? null;
        $doc_id     = $input['doc_id'] ?? null;
        $attorney_type = $input['type'] ?? null;


        $accessToken = $this->docusignService->createJWTToken();
        if (!$templateId) {
            echo json_encode([
                "success" => false,
                "message" => "template_id is required"
            ]);
            return;
        }

        // Duplicate template
        $result = $this->docusignService->cloneTemplateWithFields($accessToken, $templateId);

        if (!empty($result['success']) && $result['success'] == 1) {
            if ($doc_id && !empty($result['data']['template_id'])) {
                $cfResponse = $this->docusignService->notifyEnvelopeStatus(
                    $doc_id,
                    false,
                    null,
                    $result['data']['template_id'],
                    $attorney_type
                );
            }
        }


        echo json_encode($result);
    }
    public function freshDoc()
    {
        $this->load->helper('url');

        $this->load->view('template_builder/fresh-template');
    }
    public function templateView()
    {
        $this->load->helper('url');
        // $this->load->view('welcome_message');
        $data['template_id'] = $this->input->post('template_id')
            ?? $this->input->get('template_id')
            ?? '';
        $data['doc_id'] = $this->input->post('doc_id')
            ?? $this->input->get('doc_id')
            ?? '';
        $data['type'] = $this->input->post('type')
            ?? $this->input->get('type')
            ?? '';

        $this->load->view(
            'template_builder/index',
            $data
        );
    }

    public function getTemplateWithFields()
    {
        try {
            $input = json_decode(file_get_contents('php://input'), true) ?: $_POST;
            $templateId = $input['template_id'] ?? null;

            if (!$templateId) {
                echo json_encode(['success' => 0, 'message' => 'template_id required']);
                return;
            }

            $accessToken = $this->docusignService->createJWTToken();
            $accountId = $this->docusignConfig['account_id'];

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

            if (empty($templateResp['templateId'])) {
                echo json_encode(['success' => 0, 'message' => 'Template not found']);
                return;
            }

            // Fetch first document
            $docId = $templateResp['documents'][0]['documentId'] ?? '1';
            $docUrl = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates/{$templateId}/documents/{$docId}";
            $pdfContent = $this->docusignService->sendCurlRequest($docUrl, $accessToken, null, 'GET', true);

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

                    foreach ($tabsResp as $tabType => $tabList) {
                        if (!is_array($tabList)) continue;
                        foreach ($tabList as $tab) {
                            $fields[] = [
                                'label' => $tab['tabLabel'] ?? 'field',  // <-- send label
                                // 'tabLabel' => $tab['tabLabel'] ?? 'field',
                                'type' => $tabType,
                                'pageNumber' => $tab['pageNumber'] ?? 1,
                                'xPosition' => (float)($tab['xPosition'] ?? 0),
                                'yPosition' => (float)($tab['yPosition'] ?? 0),
                                'width' => (float)($tab['width'] ?? 120),
                                'height' => (float)($tab['height'] ?? 30)
                            ];
                        }
                    }
                }
            }


            echo json_encode([
                'success' => 1,
                'fileBase64' => base64_encode($pdfContent),
                'fields' => $fields
            ]);
        } catch (Exception $e) {
            echo json_encode(['success' => 0, 'message' => 'Error: ' . $e->getMessage()]);
        }
    }



    public function addFieldsToTemplate()
    {
        try {
            $accessToken = $this->docusignService->createJWTToken();
            $input = json_decode(file_get_contents('php://input'), true) ?: $_POST;

            $fileName = $input['fileName'] ?? null;
            $documentBase64 = $input['documentBase64'] ?? null;
            $fields = $input['fields'] ?? [];
            $doc_id = $input['doc_id'] ?? null;
            $attorney_type = $input['attorney_type'] ?? null;

            if (!$fileName || !$documentBase64) {
                echo json_encode(['success' => 0, 'message' => 'fileName & documentBase64 required']);
                return;
            }

            $tabs = [];

            foreach ($fields as $i => $f) {
                $x = (string) round($f['x']);
                $y = (string) round($f['y']);
                $width = (string) round($f['width']);
                $height = (string) round($f['height']);
                $label = $f['label'] ?? "field_{$i}";

                $common = [
                    'documentId' => '1',
                    'pageNumber' => (string)($f['pageNumber'] ?? 1),
                    'xPosition' => $x,
                    'yPosition' => $y,
                    'width' => $width,
                    'height' => $height,
                ];

                switch (strtolower($f['type'])) {
                    case 'email':
                        // 🔥 MINIMAL EMAIL TAB - No custom properties
                        $emailTab = $common;
                        $emailTab['required'] = 'true';
                        $emailTab['locked'] = 'true';
                        // ⚠️ DO NOT SET: tabLabel, name, value, or source
                        $tabs['emailTabs'][] = $emailTab;
                        break;

                    case 'signature':
                    case 'signhere':
                        $common['tabLabel'] = $label;
                        $tabs['signHereTabs'][] = $common;
                        break;

                    case 'fullname':
                        // 🔥 MINIMAL FULLNAME TAB
                        $nameTab = $common;
                        $nameTab['required'] = 'true';
                        $nameTab['locked'] = 'true';
                        // ⚠️ DO NOT SET: tabLabel, name, value
                        $tabs['fullNameTabs'][] = $nameTab;
                        break;

                    case 'date':
                    case 'datesigned':
                        $dateTab = $common;
                        $dateTab['tabLabel'] = $label;
                        $dateTab['required'] = 'true';
                        $tabs['dateSignedTabs'][] = $dateTab;
                        break;

                    case 'checkbox':
                        $common['tabLabel'] = $label;
                        $tabs['checkboxTabs'][] = $common;
                        break;

                    default:
                        // Text tabs
                        $common['value'] = $f['value'] ?? '';
                        $common['required'] = $f['required'] ?? false;
                        $common['name'] = $label;
                        $common['tabLabel'] = $label;
                        $tabs['textTabs'][] = $common;
                        break;
                }
            }

            $accountId = $this->config->item('account_id');
            $templatesUrl = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates";

            $body = [
                'name' => 'Template - ' . date('YmdHis'),
                'emailSubject' => 'Please sign this document',
                'documents' => [[
                    'documentBase64' => $documentBase64,
                    'name' => $fileName,
                    'fileExtension' => 'pdf',
                    'documentId' => '1'
                ]],
                'recipients' => [
                    'signers' => [[
                        'roleName' => 'Client',
                        'recipientId' => '1',
                        'routingOrder' => '1',
                        'tabs' => $tabs
                    ]]
                ],
                'status' => 'created'
            ];

            $response = $this->docusignService->sendCurlRequest($templatesUrl, $accessToken, $body);
            $templateResp = json_decode($response, true);

            if (empty($templateResp['templateId'])) {
                throw new RuntimeException("Could not create template");
            }

            $template_id = $templateResp['templateId'];

            if ($template_id) {
                $isSuccess = false;
                $cfRes = $this->docusignService->notifyEnvelopeStatus(
                    $doc_id,
                    $isSuccess,
                    null,
                    $template_id,
                    $attorney_type
                );

                echo json_encode([
                    'success' => 1,
                    'message' => 'Template created & status updated!',
                    'templateId' => $template_id,
                    'fieldsCount' => count($fields),
                    'cloudFunctionResponse' => $cfRes
                ]);
                return;
            }
        } catch (Exception $e) {
            echo json_encode([
                'success' => 0,
                'message' => 'Error: ' . $e->getMessage()
            ]);
        }
    }
    public function updateTemplateFields()
    {
        try {
            $input = json_decode(file_get_contents('php://input'), true) ?: $_POST;
            $templateId = $input['template_id'] ?? null;
            $fileName = $input['filename'] ?? null;
            $pdfBase64 = $input['pdf_base64'] ?? null;
            $fields = $input['fields'] ?? [];
            $docId = $input['doc_id'] ?? null;
            $document_replaced = $input['document_replaced'] ?? false;

            $myCaseLawId = $input['myCaseLawId'] ?? null;
            $mycase_doc_id = null;

            if (!$templateId) {
                echo json_encode(['success' => 0, 'message' => 'template_id is required for updating']);
                return;
            }

            if (!$pdfBase64) {
                echo json_encode(['success' => 0, 'message' => 'pdf_base64 is required']);
                return;
            }



            if ($document_replaced === true && $myCaseLawId) {
                // STEP A: Delete old document from MyCase
                $this->deleteMyCaseDocument($myCaseLawId, $docId);

                // STEP B: Upload as new document
                $mycaseResult = $this->uploadToMyCase($fileName, $pdfBase64, $docId);
                $mycase_doc_id = $mycaseResult['mycase_doc_id'] ?? null;
            } else {
                // NOT replaced → keep existing doc
                $mycase_doc_id = $myCaseLawId ?? null;
            }



            $accessToken = $this->docusignService->createJWTToken();
            $accountId = $this->config->item('account_id');

            $tabs = [];
            foreach ($fields as $i => $f) {
                $pageNum = $f['page'] ?? 1;
                $type = strtolower($f['type'] ?? 'text');
                $label = $f['label'] ?? "field_{$i}";
                $value = $f['value'] ?? '';

                $common = [
                    'documentId' => '1',
                    'pageNumber' => (string) $pageNum,
                    'xPosition'  => (string) round(($f['x'] ?? 0) * 500),
                    'yPosition'  => (string) round(($f['y'] ?? 0) * 700),
                    'width'      => (string) round(($f['width'] ?? 0.1) * 500),
                    'height'     => (string) round(($f['height'] ?? 0.05) * 700),
                ];

                switch ($type) {
                    case 'email':
                        $emailTab = $common;
                        $emailTab['required'] = 'true';
                        $emailTab['locked'] = 'true';
                        $tabs['emailTabs'][] = $emailTab;
                        break;

                    case 'signature':
                    case 'signhere':
                        $common['tabLabel'] = $label;
                        $tabs['signHereTabs'][] = $common;
                        break;

                    case 'fullname':
                        $nameTab = $common;
                        $nameTab['required'] = 'true';
                        $nameTab['locked'] = 'true';
                        $tabs['fullNameTabs'][] = $nameTab;
                        break;

                    case 'date':
                    case 'datesigned':
                        $dateTab = $common;
                        $dateTab['tabLabel'] = $label;
                        $dateTab['required'] = 'true';
                        $tabs['dateSignedTabs'][] = $dateTab;
                        break;

                    case 'checkbox':
                        $common['tabLabel'] = $label;
                        $tabs['checkboxTabs'][] = $common;
                        break;

                    default:
                        // Text tabs
                        $common['value'] = $value;
                        $common['required'] = $f['required'] ?? false;
                        $common['name'] = $label;
                        $common['tabLabel'] = $label;
                        $tabs['textTabs'][] = $common;
                        break;
                }
            }

            // Step 1: Delete the old template
            $deleteUrl = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates/{$templateId}";
            try {
                $ch = curl_init($deleteUrl);
                curl_setopt_array($ch, [
                    CURLOPT_CUSTOMREQUEST => 'DELETE',
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_HTTPHEADER => [
                        "Authorization: Bearer {$accessToken}",
                        "Content-Type: application/json"
                    ]
                ]);
                curl_exec($ch);
                curl_close($ch);
            } catch (Exception $e) {
                log_message('error', "Failed to delete old template: " . $e->getMessage());
            }

            // Step 2: Create new template
            $templatesUrl = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates";

            $body = [
                'name' => 'Updated Template - ' . date('YmdHis'),
                'emailSubject' => 'Please sign this document',
                'documents' => [[
                    'documentBase64' => $pdfBase64,
                    'name' => $fileName ?? 'updated-document.pdf',
                    'fileExtension' => 'pdf',
                    'documentId' => '1'
                ]],
                'recipients' => [
                    'signers' => [[
                        'roleName' => 'Client',
                        'recipientId' => '1',
                        'routingOrder' => '1',
                        'tabs' => $tabs
                    ]]
                ],
                'status' => 'created'
            ];

            $response = $this->docusignService->sendCurlRequest($templatesUrl, $accessToken, $body);
            $respData = json_decode($response, true);

            if (!empty($respData['templateId'])) {
                $newTemplateId = $respData['templateId'];

                if ($docId) {
                    $this->docusignService->notifyDocumentStatus(
                        $docId,
                        false,
                        null,
                        $newTemplateId,
                        $mycase_doc_id
                    );
                }

                echo json_encode([
                    'success' => 1,
                    'message' => 'Template fields successfully updated',
                    'templateId' => $newTemplateId,
                    'oldTemplateId' => $templateId,
                    'fieldsCount' => count($fields)
                ]);
                return;
            }

            echo json_encode([
                'success' => 0,
                'message' => 'Failed to create updated template',
                'response' => $respData
            ]);
        } catch (Exception $e) {
            echo json_encode([
                'success' => 0,
                'message' => 'Error: ' . $e->getMessage()
            ]);
        }
    }
    public function uploadDocumentToTemplate()
    {
        try {
            $input = json_decode(file_get_contents('php://input'), true) ?: $_POST;

            $fileName   = $input['filename'] ?? null;
            $pdfBase64  = $input['pdf_base64'] ?? null;
            $fields     = $input['fields'] ?? [];
            $doc_id     = $input['doc_id'] ?? null;

            if (!$fileName || !$pdfBase64) {
                echo json_encode([
                    'success' => 0,
                    'message' => 'filename & pdf_base64 required'
                ]);
                return;
            }

            // Upload to MyCase
            $mycaseResult = $this->uploadToMyCase($fileName, $pdfBase64, $doc_id);
            $mycase_doc_id = $mycaseResult['mycase_doc_id'] ?? null;

            // Create DocuSign template
            $accessToken = $this->docusignService->createJWTToken();

            $tabs = [];
            foreach ($fields as $i => $f) {
                $pageNum = $f['page'] ?? 1;
                $type    = strtolower($f['type'] ?? 'text');
                $label   = $f['label'] ?? "field_{$i}";
                $value   = $f['value'] ?? '';

                $common = [
                    'documentId' => '1',
                    'pageNumber' => (string) $pageNum,
                    'xPosition'  => (string) round(($f['x'] ?? 0) * 500),
                    'yPosition'  => (string) round(($f['y'] ?? 0) * 700),
                    'width'      => (string) round(($f['width'] ?? 0.1) * 500),
                    'height'     => (string) round(($f['height'] ?? 0.05) * 700),
                ];

                switch ($type) {
                    case 'email':
                        $emailTab = $common;
                        $emailTab['required'] = 'true';
                        $emailTab['locked'] = 'true';
                        $tabs['emailTabs'][] = $emailTab;
                        break;

                    case 'signature':
                    case 'signhere':
                        $common['tabLabel'] = $label;
                        $tabs['signHereTabs'][] = $common;
                        break;

                    case 'fullname':
                        $nameTab = $common;
                        $nameTab['required'] = 'true';
                        $nameTab['locked'] = 'true';
                        $tabs['fullNameTabs'][] = $nameTab;
                        break;

                    case 'date':
                    case 'datesigned':
                        $dateTab = $common;
                        $dateTab['tabLabel'] = $label;
                        $dateTab['required'] = 'true';
                        $tabs['dateSignedTabs'][] = $dateTab;
                        break;

                    case 'checkbox':
                        $common['tabLabel'] = $label;
                        $tabs['checkboxTabs'][] = $common;
                        break;

                    default:
                        // Text tabs
                        $common['value'] = $value;
                        $common['required'] = $f['required'] ?? false;
                        $common['name'] = $label;
                        $common['tabLabel'] = $label;
                        $tabs['textTabs'][] = $common;
                        break;
                }
            }

            $accountId    = $this->config->item('account_id');
            $templatesUrl = "https://na4.docusign.net/restapi/v2.1/accounts/{$accountId}/templates";

            $body = [
                'name'        => 'Builder Template - ' . date('YmdHis'),
                'emailSubject' => 'Please sign this document',
                'documents'   => [[
                    'documentBase64' => $pdfBase64,
                    'name'           => $fileName,
                    'fileExtension'  => 'pdf',
                    'documentId'     => '1'
                ]],
                'recipients'  => [
                    'signers' => [[
                        'roleName'    => 'Client',
                        'recipientId' => '1',
                        'routingOrder' => '1',
                        'tabs'        => $tabs
                    ]]
                ],
                'status' => 'created'
            ];

            $response = $this->docusignService->sendCurlRequest($templatesUrl, $accessToken, $body);
            $respData = json_decode($response, true);

            if (!empty($respData['templateId'])) {
                if ($doc_id) {
                    $this->docusignService->notifyDocumentStatus(
                        $doc_id,
                        true,
                        null,
                        $respData['templateId'],
                        $mycase_doc_id
                    );
                }

                echo json_encode([
                    'success' => 1,
                    'message' => 'Template Successfully Saved',
                    'template_id' => $respData['templateId'],
                ]);
                return;
            }

            echo json_encode([
                'success' => 0,
                'message' => 'Failed to create template',
                'response' => $respData
            ]);
        } catch (Exception $e) {
            echo json_encode([
                'success' => 0,
                'message' => 'Error: ' . $e->getMessage()
            ]);
        }
    }



    // -------------------------
    // MyCase helper methods
    // -------------------------

    private function uploadToMyCase($fileName, $pdfBase64, $docId)
    {
        $token = $this->getMyCaseToken($docId);
        if (!$token) return ['success' => false, 'message' => 'Failed to get MyCase token'];

        $doc = $this->mycaseCreateDocument($token, $fileName);
        if (empty($doc['put_url'])) return ['success' => false, 'message' => 'MyCase document creation failed', 'response' => $doc];

        $putUrl = $doc['put_url'];
        $putHeaders = $doc['put_headers'];

        // S3 upload: use binary data
        $rawFileData = base64_decode($pdfBase64);
        $uploadCode = $this->mycaseUploadToS3($putUrl, $putHeaders, $rawFileData);

        return [
            'success' => ($uploadCode == 200 || $uploadCode == 204),
            'upload_code' => $uploadCode,
            'mycase_doc_id' => $doc['id'] ?? null
        ];
    }

    private function getMyCaseToken($docId)
    {
        if (!$docId) return null;
        $url = "https://buzzwaretechserver.site/mycase_apis/mycase/token?lawId=" . $docId;
        $data = json_decode(file_get_contents($url), true);
        return $data['access_token'] ?? null;
    }

    private function mycaseCreateDocument($token, $fileName)
    {
        $payload = [
            "path"        => "Templates/" . $fileName  . "_" . time(),
            "filename"    => $fileName,
            "description" => "Firm Templates"
        ];

        $ch = curl_init("https://external-integrations.mycase.com/v1/documents");
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "Authorization: Bearer $token",
            "Content-Type: application/json"
        ]);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch);
        return json_decode($result, true);
    }

    private function mycaseUploadToS3($putUrl, $putHeaders, $rawFileData)
    {
        $headers = [];
        foreach ($putHeaders as $key => $value) $headers[] = "$key: $value";
        $headers[] = "Content-Length: " . strlen($rawFileData);
        if (!isset($putHeaders['Content-Type'])) $headers[] = "Content-Type: application/octet-stream";

        $ch = curl_init($putUrl);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
        curl_setopt($ch, CURLOPT_POSTFIELDS, $rawFileData);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

        curl_exec($ch);
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        return $code;
    }
    private function deleteMyCaseDocument($myCaseLawId, $docId)
    {
        $token = $this->getMyCaseToken($docId);

        if (!$token) return false;

        $url = "https://external-integrations.mycase.com/v1/documents/{$myCaseLawId}";

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "Authorization: Bearer {$token}",
            "Content-Type: application/json"
        ]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);



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

        return ['success' => $code === 204, 'body' => $response, 'http_code' => $code];
    }
}
