<?php
if ( ! defined( 'ABSPATH' ) ) exit;
class ShippingGuard_Claims_API {
    public function init() {
        add_action( 'rest_api_init', array( $this, 'register_routes' ) );
    }

    public function register_routes() {
        // Admin: Get all claims
        register_rest_route( 'shippingguard/v1', '/claims', array(
            array(
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => array( $this, 'get_claims' ),
                'permission_callback' => function() { return current_user_can( 'manage_options' ); },
            ),
        ) );

        // Admin: Update claim status
        register_rest_route( 'shippingguard/v1', '/claims/(?P<id>\d+)', array(
            array(
                'methods'             => WP_REST_Server::EDITABLE,
                'callback'            => array( $this, 'update_claim' ),
                'permission_callback' => function() { return current_user_can( 'manage_options' ); },
                'args'               => array(
                    'id' => array( 'validate_callback' => function( $param ) { return is_numeric( $param ); } ),
                ),
            ),
        ) );

        // Customer: Submit a claim
        register_rest_route( 'shippingguard/v1', '/claims/submit', array(
            array(
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => array( $this, 'submit_claim' ),
                'permission_callback' => function() { return is_user_logged_in(); },
            ),
        ) );

        // Customer: Get their own claims
        register_rest_route( 'shippingguard/v1', '/claims/my', array(
            array(
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => array( $this, 'get_my_claims' ),
                'permission_callback' => function() { return is_user_logged_in(); },
            ),
        ) );
    }

    public function get_claims( $request ) {
        global $wpdb;
        $table = esc_sql( $wpdb->prefix . 'shippingguard_claims' );

        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- table string constructed securely via esc_sql. Direct query needed.
        $claims_results = $wpdb->get_results( "SELECT * FROM {$table} ORDER BY created_at DESC" );

        $claims = array();
        $stats  = array(
            'total'    => 0,
            'approved' => 0,
            'rejected' => 0,
            'pending'  => 0,
        );

        foreach ( $claims_results as $claim ) {
            $order    = wc_get_order( $claim->order_id );
            $customer = get_userdata( $claim->customer_id );

            $claims[] = array(
                'id'            => (int) $claim->id,
                'order_id'      => (int) $claim->order_id,
                'order_number'  => $order ? $order->get_order_number() : '#' . $claim->order_id,
                'customer'      => $customer ? $customer->display_name . ' (' . $customer->user_email . ')' : 'Guest',
                'reason'        => $claim->reason,
                'status'        => $claim->status,
                'photo_url'     => $claim->attachment_id ? wp_get_attachment_url( $claim->attachment_id ) : null,
                'created_at'    => $claim->created_at,
            );

            $stats['total']++;
            $status_key = strtolower( $claim->status );
            if ( isset( $stats[ $status_key ] ) ) {
                $stats[ $status_key ]++;
            }
        }

        return rest_ensure_response( array(
            'claims' => $claims,
            'stats'  => $stats,
        ) );
    }

    public function update_claim( $request ) {
        global $wpdb;
        $table  = esc_sql( $wpdb->prefix . 'shippingguard_claims' );
        $id     = (int) $request['id'];
        $params = $request->get_json_params();

        $allowed_statuses = array( 'Pending', 'Approved', 'Rejected', 'Refunded' );
        $status = isset( $params['status'] ) ? sanitize_text_field( $params['status'] ) : null;

        if ( ! $status || ! in_array( $status, $allowed_statuses, true ) ) {
            return new WP_Error( 'invalid_status', 'Invalid status value.', array( 'status' => 400 ) );
        }
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Direct updates handled manually.
        $wpdb->update(
            $table,
            array( 'status' => $status ),
            array( 'id'     => $id ),
            array( '%s' ),
            array( '%d' )
        );

        return rest_ensure_response( array( 'success' => true ) );
    }

