<?php
/**
 * Theft detection (actions)
 * 
 * Trait for the main plugin class.
 * Recovery scoring, Theft detection logs, shortcodes.
 * 
 * @package My Trail Camera
 * @since 8.1.0
 */

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

trait Mtcam_Detections_Actions {
    
    public function get_camera_info($device_id) {
        $cameras = $this->get_cameras();
        return isset($cameras[$device_id]) ? $cameras[$device_id] : array('name' => $device_id, 'color' => MTCAM_DEFAULT_COLOR, 'location' => __('Unknown', 'my-trail-camera'));
    }

    // ============================================================================
    // DETECTIONS — N+1 QUERY FIX + RECOVERY SCORING
    // ============================================================================
    
    /**
     * Batch load detection counts for all Trail Cameras
     */
    public function get_detection_counts() {
        global $wpdb;
        
        $counts = wp_cache_get( 'mtcam_detection_counts' );
        if ( false === $counts ) {
            $results = mtcam_db_get_results(
                'SELECT device_id, COUNT(*) as count
                 FROM `' . $wpdb->prefix . 'mtcam_detections`
                 GROUP BY device_id',
                OBJECT_K
            );
            
            $counts = [];
            foreach ($results as $device_id => $row) {
                $counts[$device_id] = (int) $row->count;
            }
            wp_cache_set( 'mtcam_detection_counts', $counts );
        }
        
        return $counts;
    }

    public function calculate_recovery_chance($log) {
        $score = 0;
        $factors = array();

        // ── GPS (max 35) — most important for physical recovery ──
        if ($log->lat != '?' && $log->lon != '?' && $log->lat != '0' && $log->lon != '0') {
            $accuracy = floatval($log->acc);
            if ($accuracy > 0 && $accuracy <= 100) {
                $score += 35;
                /* translators: %s: Accuracy distance in meters */
                $factors[] = array('factor' => '📍 ' . sprintf(__('GPS excellent (%sm)', 'my-trail-camera'), round($accuracy)), 'points' => 35, 'status' => 'good');
            } elseif ($accuracy <= 500) {
                $score += 28;
                /* translators: %s: Accuracy distance in meters */
                $factors[] = array('factor' => '📍 ' . sprintf(__('GPS accurate (%sm)', 'my-trail-camera'), round($accuracy)), 'points' => 28, 'status' => 'good');
            } elseif ($accuracy <= 5000) {
                $gps_score = max(8, min(18, round(18 - (($accuracy - 500) / 350))));
                $score += $gps_score;
                /* translators: %s: Accuracy distance in meters */
                $factors[] = array('factor' => '📍 ' . sprintf(__('GPS medium (%sm)', 'my-trail-camera'), round($accuracy)), 'points' => $gps_score, 'status' => 'medium');
            } else {
                $score += 5;
                /* translators: %s: Accuracy distance in meters */
                $factors[] = array('factor' => '📍 ' . sprintf(__('GPS low accuracy (%sm)', 'my-trail-camera'), round($accuracy)), 'points' => 5, 'status' => 'medium');
            }
        } else {
            $factors[] = array('factor' => __('GPS not available', 'my-trail-camera'), 'points' => 0, 'status' => 'bad');
        }

        // ── IP address (max 15) ──
        if (!empty($log->ip) && $log->ip != '?' && $log->ip != 'Unknown') {
            $score += 15;
            $factors[] = array('factor' => '🌐 ' . __('IP address captured', 'my-trail-camera'), 'points' => 15, 'status' => 'good');
        } else {
            $factors[] = array('factor' => __('No IP address', 'my-trail-camera'), 'points' => 0, 'status' => 'bad');
        }

        // ── Time factor (max 10) — fresher detection = higher chance ──
        if (!empty($log->time)) {
            $hours_ago = (time() - strtotime($log->time)) / 3600;
            if ($hours_ago <= 1) {
                $score += 10;
                $factors[] = array('factor' => '⏰ ' . __('Detected less than 1 hour ago', 'my-trail-camera'), 'points' => 10, 'status' => 'good');
            } elseif ($hours_ago <= 24) {
                $score += 7;
                $factors[] = array('factor' => '⏰ ' . __('Detected within 24 hours', 'my-trail-camera'), 'points' => 7, 'status' => 'good');
            } elseif ($hours_ago <= 168) {
                $score += 3;
                $factors[] = array('factor' => '⏰ ' . __('Detected within 7 days', 'my-trail-camera'), 'points' => 3, 'status' => 'medium');
            } else {
                $factors[] = array('factor' => '⏰ ' . __('Detection is older than 7 days', 'my-trail-camera'), 'points' => 0, 'status' => 'bad');
            }
        }

        // ── Device fingerprint (max 5) — helps identify the device ──
        $has_os = !empty($log->os_info) && $log->os_info != '?';
        $has_screen = !empty($log->screen_res) && $log->screen_res != '?';
        if ($has_os && $has_screen) {
            $score += 5;
            $factors[] = array('factor' => '💻 ' . __('Full device fingerprint', 'my-trail-camera'), 'points' => 5, 'status' => 'good');
        } elseif ($has_os || $has_screen) {
            $score += 2;
            $factors[] = array('factor' => '💻 ' . __('Partial device fingerprint', 'my-trail-camera'), 'points' => 2, 'status' => 'medium');
        }

        $percentage = min(100, $score);
        return array('percentage' => round($percentage), 'factors' => $factors, 'recommendation' => $this->get_recommendation($percentage, $log));
    }

