#!/bin/bash

# Function to URL encode a string (for shell, compatible with Ubuntu 20.04)
urlencode() {
    local length="${#1}"
    for (( i = 0; i < length; i++ )); do
        local c="${1:i:1}"
        case $c in
            [a-zA-Z0-9.~_-]) printf "$c" ;;
            *) printf '%%%02X' "'$c" ;;
        esac
    done
}

# Function to send SMS using different API methods
sendSmsThroughApi() {
    local smsMethod="$1"
    local smsApiUrl="$2"
    local smsApiKey="$3"
    local smsApiSecret="$4"
    local dst="$5"
    local text="$6"
    local smsCallerID="$7"
    local smsMessageType="$7"

    # URL encode the message
    local text_encoded
    text_encoded=$(urlencode "$text")

    # Replace placeholders in URL
    smsApiUrl="${smsApiUrl//\{dst\}/$dst}"
    smsApiUrl="${smsApiUrl//\{text\}/$text_encoded}"

    if [[ "$smsMethod" == "1" ]]; then
        response=$(curl -s -X POST "$smsApiUrl" \
            -H "Content-Type: application/json" \
            -d "{\"apikey\":\"$smsApiKey\",\"secretkey\":\"$smsApiSecret\",\"callerID\":\"$smsCallerID\",\"toUser\":\"$dst\",\"messageContent\":\"$text\"}")
        echo "$response"

    elif [[ "$smsMethod" == "2" ]]; then
        response=$(curl -s "$smsApiUrl")
        echo "$response"

    elif [[ "$smsMethod" == "3" ]]; then
        msgType="TEXT"
        [[ "$smsMessageType" == "2" ]] && msgType="UNICODE"

        response=$(curl -s -X POST "$smsApiUrl" \
            -H "Accept: application/json" \
            -d "api_key=$smsApiKey&api_secret=$smsApiSecret&request_type=SINGLE_SMS&message_type=$msgType&mobile=$dst&message_body=$text")
        echo "$response"

    elif [[ "$smsMethod" == "4" ]]; then
        # Fetch token info from DB
        tokenQuery="SELECT id, token, refresh_token, token_time FROM srzone_sms_api WHERE api_key = '$smsApiKey' LIMIT 1;"
        tokenResult=$($mysql_command -N -e "$tokenQuery")

        tokenId=$(echo "$tokenResult" | awk '{print $1}')
        token=$(echo "$tokenResult" | awk '{print $2}')
        refreshToken=$(echo "$tokenResult" | awk '{print $3}')
        tokenTime=$(echo "$tokenResult" | awk '{print $4}')

        # Convert tokenTime to epoch seconds
        if [[ -n "$tokenTime" ]]; then
            tokenTimeEpoch=$(date -d "$tokenTime" +%s)
        else
            tokenTimeEpoch=0
        fi

        nowEpoch=$(date +%s)
        expiryThreshold=$((55 * 60))  # 55 minutes in seconds

        # Function to update token info in DB
        update_token_db() {
            local newToken="$1"
            local newRefreshToken="$2"
            local id="$3"
            updateQuery="UPDATE srzone_sms_api SET token = '$newToken', refresh_token = '$newRefreshToken', token_time = NOW() WHERE id = $id;"
            $mysql_command -e "$updateQuery"
        }

        # Refresh token if expired or missing
        if [[ -z "$token" || $(( nowEpoch - tokenTimeEpoch )) -ge $expiryThreshold ]]; then
            newTokenData=""

            # Try refresh with refreshToken
            if [[ -n "$refreshToken" ]]; then
                refreshResponse=$(curl -s -X POST "https://api.mobireach.com.bd/auth/token/refresh" \
                    -H "Content-Type: application/json" \
                    -H "Authorization: Bearer $refreshToken" \
                    --max-time 10)

                newToken=$(echo "$refreshResponse" | jq -r '.token // empty')
                if [[ -n "$newToken" ]]; then
                    newRefreshToken=$(echo "$refreshResponse" | jq -r '.refresh_token // empty')
                    newTokenData="$refreshResponse"
                fi
            fi

            # If refresh failed, get new token with username & password
            if [[ -z "$newTokenData" ]]; then
                authPayload=$(jq -n --arg u "$smsApiKey" --arg p "$smsApiSecret" '{username: $u, password: $p}')
                newTokenData=$(curl -s -X POST "https://api.mobireach.com.bd/auth/tokens" \
                    -H "Content-Type: application/json" \
                    --data "$authPayload" \
                    --max-time 10)

                newToken=$(echo "$newTokenData" | jq -r '.token // empty')
                newRefreshToken=$(echo "$newTokenData" | jq -r '.refresh_token // empty')

                if [[ -z "$newToken" ]]; then
                    echo "Error: Failed to obtain a new token."
                    echo "$newTokenData"
                    exit 1
                fi
            fi

            # Update DB with new token info
            update_token_db "$newToken" "$newRefreshToken" "$tokenId"
            token="$newToken"
        fi

        # Sanitize smsMessageType as a valid number
        if ! [[ "$smsMessageType" =~ ^[0-9]+$ ]]; then
            smsMessageType="1"  # default value if invalid
        fi

        # Prepare JSON data for sending SMS
        postData=$(jq -n \
            --arg sender "$smsCallerID" \
            --arg receiver "$dst" \
            --arg content "$text" \
            --argjson contentType "$smsMessageType" \
            '{
                sender: $sender,
                receiver: [$receiver],
                contentType: $contentType,
                content: $content,
                msgType: "T",
                requestType: "S"
            }')

        # Send SMS using token
        response=$(curl -s -X POST "$smsApiUrl" \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $token" \
            --data "$postData" \
            --max-time 10)

        # Output response
        echo "$response"
    fi

}

export DB_NAME=$(grep 'db_name' /opt/srzone/etc/config.ini | awk -F= '{print $2}')
export DB_HOST=$(grep 'db_host' /opt/srzone/etc/config.ini | awk -F= '{print $2}')
export DB_USERNAME=$(grep 'db_username' /opt/srzone/etc/config.ini | awk -F= '{print $2}')
export DB_PASSWORD=$(grep 'db_password' /opt/srzone/etc/config.ini | awk -F= '{print $2}')

# Connect to the database
mysql_command="mysql -h$DB_HOST -u$DB_USERNAME -p$DB_PASSWORD $DB_NAME"

# Fetch unsent SMS entries
unsent_sms_query="SELECT id, dst, text, user_id FROM srzone_sms_queue WHERE sent = 0;"
unsent_sms_result=$($mysql_command -e "$unsent_sms_query")

if [ $? -ne 0 ]; then
    echo "Error retrieving unsent SMS entries: $unsent_sms_result"
    exit 1
fi

# Process unsent SMS entries
while IFS=$'\t' read -r sms_id dst sms_text user_id; do
    # Skip the header row
    if [[ "$sms_id" == "id" ]]; then
        continue
    fi

    # Retrieve SMS API details based on dst phone number
    sms_api_query="SELECT sa.api_url, sa.api_key, sa.api_secret, sa.sms_method, sa.callerID, sa.messageType, sa.status 
                   FROM srzone_users u 
                   JOIN srzone_partners p ON u.partnerId = p.id 
                   JOIN srzone_sms_api sa ON p.sms_api_id = sa.id 
                   WHERE u.phone = '$dst' AND sa.status = 1;"
    sms_api_result=$($mysql_command -e "$sms_api_query")

    if [ $? -ne 0 ]; then
        echo "Error retrieving SMS API details for phone number $dst: $sms_api_result"
        exit 1
    fi

    # Extract API details
    smsApiUrl=$(echo "$sms_api_result" | tail -n 1 | cut -f1)
    smsApiKey=$(echo "$sms_api_result" | tail -n 1 | cut -f2)
    smsApiSecret=$(echo "$sms_api_result" | tail -n 1 | cut -f3)
    smsMethod=$(echo "$sms_api_result" | tail -n 1 | cut -f4)
    smsCallerID=$(echo "$sms_api_result" | tail -n 1 | cut -f5)
    messageType=$(echo "$sms_api_result" | tail -n 1 | cut -f6)

    if [[ -z "$smsApiUrl" || -z "$smsMethod" ]]; then
        echo "No valid API URL or method found for phone number $dst. Skipping."

        # Mark SMS as sent even though it was skipped
        if [[ "$sms_id" =~ ^[0-9]+$ ]] && [ "$sms_id" -gt 0 ]; then
            update_query="UPDATE srzone_sms_queue SET sent = 1, sms_log = 'Skipped due to missing API info', updated_at = NOW() WHERE id = $sms_id;"
            $mysql_command -e "$update_query"

            if [ $? -ne 0 ]; then
                echo "Error updating skipped SMS entry in the database for ID $sms_id"
                exit 1
            fi
        fi

        continue
    fi

    # Send SMS through API
    api_response=$(sendSmsThroughApi "$smsMethod" "$smsApiUrl" "$smsApiKey" "$smsApiSecret" "$dst" "$sms_text" "$smsCallerID" "$messageType")

    # Check if $sms_id is a valid number
    if [[ "$sms_id" =~ ^[0-9]+$ ]] && [ "$sms_id" -gt 0 ]; then
        # Update srzone_sms_queue with the API response
        update_query="UPDATE srzone_sms_queue SET sent = 1, sms_log = '$api_response', updated_at = NOW() WHERE id = $sms_id;"
        $mysql_command -e "$update_query"

        if [ $? -ne 0 ]; then
            echo "Error updating SMS entry in the database: $api_response"
            exit 1
        fi
    else
        echo "Invalid SMS ID '$sms_id'. Skipping update."
    fi
done <<< "$unsent_sms_result"

echo "SMS entries processed successfully."
