<?php
// Exit if accessed directly.
if (!defined('ABSPATH')) {
    exit; // Prevent direct access to the file.
}

// Check if the class already exists to avoid redeclaration.
if (!class_exists('IAFWZDESK_PRODUCT')) {
    class IAFWZDESK_PRODUCT
    {
        private $refresh_token;
        private $access_token;
        private $data_center;
        private $account_id;
        private $org_id;
        public function __construct($account_details = [], $access_token = null)
        {
            $this->refresh_token = $account_details['refresh_token'] ?? null;
            $this->data_center = $account_details['data_center'] ?? null;
            $this->account_id = $account_details['account_id'] ?? null;
            $this->access_token = $access_token;
            $this->org_id = $account_details['org_id'] ?? null;
        }
        // Function to get access token using refresh token
        private function get_access_token()
        {
            $url = "https://accounts.zoho." . $this->data_center . "/oauth/v2/token";
            $body = [
                'refresh_token' => $this->refresh_token,
                'client_id' => "1000.R6NADONBVTIS0VZSZ0DE5MNO3DEV7T",
                'client_secret' => "52f6c37069fd0db03ed6025766e968214d35bffbe5",
                'grant_type' => 'refresh_token'
            ];

            $response = wp_remote_post($url, [
                'body' => $body,
                'headers' => [
                    'Content-Type' => 'application/x-www-form-urlencoded'
                ],
                'timeout' => 60
            ]);

            if (is_wp_error($response)) {
                return false;
            }

            $response_body = wp_remote_retrieve_body($response);
            $data = json_decode($response_body, true);
            if (isset($data['access_token'])) {
                // Corrected account_id reference and updating the access token
                IAFWZDESK_Util::updateAccessToken($this->account_id, $data['access_token']);
                $this->access_token = $data['access_token']; // Update the current access token
                return true;
            }

            return false;
        }
        // Function to get a valid Zoho Desk org ID by checking departments
        public static function get_desk_org_id($access_token, $data_center)
        {
            try {
                // Construct the API URL to get organizations
                $url = "https://desk.zoho." . sanitize_text_field($data_center) . "/api/v1/organizations";

                // Send API request
                $response = wp_remote_get($url, [
                    'headers' => [
                        'Authorization' => 'Zoho-oauthtoken ' . sanitize_text_field($access_token),
                        'Content-Type'  => 'application/json'
                    ],
                    'timeout' => 60
                ]);

                // Retrieve response status and body
                $status_code = wp_remote_retrieve_response_code($response);
                $body = json_decode(wp_remote_retrieve_body($response), true);
                // Loop through organizations and test with department API
                if ($status_code === 200 && isset($body['data']) && is_array($body['data'])) {
                    foreach ($body['data'] as $org) {
                        if (!empty($org['id'])) {
                            $org_id = sanitize_text_field($org['id']);

                            // Try calling departments API with this orgId
                            $dept_url = "https://desk.zoho." . sanitize_text_field($data_center) . "/api/v1/departments";
                            $dept_response = wp_remote_get($dept_url, [
                                'headers' => [
                                    'Authorization' => 'Zoho-oauthtoken ' . sanitize_text_field($access_token),
                                    'Content-Type'  => 'application/json',
                                    'orgId'         => $org_id
                                ],
                                'timeout' => 60
                            ]);

                            $dept_body = json_decode(wp_remote_retrieve_body($dept_response), true);
                            if (isset($dept_body['data']) && is_array($dept_body['data']) && !empty($dept_body['data'])) {
                                // Found a working orgId with department data
                                return $org_id;
                            }
                        }
                    }
                }

                return -1;
            } catch (Throwable $e) {
                return -1;
            }
        }


        // Function to get all Zoho Desk departments
        public function get_desk_departments($retry = true)
        {
            try {
                // Construct the API URL for Zoho Desk departments
                $url = "https://desk.zoho." . sanitize_text_field($this->data_center) . "/api/v1/departments";
                // Send API request
                $response = wp_remote_get($url, [
                    'headers' => [
                        'Authorization' => 'Zoho-oauthtoken ' . sanitize_text_field($this->access_token),
                        'Content-Type'  => 'application/json',
                        'orgId'         => sanitize_text_field($this->org_id)
                    ],
                    'timeout' => 60
                ]);

                // Check for network-related errors
                if (is_wp_error($response)) {
                    return [
                        'error' => 'Failed to connect to Zoho Desk. Please check your internet connection or try again later.'
                    ];
                }

                // Get HTTP response code and body
                $status_code = wp_remote_retrieve_response_code($response);
                $body = json_decode(wp_remote_retrieve_body($response), true);
                // Handle authentication or token failure
                if (
                    $status_code === 401 &&
                    isset($body['errorCode']) &&
                    in_array($body['errorCode'], ['AUTHENTICATION_FAILURE', 'INVALID_TOKEN', 'INVALID_OAUTH', 'UNAUTHORIZED'])
                ) {
                    if ($retry && $this->get_access_token()) {
                        return $this->get_desk_departments(false);
                    }
                    return [
                        'error' => 'Authentication failed. The Zoho access token is invalid or expired. Please reconnect your account and try again.'
                    ];
                }

                // Handle rate limit error
                if ($status_code === 429) {
                    return [
                        'error' => 'Too many requests. You have reached the Zoho Desk API rate limit. Please wait a few minutes and try again.'
                    ];
                }

                // Handle server errors
                if ($status_code >= 500) {
                    return [
                        'error' => 'Zoho Desk is currently experiencing technical difficulties. Please try again in a few minutes.'
                    ];
                }

                // Handle valid response with no department data
                if (isset($body['data']) && empty($body['data'])) {
                    return [
                        'error' => 'No departments found in your Zoho Desk account. Please create at least one department to proceed.'
                    ];
                }

                // Handle successful response
                if (isset($body['data'])) {
                    return $body['data'];
                }

                // Fallback for all other cases
                return [
                    'error' => 'Could not retrieve departments from Zoho Desk. Please verify your account settings and try again.'
                ];
            } catch (Throwable $e) {
                return [
                    'error' => 'An internal error occurred while retrieving departments. Please try again. If the issue continues, contact support.'
                ];
            }
        }
        // Function to get all ticket fields for a specific Zoho Desk department
        public function get_desk_departments_fields($department_id, $retry = true)
        {
            try {
                // Construct the API URL for Zoho Desk organization fields
                $url = "https://desk.zoho." . sanitize_text_field($this->data_center) . "/api/v1/organizationFields?departmentId=" . urlencode($department_id) . "&module=tickets";

                // Send API request
                $response = wp_remote_get($url, [
                    'headers' => [
                        'Authorization' => 'Zoho-oauthtoken ' . sanitize_text_field($this->access_token),
                        'Content-Type'  => 'application/json',
                        'orgId'         => sanitize_text_field($this->org_id)
                    ],
                    'timeout' => 60
                ]);

                // Check for network-related errors
                if (is_wp_error($response)) {
                    return [
                        'error' => 'Failed to connect to Zoho Desk. Please check your internet connection or try again later.'
                    ];
                }

                // Get HTTP response code and body
                $status_code = wp_remote_retrieve_response_code($response);
                $body = json_decode(wp_remote_retrieve_body($response), true);
                // Handle authentication or token failure
                if (
                    $status_code === 401 &&
                    isset($body['errorCode']) &&
                    in_array($body['errorCode'], ['AUTHENTICATION_FAILURE', 'INVALID_TOKEN', 'INVALID_OAUTH', 'UNAUTHORIZED'])
                ) {
                    if ($retry && $this->get_access_token()) {
                        return $this->get_desk_departments_fields($department_id, false);
                    }
                    return [
                        'error' => 'Authentication failed. The Zoho access token is invalid or expired. Please reconnect your account and try again.'
                    ];
                }

                // Handle rate limit error
                if ($status_code === 429) {
                    return [
                        'error' => 'Too many requests. You have reached the Zoho Desk API rate limit. Please wait a few minutes and try again.'
                    ];
                }

                // Handle server errors
                if ($status_code >= 500) {
                    return [
                        'error' => 'Zoho Desk is currently experiencing technical difficulties. Please try again in a few minutes.'
                    ];
                }

                // Handle valid response with no field data
                if (isset($body['data']) && empty($body['data'])) {
                    return [
                        'error' => 'No ticket fields found for this department. Please verify your Zoho Desk configuration.'
                    ];
                }

                // Handle successful response
                if (isset($body['data'])) {
                    return $body['data'];
                }

                // Fallback for all other cases
                return [
                    'error' => 'Could not retrieve ticket fields for the selected department. Please verify your setup and try again.'
                ];
            } catch (Throwable $e) {
                return [
                    'error' => 'An internal error occurred while retrieving ticket fields. Please try again. If the issue continues, contact support.'
                ];
            }
        }

        public function add_desk_ticket_with_contact($department_id, $ticket_data, $retry = true)
        {
            try {
                $contact_email = $ticket_data['email'];
                $contact_id_result = $this->get_zoho_desk_contact_id_by_email($contact_email);

                if (is_array($contact_id_result) && isset($contact_id_result['status']) && $contact_id_result['status'] === 'error') {
                    return $contact_id_result;
                }

                $contact_id = $contact_id_result;

                if (!$contact_id) {
                    $contact_create_result = $this->create_zoho_desk_contact([
                        'lastName' => $ticket_data['contactId'], // Or use a proper name if available
                        'email'    => $contact_email,
                    ]);

                    if (is_array($contact_create_result) && isset($contact_create_result['status']) && $contact_create_result['status'] === 'error') {
                        return $contact_create_result;
                    }

                    $contact_id = $contact_create_result;
                }

                if (!$contact_id) {
                    return $this->create_error_response('CONTACT_CREATION_FAILED', []);
                }

                $ticket_data['contactId'] = $contact_id;
                $ticket_data['departmentId'] = $department_id;

                $url = "https://desk.zoho." . $this->data_center . "/api/v1/tickets";
                $response = wp_remote_post($url, [
                    'headers' => [
                        'Authorization' => 'Zoho-oauthtoken ' . $this->access_token,
                        'Content-Type'  => 'application/json',
                        'orgId'         => $this->org_id,
                    ],
                    'body'    => wp_json_encode($ticket_data),
                    'timeout' => 60,
                ]);

                if (is_wp_error($response)) {
                    return $this->create_error_response('NETWORK_ISSUE', []);
                }

                $status_code = wp_remote_retrieve_response_code($response);
                $body = json_decode(wp_remote_retrieve_body($response), true);
                if (!is_array($body)) {
                    return $this->create_error_response('INVALID_RESPONSE', []);
                }
                if (
                    $status_code === 401 &&
                    isset($body['errorCode']) &&
                    in_array($body['errorCode'], ['AUTHENTICATION_FAILURE', 'INVALID_TOKEN', 'INVALID_OAUTH', 'UNAUTHORIZED'])
                ) {
                    if ($retry && $this->get_access_token()) {
                        return $this->add_desk_ticket_with_contact($department_id, $ticket_data, false);
                    }
                    return $this->create_error_response('AUTHENTICATION_FAILURE', $body);
                }
                if (is_array($body) && isset($body['errorCode'])) {
                    return $this->create_error_response($body['errorCode'], $body);
                }

                return $body;
            } catch (Throwable $e) {
                return $this->create_error_response('UNEXPECTED_ERROR', []);
            }
        }


        private function get_zoho_desk_contact_id_by_email($email, $retry = true)
        {
            try {
                $url = "https://desk.zoho." . $this->data_center . "/api/v1/contacts/search?email=" . urlencode($email);

                $response = wp_remote_get($url, [
                    'headers' => [
                        'Authorization' => 'Zoho-oauthtoken ' . $this->access_token,
                        'orgId'         => $this->org_id,
                    ],
                    'timeout' => 30,
                ]);

                if (is_wp_error($response)) {
                    return $this->create_error_response('NETWORK_ISSUE', []);
                }

                $body = json_decode(wp_remote_retrieve_body($response), true);
                $status_code = wp_remote_retrieve_response_code($response);

                if (!is_array($body)) {
                    return null;
                }

                if (
                    $status_code === 401 &&
                    isset($body['errorCode']) &&
                    in_array($body['errorCode'], ['AUTHENTICATION_FAILURE', 'INVALID_TOKEN', 'INVALID_OAUTH', 'UNAUTHORIZED'])
                ) {
                    if ($retry && $this->get_access_token()) {
                        return $this->get_zoho_desk_contact_id_by_email($email, false);
                    }
                    return $this->create_error_response('AUTHENTICATION_FAILURE', $body);
                }

                if (isset($body['data'][0]['id'])) {
                    return $body['data'][0]['id'];
                }

                return null;
            } catch (Throwable $e) {
                return $this->create_error_response('UNEXPECTED_ERROR', []);
            }
        }



        private function create_zoho_desk_contact($contact_data, $retry = true)
        {
            try {
                $url = "https://desk.zoho." . $this->data_center . "/api/v1/contacts";

                $response = wp_remote_post($url, [
                    'headers' => [
                        'Authorization' => 'Zoho-oauthtoken ' . $this->access_token,
                        'Content-Type'  => 'application/json',
                        'orgId'         => $this->org_id,
                    ],
                    'body'    => wp_json_encode($contact_data),
                    'timeout' => 30,
                ]);

                if (is_wp_error($response)) {
                    return $this->create_error_response('NETWORK_ISSUE', []);
                }

                $body = json_decode(wp_remote_retrieve_body($response), true);
                $status_code = wp_remote_retrieve_response_code($response);

                if (!is_array($body)) {
                    return $this->create_error_response('INVALID_RESPONSE', []);
                }

                if (
                    $status_code === 401 &&
                    isset($body['errorCode']) &&
                    in_array($body['errorCode'], ['AUTHENTICATION_FAILURE', 'INVALID_TOKEN', 'INVALID_OAUTH', 'UNAUTHORIZED'])
                ) {
                    if ($retry && $this->get_access_token()) {
                        return $this->create_zoho_desk_contact($contact_data, false);
                    }
                    return $this->create_error_response('AUTHENTICATION_FAILURE', $body);
                }

                if (isset($body['id'])) {
                    return $body['id'];
                }

                return null;
            } catch (Throwable $e) {
                return $this->create_error_response('UNEXPECTED_ERROR', []);
            }
        }
        //
      public function upload_attachment($ticket_id, $file_input, $retry = true)
{
    try {
        $ticket_id  = sanitize_text_field($ticket_id);
        $upload_dir = wp_upload_dir();

        /* ---------------------------------
         * Normalize input (URL or FILE PATH)
         * --------------------------------- */
        if (file_exists($file_input)) {
            // Absolute path (CF7)
            $file_path = wp_normalize_path($file_input);
            $file_url  = str_replace(
                wp_normalize_path($upload_dir['basedir']),
                $upload_dir['baseurl'],
                $file_path
            );
        } else {
            // URL (WPForms / Elementor / Gravity)
            $file_url = esc_url_raw($file_input);

            if (empty($upload_dir['baseurl']) || strpos($file_url, $upload_dir['baseurl']) !== 0) {
                return $this->create_error_response('INVALID_FILE_URL', [
                    'file_url' => $file_url,
                ]);
            }

            $file_path = wp_normalize_path(
                str_replace($upload_dir['baseurl'], $upload_dir['basedir'], $file_url)
            );
        }

        if (!file_exists($file_path) || !is_readable($file_path)) {
            return $this->create_error_response('FILE_NOT_FOUND', [
                'file_path' => $file_path,
            ]);
        }

        /* ---------------------------------
         * File metadata
         * --------------------------------- */
        $filename = basename($file_path);
        $mime     = function_exists('mime_content_type')
            ? mime_content_type($file_path)
            : 'application/octet-stream';

        if (empty($mime)) {
            $mime = 'application/octet-stream';
        }

        /* ---------------------------------
         * Read file using WP_Filesystem
         * --------------------------------- */
        global $wp_filesystem;

        if (!function_exists('WP_Filesystem')) {
            require_once ABSPATH . 'wp-admin/includes/file.php';
        }

        WP_Filesystem();

        if (!$wp_filesystem) {
            return $this->create_error_response('FILESYSTEM_INIT_FAILED', []);
        }

        $file_contents = $wp_filesystem->get_contents($file_path);

        if ($file_contents === false) {
            return $this->create_error_response('FILE_READ_FAILED', [
                'file_path' => $file_path,
            ]);
        }

        /* ---------------------------------
         * Build multipart body (WP safe)
         * --------------------------------- */
        $boundary = '----wpzoho' . wp_generate_password(24, false, false);

        $body  = "--{$boundary}\r\n";
        $body .= "Content-Disposition: form-data; name=\"file\"; filename=\"{$filename}\"\r\n";
        $body .= "Content-Type: {$mime}\r\n\r\n";
        $body .= $file_contents . "\r\n";
        $body .= "--{$boundary}--\r\n";

        /* ---------------------------------
         * Zoho Desk API request
         * --------------------------------- */
        $url = "https://desk.zoho." . sanitize_text_field($this->data_center)
            . "/api/v1/tickets/" . rawurlencode($ticket_id) . "/attachments";

        $response = wp_remote_post($url, [
            'headers' => [
                'Authorization'  => 'Zoho-oauthtoken ' . sanitize_text_field($this->access_token),
                'orgId'          => sanitize_text_field($this->org_id),
                'Content-Type'   => 'multipart/form-data; boundary=' . $boundary,
                'Content-Length' => strlen($body),
            ],
            'body'    => $body,
            'timeout' => 60,
        ]);

        if (is_wp_error($response)) {
            return $this->create_error_response('NETWORK_ISSUE', [
                'message' => $response->get_error_message(),
            ]);
        }

        $status_code = wp_remote_retrieve_response_code($response);
        $resp_raw    = wp_remote_retrieve_body($response);
        $resp_body   = json_decode($resp_raw, true);

        if (!is_array($resp_body)) {
            $resp_body = ['raw' => $resp_raw];
        }

        /* ---------------------------------
         * Token refresh handling
         * --------------------------------- */
        if (
            $status_code === 401 &&
            isset($resp_body['errorCode']) &&
            in_array($resp_body['errorCode'], [
                'AUTHENTICATION_FAILURE',
                'INVALID_TOKEN',
                'INVALID_OAUTH',
                'UNAUTHORIZED'
            ], true)
        ) {
            if ($retry && $this->get_access_token()) {
                return $this->upload_attachment($ticket_id, $file_input, false);
            }
            return $this->create_error_response('AUTHENTICATION_FAILURE', $resp_body);
        }

        if (isset($resp_body['errorCode'])) {
            return $this->create_error_response($resp_body['errorCode'], $resp_body);
        }

        return $resp_body;

    } catch (Throwable $e) {
        return $this->create_error_response('UNEXPECTED_ERROR', [
            'message' => $e->getMessage(),
        ]);
    }
}


        /**
         * Helper function to create a standardized error response.
         */
        private function create_error_response($error_code, $body)
        {
            return [
                'status' => 'error',
                'category' => $error_code,
                'body' => $body
            ];
        }
    }
}
