<?php
/**
 * MTC - Shared helper functions (core)
 * Version, formatting, filters, ownership, security.
 * @package My Trail Camera
 * @since 8.1.0
 */

if (!defined('ABSPATH')) exit;

// ============================================================================
// VERSION
// ============================================================================

/**
 * Get MTC version
 */
function mtcam_get_version() {
    return defined('MTCAM_VERSION') ? MTCAM_VERSION : '7.9.7';
}

/**
 * Get MTC version with 'v' prefix for display
 */
function mtcam_get_version_display() {
    return 'v' . mtcam_get_version();
}

// ============================================================================
// FREEMIUS — PRO TIER
// ============================================================================

// ============================================================================
// FORMATTING
// ============================================================================

/**
 * Format date (dd.mm.yyyy style)
 */
function mtcam_format_date($date_string) {
    if (empty($date_string)) return '—';
    try {
        $date = new DateTime($date_string);
        return $date->format('d.m.Y');
    } catch (Exception $e) {
        return $date_string;
    }
}

/**
 * Format date wrapped in a <time> element for HTML5 semantics.
 *
 * @param string $date_string Raw date string.
 * @param string $format      Display format (default 'd.m.Y').
 * @return string HTML <time> element or em-dash if empty.
 */
function mtcam_format_date_html( $date_string, $format = 'd.m.Y' ) {
    if ( empty( $date_string ) ) {
        return '—';
    }
    try {
        $date = new DateTime( $date_string );
    } catch ( Exception $e ) {
        return esc_html( $date_string );
    }
    return '<time datetime="' . esc_attr( $date->format( 'Y-m-d' ) ) . '">'
        . esc_html( $date->format( $format ) ) . '</time>';
}

/**
 * Echo a date wrapped in <time> element (shorthand for echo wp_kses_post( mtcam_format_date_html(...) )).
 *
 * @param string $date_string Date string (Y-m-d or similar).
 * @param string $format      Display format (default 'd.m.Y').
 */
function mtcam_echo_date_html( $date_string, $format = 'd.m.Y' ) {
    echo wp_kses_post( mtcam_format_date_html( $date_string, $format ) );
}

/**
 * Format a timestamp (date+time) as a <time> element.
 * Uses wp_date() for WordPress timezone-aware formatting.
 *
 * @param string $timestamp      MySQL datetime string.
 * @param string $display_format Display format (default 'j.m.Y - H:i').
 * @param string $iso_format     ISO datetime attr format (default 'Y-m-d\TH:i').
 * @return string HTML <time> element.
 */
function mtcam_format_datetime_html( $timestamp, $display_format = 'j.m.Y - H:i', $iso_format = 'Y-m-d\\TH:i' ) {
    if ( empty( $timestamp ) ) {
        return '—';
    }
    $unix = strtotime( $timestamp );
    if ( false === $unix ) {
        return esc_html( $timestamp );
    }
    return '<time datetime="' . esc_attr( wp_date( $iso_format, $unix ) ) . '">'
        . esc_html( wp_date( $display_format, $unix ) ) . '</time>';
}

/**
 * Render an accessible table caption (visually hidden).
 *
 * @param string $text Caption text (already translated).
 */
function mtcam_table_caption( $text ) {
    echo '<caption class="screen-reader-text">' . esc_html( $text ) . '</caption>';
}

// ============================================================================
// CAMERA STATUS
// ============================================================================

/**
 * Check if camera is owned by current user
 */
function mtcam_is_my_camera($cam) {
    return ($cam['owner'] ?? 'me') === 'me';
}

/**
 * Helper functions for repeated checks
 * Eliminates duplicate code across the project
 */

/**
 * Check if camera is stolen
 */
function mtcam_is_stolen($cam) {
    return !empty($cam['stolen_date'] ?? '');
}

/**
 * Check if camera is active
 */
function mtcam_is_active($cam) {
    return ($cam['active'] ?? 'yes') === 'yes';
}

/**
 * Check if camera is tested
 */