    public function submit_claim( $request ) {
        global $wpdb;
        $table  = esc_sql( $wpdb->prefix . 'shippingguard_claims' );
        
        $order_id = $request->get_param('order_id');
        $reason   = $request->get_param('reason');

        if ( ! $order_id || ! $reason ) {
            return new WP_Error( 'invalid_data', 'Order ID and reason are required.', array( 'status' => 400 ) );
        }

        $order = wc_get_order( $order_id );
        if ( ! $order ) {
            return new WP_Error( 'invalid_order', 'Order not found.', array( 'status' => 404 ) );
        }

        // Verify ownership
        if ( (int) $order->get_customer_id() !== get_current_user_id() ) {
            return new WP_Error( 'forbidden', 'You cannot claim on this order.', array( 'status' => 403 ) );
        }

        // Check protection was enabled
        global $wpdb;
        $table_orders = esc_sql( $wpdb->prefix . 'shippingguard_orders' );
        $order_id_safe = absint( $order_id );
        
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Custom table query for order protection status.
        $is_protected = $wpdb->get_var( $wpdb->prepare(
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name interpolation is safe with esc_sql.
            "SELECT is_protected FROM $table_orders WHERE order_id = %d",
            $order_id_safe
        ) );

        if ( ! $is_protected ) {
            return new WP_Error( 'not_protected', 'This order does not have shipping protection.', array( 'status' => 400 ) );
        }

        // Duplicate check
        $table    = esc_sql( $wpdb->prefix . 'shippingguard_claims' );
        $order_id = absint( $request->get_param( 'order_id' ) );
        
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- securely constructed query.
        $existing = $wpdb->get_var( $wpdb->prepare(
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
            "SELECT id FROM {$table} WHERE order_id = %d AND customer_id = %d LIMIT 1",
            $order_id, get_current_user_id()
        ) );
        if ( $existing ) {
            return new WP_Error( 'duplicate_claim', 'A claim already exists for this order.', array( 'status' => 400 ) );
        }

        // Handle File Upload
        $attachment_id = 0;
        $files = $request->get_file_params();
        if ( ! empty( $files['photo'] ) ) {
            require_once ABSPATH . 'wp-admin/includes/image.php';
            require_once ABSPATH . 'wp-admin/includes/file.php';
            require_once ABSPATH . 'wp-admin/includes/media.php';

            $attachment_id = media_handle_upload( 'photo', 0 );
            if ( is_wp_error( $attachment_id ) ) {
                return $attachment_id;
            }
        }

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- Insert needed directly over WP functions.
        $wpdb->insert(
            $table,
            array(
                'order_id'      => $order_id,
                'customer_id'   => get_current_user_id(),
                'reason'        => $reason,
                'status'        => 'Pending',
                'attachment_id' => $attachment_id,
                'created_at'    => current_time( 'mysql' ),
            ),
            array( '%d', '%d', '%s', '%s', '%d', '%s' )
        );

        $claim_id = $wpdb->insert_id;
        ShippingGuard_Emails::send_admin_claim_notification( $claim_id, $order_id, $reason );

        return rest_ensure_response( array( 'success' => true, 'claim_id' => $claim_id ) );
    }

    public function get_my_claims( $request ) {
        global $wpdb;
        $table       = esc_sql( $wpdb->prefix . 'shippingguard_claims' );
        $customer_id = get_current_user_id();

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Direct fetch needed.
        $claims = $wpdb->get_results( $wpdb->prepare(
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
            "SELECT * FROM {$table} WHERE customer_id = %d ORDER BY created_at DESC",
            $customer_id
        ) );

        $result = array();
        foreach ( $claims as $claim ) {
            $order = wc_get_order( $claim->order_id );
            $result[] = array(
                'id'           => (int) $claim->id,
                'order_id'     => (int) $claim->order_id,
                'order_number' => $order ? $order->get_order_number() : '#' . $claim->order_id,
                'reason'       => $claim->reason,
                'status'       => $claim->status,
                'photo_url'    => $claim->attachment_id ? wp_get_attachment_url( $claim->attachment_id ) : null,
                'created_at'   => $claim->created_at,
            );
        }

        return rest_ensure_response( $result );
    }
}
