<?php
if (!defined('ABSPATH')) exit;

class DevsAccounting_Taxes {
    private $settings;

    public function __construct() {
        $this->settings = new DevsAccounting_Setting();
        add_action('rest_api_init', [$this, 'tax_api_endpoint']);
    }

    public function tax_api_endpoint() {
        register_rest_route('devs-accounting/v1', '/add-taxes', array(
            'methods' => 'POST',
            'callback' => [$this, 'save_tax_data'],
            'permission_callback' => [$this, 'verify_taxes_nonce'],
        ));

        register_rest_route('devs-accounting/v1', '/get-taxes', array(
            'methods' => 'GET',
            'callback' => [$this, 'get_all_taxes'],
            'permission_callback' => [$this, 'verify_taxes_nonce'],
        ));

        register_rest_route('devs-accounting/v1', '/delete-tax/(?P<tax_id>\d+)', array(
            'methods' => 'DELETE',
            'callback' => [$this, 'delete_tax_data'],
            'permission_callback' => [$this, 'verify_taxes_nonce'],
        ));

        register_rest_route('devs-accounting/v1', '/edit-tax/(?P<tax_id>\d+)', array(
            'methods' => 'PUT',
            'callback' => [$this, 'edit_tax_data'],
            'permission_callback' => [$this, 'verify_taxes_nonce'],
        ));
        register_rest_route('devs-accounting/v1', '/item-taxes', array(
            'methods' => 'POST',
            'callback' => [$this, 'item_taxes'],
            'permission_callback' => [$this, 'verify_taxes_nonce'],
        ));
        register_rest_route('devs-accounting/v1', '/get-item-tax/(?P<item_id>\d+)', array(
            'methods' => 'GET',
            'callback' => [$this, 'get_item_tax_with_settings'],
            'permission_callback' => [$this, 'verify_taxes_nonce'],
        ));

        register_rest_route('devs-accounting/v1', '/get-tax/(?P<tax_id>\d+)', array(
            'methods' => 'GET',
            'callback' => [$this, 'get_single_tax'],
            'permission_callback' => [$this, 'verify_taxes_nonce'],
        ));
        
        
    }

    public function verify_taxes_nonce($request) {
        $nonce = $request->get_header('X-WP-Nonce');
        if (!wp_verify_nonce($nonce, 'wp_rest')) {
            return new WP_Error('rest_forbidden', esc_html__('Invalid nonce.', 'devs-accounting'), array('status' => 403));
        }
        return true;
    }

    public function save_tax_data($request) {
        global $wpdb;
    
        $table = $wpdb->prefix . 'dac_taxes';
    
        $tax_name = sanitize_text_field($request['tax_name']);
        $tax_rate = floatval($request['tax_rate']);
        $tax_type = sanitize_text_field($request['tax_type']);
        $country = sanitize_text_field($request['country']);
        $states = sanitize_text_field($request['states']);
    
        // Basic validation
        if (empty($tax_name) || !is_numeric($tax_rate) || empty($tax_type)) {
            return new WP_REST_Response([
                'success' => false,
                'message' => 'Please provide valid tax_name, tax_rate, and tax_type.',
            ], 400);
        }
    
        // Check for existing tax name
        $existing = $wpdb->get_var($wpdb->prepare(
            "SELECT id FROM $table WHERE tax_name = %s", $tax_name
        ));
    
        if ($existing) {
            return new WP_REST_Response([
                'success' => false,
                'message' => 'A tax with this name already exists.',
            ], 400);
        }
    
        // Insert new tax
        $inserted = $wpdb->insert($table, [
            'tax_name'  => $tax_name,
            'tax_rate'  => $tax_rate,
            'tax_type'  => $tax_type,
            'country'   => $country,
            'states'    => $states,
        ]);
    
        if ($inserted === false) {
            return new WP_REST_Response([
                'success' => false,
                'message' => 'Failed to add tax.',
            ], 500);
        }
    
        return new WP_REST_Response([
            'success' => true,
            'message' => 'Tax added successfully.',
            'tax_id'  => $wpdb->insert_id,
        ], 200);
    }
    
    


    public function get_single_tax($request) {
        global $wpdb;
    
        $tax_id = intval($request['tax_id']);
        $table = $wpdb->prefix . 'dac_taxes';
    
        if (!$tax_id) {
            return new WP_Error('invalid_id', 'Invalid tax ID.', array('status' => 400));
        }
    
        $tax = $wpdb->get_row(
            $wpdb->prepare("SELECT * FROM $table WHERE id = %d AND deleted_at IS NULL", $tax_id),
            ARRAY_A
        );
    
        if (!$tax) {
            return new WP_Error('not_found', 'Tax not found.', array('status' => 404));
        }
    
        return rest_ensure_response([
            'success' => true,
            'data' => $tax
        ]);
    }

    
    public function get_all_taxes($request) {
        global $wpdb;

        $table = $wpdb->prefix . 'dac_taxes';

        $results = $wpdb->get_results("SELECT * FROM $table WHERE deleted_at IS NULL ORDER BY id DESC", ARRAY_A);

        if ($results === null) {
            return new WP_Error('db_error', 'Failed to retrieve taxes.', array('status' => 500));
        }

        return rest_ensure_response([
            'success' => true,
            'data' => $results
        ]);
    }