    private function get_recommendation($percentage, $log) {
        if ($percentage >= 70) {
            $actions = array(__('Contact police immediately with GPS coordinates', 'my-trail-camera'));
            return array('level' => 'high', 'text' => __('HIGH chance of recovery!', 'my-trail-camera'), 'actions' => $actions);
        } elseif ($percentage >= 40) {
            return array('level' => 'medium', 'text' => __('MEDIUM chance of recovery', 'my-trail-camera'), 'actions' => array(__('Contact police with available data', 'my-trail-camera'), __('Monitor further access attempts', 'my-trail-camera'), __('Check the nearby area', 'my-trail-camera')));
        }
        return array('level' => 'low', 'text' => __('LOW chance of recovery', 'my-trail-camera'), 'actions' => array(__('Report the case to police', 'my-trail-camera'), __('Monitor IP address', 'my-trail-camera'), __('Camera is probably lost', 'my-trail-camera')));
    }

    /**
     * Handle detection POST actions (delete/reset) before headers are sent.
     * Hooked to admin_init so wp_safe_redirect() works correctly.
     */
    public function handle_detection_actions() {
        if ( ! isset( $_POST['action'] ) ) {
            return;
        }
        $post_action = sanitize_text_field( wp_unslash( $_POST['action'] ) );

        // Delete single record (POST)
        if ( 'delete_record' === $post_action && isset( $_POST['log_id'] ) ) {
            if ( ! current_user_can( 'manage_options' ) ) {
                wp_die( esc_html__( 'Insufficient permissions.', 'my-trail-camera' ), '', 403 );
            }
            $del_log_id = intval( wp_unslash( $_POST['log_id'] ) );
            check_admin_referer( 'delete_log_' . $del_log_id );
            $this->delete_log( $del_log_id );
            wp_safe_redirect( wp_nonce_url( admin_url( 'admin.php?page=mtcam-logs&deleted=1' ), 'mtcam_logs_notice' ) );
            exit;
        }

        // Reset all records (POST)
        if ( 'reset_all' === $post_action ) {
            if ( ! current_user_can( 'manage_options' ) ) {
                wp_die( esc_html__( 'Insufficient permissions.', 'my-trail-camera' ), '', 403 );
            }
            check_admin_referer( 'reset_all_logs' );
            global $wpdb;
            mtcam_db_query( 'TRUNCATE TABLE `' . $wpdb->prefix . 'mtcam_detections`' );
            wp_cache_delete( 'mtcam_detection_counts' );

            wp_safe_redirect( wp_nonce_url( admin_url( 'admin.php?page=mtcam-logs&reset=1' ), 'mtcam_logs_notice' ) );
            exit;
        }
    }