function mtcam_is_tested($cam) {
    return ($cam['tested'] ?? 'no') === 'yes';
}

/**
 * Reset all deployment-related fields when camera goes home.
 *
 * Clears GPS, deploy date/time, recording settings, battery, solar and terrain.
 * Used by End Monitoring and status change to "at home".
 *
 * @param array $cam Camera data array (modified in place via reference).
 * @return array The cleaned camera data.
 */
function mtcam_reset_deployment_fields( &$cam ) {
	$fields = array(
		'location', 'deploy_date', 'deploy_time',
		'gps_lat', 'gps_lon',
		'rec_mode', 'rec_resolution', 'rec_length',
		'rec_day_count', 'rec_night_count',
		'battery_pct', 'solar_panel_w', 'terrain_type',
		'last_checked',
	);
	foreach ( $fields as $f ) {
		$cam[ $f ] = '';
	}
	return $cam;
}

// ============================================================================
// FILTERS AND OWNERSHIP
// ============================================================================

/**
 * Filter cameras by ownership
 * 
 * @param array $cameras All cameras
 * @param string $filter 'my'|'other'|'all'
 * @return array Filtered cameras
 */
function mtcam_filter_cameras($cameras, $filter = 'all') {
    if ($filter === 'all') {
        return $cameras;
    }
    
    $filtered = array();
    foreach ($cameras as $cam_id => $cam) {
        $is_mine = mtcam_is_my_camera($cam);
        
        if ($filter === 'my' && $is_mine) {
            $filtered[$cam_id] = $cam;
        } elseif ($filter === 'other' && !$is_mine) {
            $filtered[$cam_id] = $cam;
        }
    }
    
    return $filtered;
}

/**
 * Filter logs by camera ownership
 * 
 * @param array $logs All logs
 * @param array $cameras All cameras (for ownership lookup)
 * @param string $filter 'my'|'other'|'all'
 * @return array Filtered logs
 */
function mtcam_filter_logs($logs, $cameras, $filter = 'all') {
    if ($filter === 'all') {
        return $logs;
    }
    
    $filtered = array();
    foreach ($logs as $log) {
        $device_id = strtoupper($log->device_id); // Ensure uppercase
        $cam = $cameras[$device_id] ?? null;
        if (!$cam) continue; // Skip logs without camera
        
        $is_mine = mtcam_is_my_camera($cam);
        
        if ($filter === 'my' && $is_mine) {
            $filtered[] = $log;
        } elseif ($filter === 'other' && !$is_mine) {
            $filtered[] = $log;
        }
    }
    
    return $filtered;
}

/**
 * Get notification email for camera
 */
function mtcam_get_notification_email($cam) {
    if (mtcam_is_my_camera($cam)) {
        return get_option('mtcam_notify_email', get_option('admin_email'));
    }
    return $cam['owner_email'] ?? get_option('admin_email');
}

/**
 * Get locale for plugin emails (uses recipient's WP user locale if available)
 */
function mtcam_get_email_locale() {
    $email = get_option('mtcam_notify_email', get_option('admin_email'));
    $user  = get_user_by('email', $email);
    if ($user) {
        return get_user_locale($user->ID);
    }
    return get_locale();
}

/**
 * Render owner badge
 */
function mtcam_render_owner_badge($cam) {
    if (!mtcam_is_my_camera($cam)) {
        $owner_name = $cam['owner_name'] ?? __('Other owner', 'my-trail-camera');
        $owner_email = $cam['owner_email'] ?? '';
        echo '<span class="mtcam-owner-badge" title="' . esc_attr($owner_email) . '">';
        echo esc_html(MTCAM_ICON_OWNER) . ' ' . esc_html($owner_name);
        echo '</span>';
    }
}

/**
 * Get camera display name (for public widgets)
 * Shows camera name, or camera ID if name not available
 */
function mtcam_get_camera_display_name($cam_id, $cam) {
    if (!empty($cam['name'])) {
        return $cam['name'];
    }
    return $cam_id;
}

// ============================================================================
// SECURITY
// ============================================================================