    public function delete_tax_data($request) {
        global $wpdb;

        $tax_id = $request['tax_id'];
        $table = $wpdb->prefix . 'dac_taxes';

        $tax = $wpdb->get_row($wpdb->prepare("SELECT id FROM $table WHERE id = %d AND deleted_at IS NULL", $tax_id));

        if ($tax === null) {
            return new WP_Error('not_found', 'Tax not found or already deleted.', array('status' => 404));
        }

        $deleted = $wpdb->update($table, [
            'deleted_at' => current_time('mysql') 
        ], ['id' => $tax_id]);

        if ($deleted === false) {
            return new WP_Error('db_error', 'Failed to delete tax.', array('status' => 500));
        }

        return rest_ensure_response([
            'success' => true,
            'message' => 'Tax deleted successfully.',
        ]);
    }

    public function edit_tax_data($request) {
        global $wpdb;

        $tax_id = $request['tax_id'];
        $table = $wpdb->prefix . 'dac_taxes';

        $tax_name = sanitize_text_field($request['tax_name']);
        $tax_rate = floatval($request['tax_rate']);
        $tax_type = sanitize_text_field($request['tax_type']);
        $country = sanitize_text_field($request['country']);
        $states = sanitize_text_field($request['states']);

        if (empty($tax_name) || !is_numeric($tax_rate) || empty($tax_type)) {
            return new WP_Error('invalid_input', 'Please provide valid tax_name, tax_rate, and tax_type.', array('status' => 400));
        }

        $tax = $wpdb->get_row($wpdb->prepare("SELECT id FROM $table WHERE id = %d AND deleted_at IS NULL", $tax_id));

        if ($tax === null) {
            return new WP_Error('not_found', 'Tax not found or already deleted.', array('status' => 404));
        }

        $updated = $wpdb->update($table, [
            'tax_name'  => $tax_name,
            'tax_rate'  => $tax_rate,
            'tax_type'  => $tax_type,
            'country'   => $country,
            'states'    => $states,
        ], ['id' => $tax_id]);

        if ($updated === false) {
            return new WP_Error('db_error', 'Failed to update tax.', array('status' => 500));
        }

        return rest_ensure_response([
            'success' => true,
            'message' => 'Tax updated successfully.',
        ]);
    }

    public function item_taxes($request) 
	{
		global $wpdb;

		$item_id = intval($request['item_id']);
		$tax_ids = $request['taxes'];

		if (empty($item_id) || !is_array($tax_ids)) {
			return new WP_Error(
				'invalid_input', 
				'Invalid item_id or taxes.', 
				['status' => 400]
			);
		}

		$table = esc_sql($wpdb->prefix . 'dac_item_tax');

		$wpdb->delete($table, ['item_id' => $item_id], ['%d']);

		$values = [];
		$placeholders = [];

		foreach ($tax_ids as $tax_id) {
			$values[] = $item_id;
			$values[] = intval($tax_id);
			$placeholders[] = "(%d, %d)";
		}

		if (!empty($values)) {
			$sql = "INSERT INTO {$table} (item_id, tax_id) VALUES " . implode(", ", $placeholders);

			$prepared = $wpdb->prepare($sql, ...$values);

			$result = $wpdb->query($prepared); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared

			if ($result === false) {
				return new WP_Error(
					'db_error', 
					'Failed to assign taxes.', 
					['status' => 500]
				);
			}
		}

		return rest_ensure_response([
			'success' => true,
			'message' => 'Taxes assigned to item successfully.',
		]);
	}


    public function get_item_tax_with_settings($request) 
	{
		global $wpdb;

		$item_id = intval($request['item_id']); 

		if (empty($item_id)) {
			return new WP_Error(
				'invalid_item_id',
				'Invalid item ID.',
				['status' => 400]
			);
		}

		$itemTaxTable = esc_sql($wpdb->prefix . 'dac_item_tax');
		$taxesTable = esc_sql($wpdb->prefix . 'dac_taxes');

		$sql = "
			SELECT it.*, t.* 
			FROM {$itemTaxTable} it
			JOIN {$taxesTable} t ON it.tax_id = t.id
			WHERE it.item_id = %d
		";

		$itemTaxWithTaxDetails = $wpdb->get_results($wpdb->prepare($sql, $item_id), ARRAY_A); // safe

		if (empty($itemTaxWithTaxDetails)) {
			return new WP_Error(
				'tax_not_found',
				'No tax data found for the given item ID.',
				['status' => 404]
			);
		}

		$tax_display = $this->settings->get_settings()->data['tax_display'] ?? 'total';
		$itemTaxWithTaxDetails = array_map(function($taxRow) use ($tax_display) {
			$taxRow['tax_display'] = $tax_display;
			return $taxRow;
		}, $itemTaxWithTaxDetails);

		return rest_ensure_response([
			'success' => true,
			'item_taxes' => $itemTaxWithTaxDetails,
		]);
	}

    
    
}

new DevsAccounting_Taxes();