    public function admin_page() {
        global $wpdb;

        $cache_key = 'mtcam_admin_logs';
        $logs = wp_cache_get( $cache_key );
        if ( false === $logs ) {
            $logs = mtcam_db_get_results( 'SELECT * FROM `' . $wpdb->prefix . 'mtcam_detections` ORDER BY time DESC' );
            wp_cache_set( $cache_key, $logs );
        }
        $cameras = $this->get_cameras();
        $tracker = $this;
        
        include plugin_dir_path($this->plugin_file) . 'thor/pages/page-detections.php';
    }

    private function delete_log($id) {
        global $wpdb;

        // Get device_id before deleting so we can check remaining detections.
        $device_id = mtcam_db_get_var(
            $wpdb->prepare( 'SELECT device_id FROM `' . $wpdb->prefix . 'mtcam_detections` WHERE id = %d', $id )
        );

        mtcam_db_delete($this->table_name, array('id' => $id), array('%d'));
        wp_cache_delete( 'mtcam_detection_counts' );
        wp_cache_delete( 'mtcam_admin_logs' );

        // If no detections remain for this camera, revert its status.
        if ( $device_id && $device_id !== '?' ) {
            $remaining = (int) mtcam_db_get_var(
                $wpdb->prepare( 'SELECT COUNT(*) FROM `' . $wpdb->prefix . 'mtcam_detections` WHERE device_id = %s', $device_id )
            );
            if ( 0 === $remaining ) {
                $this->revert_camera_status( $device_id );
            }
        }
    }

    /**
     * Revert camera status after all detections are deleted.
     * Stolen → In field, Tested → In field (clear tested flag).
     */
    private function revert_camera_status( $device_id ) {
        $cameras = mtcam_get_cameras();
        if ( ! isset( $cameras[ $device_id ] ) ) {
            return;
        }
        $cam = $cameras[ $device_id ];

        $fields = array();

        if ( ! empty( $cam['stolen_date'] ) ) {
            // Camera was marked stolen — revert to "in field".
            $fields['stolen_date']     = '';
            $fields['active']          = 'yes';
            $fields['tested']          = 'no';
            $fields['police_reported'] = 'no';
        } elseif ( 'yes' === ( $cam['tested'] ?? 'no' ) ) {
            // Camera was marked as tested — clear tested flag.
            $fields['tested'] = 'no';
        }

        if ( ! empty( $fields ) ) {
            mtcam_update_camera_fields( $device_id, $fields );
        }
    }

    public function public_logs_shortcode($atts) {
        global $wpdb;
        $atts = shortcode_atts(array('limit' => 5, 'device' => ''), $atts);
        if ( ! empty( $atts['device'] ) ) {
            $logs = mtcam_db_get_results( $wpdb->prepare(
                            'SELECT id, time, device_id, file_name, os_info, screen_res, ip, lat, lon, acc FROM `' . $wpdb->prefix . 'mtcam_detections` WHERE device_id = %s ORDER BY time DESC LIMIT %d',
                            strtoupper( $atts['device'] ),
                            intval( $atts['limit'] )
                        ) );
        } else {
            $logs = mtcam_db_get_results( $wpdb->prepare(
                            'SELECT id, time, device_id, file_name, os_info, screen_res, ip, lat, lon, acc FROM `' . $wpdb->prefix . 'mtcam_detections` ORDER BY time DESC LIMIT %d',
                            intval( $atts['limit'] )
                        ) );
        }
        $cameras = $this->get_cameras();
        $tracker = $this;
        ob_start();
        include plugin_dir_path($this->plugin_file) . 'admin/widgets/widget-public-logs.php';
        return ob_get_clean();
    }

}