function mtcam_rate_limit($device_id) {

    $client_ip = isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : '';
    $key = 'mtcam_rate_' . md5($device_id . $client_ip);
    $count = get_transient($key);

    if ($count === false) {
        set_transient($key, 1, 300);
        return true;
    }

    if ($count > 30) { // 30 requests / 5 min
        return false;
    }

    set_transient($key, $count + 1, 300);
    return true;
}

function mtcam_verify_signature($payload, $timestamp, $signature, $secret) {
    // Bait HTML/JS cannot contain secret_key (it would be visible to the thief),
    // so cameras without secret_key work without HMAC — device_id validation
    // and rate limiting is handled in data-collector.
    if (empty($secret)) return true;
    
    // Camera has secret_key — signature is REQUIRED
    if (empty($signature) || empty($timestamp)) return false;

    // Replay attack protection: max 5 min old requests
    if (abs(time() - intval($timestamp)) > 300) {
        return false;
    }

    $expected = hash_hmac('sha256', $payload . $timestamp, $secret);
    return hash_equals($expected, $signature);
}

function mtcam_check_nonce($nonce) {
    // Bait files do not generate nonce — replay protection only works for cameras with secret_key
    if (!$nonce) return true;

    $key = 'mtcam_nonce_' . md5($nonce);

    if (get_transient($key)) {
        return false;
    }

    set_transient($key, 1, DAY_IN_SECONDS);
    return true;
}

/**
 * Encrypt a value using AES-256-CBC with wp_salt().
 * @since 8.2.1
 */
function mtcam_encrypt($value) {
    if (empty($value)) return '';
    $key = hash('sha256', wp_salt('auth'), true);
    $iv  = openssl_random_pseudo_bytes(16);
    $encrypted = openssl_encrypt($value, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
    return base64_encode($iv . $encrypted);
}

/**
 * Decrypt a value encrypted with mtcam_encrypt().
 * @since 8.2.1
 */
function mtcam_decrypt($value) {
    if (empty($value)) return '';
    $data = base64_decode($value);
    if ($data === false || strlen($data) < 17) return '';
    $key = hash('sha256', wp_salt('auth'), true);
    $iv  = substr($data, 0, 16);
    $encrypted = substr($data, 16);
    $decrypted = openssl_decrypt($encrypted, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
    return $decrypted !== false ? $decrypted : '';
}

// ============================================================================
// CAMERA VALUE & DISPLAY HELPERS
// ============================================================================

/**
 * Calculate total camera value including accessories
 */
function mtcam_get_camera_total_value($cam) {
    $total = floatval($cam['price'] ?? 0);

    if (($cam['acc_battery'] ?? 'no') === 'yes') {
        $total += floatval($cam['acc_battery_price'] ?? 0);
    }
    if (($cam['acc_sdcard'] ?? 'no') === 'yes') {
        $total += floatval($cam['acc_sdcard_price'] ?? 0);
    }
    if (($cam['acc_sim'] ?? 'no') === 'yes') {
        $total += floatval($cam['acc_sim_price'] ?? 0);
    }

    // Extra priced items merged into the accessories list (security + GPS trackers).
    // bait_html / bait_tel are intentionally excluded — they are digital trap templates with no physical cost.
    $mtcam_extra_priced = array(
        'sec_box', 'sec_cable', 'sec_padlock', 'sec_password', 'sec_camera',
        'gps_airtag', 'gps_tile', 'gps_samsung', 'gps_other',
    );
    foreach ( $mtcam_extra_priced as $mtcam_key ) {
        if ( ( $cam[ $mtcam_key ] ?? 'no' ) === 'yes' ) {
            $total += floatval( $cam[ $mtcam_key . '_price' ] ?? 0 );
        }
    }

    return $total;
}

/**
 * Battery color based on percentage level
 * Green > 60%, Orange > 30%, Red <= 30%
 */
function mtcam_battery_color($pct) {
    if ($pct > 60) return '#4CAF50';
    if ($pct > 30) return '#FF9800';
    return '#f44336';
}

