<?php
if (!defined('ABSPATH'))
exit; // Exit if accessed directly
class DevsAccounting_Contact{
    public function __construct()
    {
        add_action('rest_api_init', [$this, 'contact_api_endpoint']);
    }

    // Define your custom endpoint
    public function contact_api_endpoint() {
        register_rest_route('devs-accounting/v1', '/add-contact', array(
            'methods' => 'POST', 
            'callback' => [$this, 'save_contact_data'],
            'permission_callback' => [$this, 'verify_contact_nonce'],
        ));

        register_rest_route('devs-accounting/v1', '/contacts', array(
            'methods' => 'get',
            'callback' => [$this, 'get_contacts'],
            'permission_callback' => [$this, 'verify_contact_nonce'],
        ));

        register_rest_route('devs-accounting/v1', '/get-customer', array(
            'methods' => 'get',
            'callback' => [$this, 'get_customer'],
            'permission_callback' => function () {
                return true;
            },
        ));


        register_rest_route('devs-accounting/v1', '/get-contact/(?P<id>\d+)', array(
            'methods' => 'get', 
            'callback' => [$this, 'get_single_contact'],
            'permission_callback' => function () {
                return true;
            },
        ));
        
        register_rest_route('devs-accounting/v1', '/delete-contact/(?P<id>\d+)', array(
            'methods' => 'get',
            'callback' => [$this, 'delete_single_contact'],
            'permission_callback' => [$this, 'verify_contact_nonce'],
        ));

        register_rest_route('devs-accounting/v1', '/contacts-export', array(
            'methods' => 'GET',
            'callback' => [$this, 'export_contacts'],
            'permission_callback' => [$this, 'verify_contact_nonce'],
        ));

        register_rest_route('devs-accounting/v1', '/import-contacts', array(
            'methods'             => 'POST',
            'callback'            => [$this, 'import_contacts'],
            'permission_callback' => [$this, 'verify_contact_nonce'],
        ));
        
        register_rest_route('devs-accounting/v1', '/sample-contacts', [
            'methods'  => 'GET',
            'callback' => [$this, 'download_sample_contacts'],
            'permission_callback' => '__return_true',
        ]);
        
    }

    function verify_contact_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 get_contacts( $request ) 
	{
		global $wpdb;

		$table_name = $wpdb->prefix . 'dac_contacts';

		$page     = isset( $request['page'] ) && is_numeric( $request['page'] ) ? max( 1, intval( $request['page'] ) ) : 1;
		$per_page = isset( $request['per_page'] ) && is_numeric( $request['per_page'] ) ? max( 1, intval( $request['per_page'] ) ) : 10;

		$search = isset( $request['search'] ) ? sanitize_text_field( $request['search'] ) : '';

		$offset = ( $page - 1 ) * $per_page;

		$params   = [];
		$where_sql = 'WHERE deleted_at IS NULL';

		if ( ! empty( $search ) ) {
			$where_sql .= ' AND (name LIKE %s OR email LIKE %s OR type LIKE %s OR phone LIKE %s)';
			$like      = '%' . $wpdb->esc_like( $search ) . '%';
			$params    = [ $like, $like, $like, $like ];
		}

		// Add LIMIT/OFFSET
		$params = array_merge( $params, [ $per_page, $offset ] );

		$sql = $wpdb->prepare(
			"SELECT * FROM $table_name $where_sql ORDER BY id DESC LIMIT %d OFFSET %d",
			$params
		);
		$results = $wpdb->get_results( $sql );

		// Total contacts
		$count_params = ! empty( $search ) ? [ $like, $like, $like, $like ] : [];
		$count_sql = ! empty( $count_params )
			? $wpdb->prepare( "SELECT COUNT(*) FROM $table_name $where_sql", $count_params )
			: "SELECT COUNT(*) FROM $table_name $where_sql";

		$total_contact = $wpdb->get_var( $count_sql );

		if ( $results === null || $total_contact === null ) {
			return new WP_Error( 'db_query_error', 'Error retrieving contacts from the database.', [ 'status' => 500 ] );
		}

		foreach ( $results as &$contact ) {
			$contact->folder_name = DEVSACCOUNTING_PLUGIN_FOLDER_NAME;
		}

		$response = [
			'data'          => $results,
			'total_contact' => intval( $total_contact ),
			'total_pages'   => ceil( $total_contact / $per_page ),
			'current_page'  => $page,
			'per_page'      => $per_page,
		];

		return rest_ensure_response( $response );
	}

    

    public function get_customer($request) {
        global $wpdb;
    
        $table_name = $wpdb->prefix . 'dac_contacts';
    
        $page = isset($request['page']) ? max(1, intval($request['page'])) : 1;
        $per_page = isset($request['per_page']) ? max(1, intval($request['per_page'])) : 10;
        $type = isset($request['type']) ? sanitize_text_field($request['type']) : '';
        $search = isset($request['search']) ? sanitize_text_field($request['search']) : '';
    
        $offset = ($page - 1) * $per_page;
    
        $search_condition = '';
        $search_param = [];
        if (!empty($search)) {
            $search_condition = "AND (name LIKE %s OR email LIKE %s OR type LIKE %s OR phone LIKE %s)";
            $search_param = [
                '%' . $wpdb->esc_like($search) . '%',
                '%' . $wpdb->esc_like($search) . '%',
                '%' . $wpdb->esc_like($search) . '%',
                '%' . $wpdb->esc_like($search) . '%',
            ];
        }
    
        $type_condition = '';
        $type_param = [];
        if (!empty($type)) {
            $type_condition = "AND type = %s";
            $type_param[] = $type;
        }
    
        $query = "
            SELECT * FROM $table_name 
            WHERE deleted_at IS NULL 
            $type_condition 
            $search_condition 
            ORDER BY id DESC 
            LIMIT %d OFFSET %d
        ";
    
        $results = $wpdb->get_results(
            $wpdb->prepare($query, array_merge($type_param, $search_param, [$per_page, $offset]))
        );
    
        $count_query = "
            SELECT COUNT(*) FROM $table_name 
            WHERE deleted_at IS NULL 
            $type_condition 
            $search_condition
        ";
    
        $total = $wpdb->get_var(
            $wpdb->prepare($count_query, array_merge($type_param, $search_param))
        );
    
        if ($results === null || $total === null) {
            return new WP_Error('db_query_error', 'Error retrieving contacts.', ['status' => 500]);
        }
    
        return rest_ensure_response([
            'data' => $results,
            'folder_name' => DEVSACCOUNTING_PLUGIN_FOLDER_NAME, 
            'total_contact' => intval($total),
            'total_pages' => ceil($total / $per_page),
            'current_page' => $page,
            'per_page' => $per_page,
        ]);
    }
    
    
    

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

        $table_name = $wpdb->prefix . 'dac_contacts';
        $contact_id = $request['id'];

        $contact = $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM $table_name WHERE ID = %d",
            $contact_id
        ) );

        if ( $contact ) {
            return rest_ensure_response( $contact );
        } else {
            return new WP_Error( 'task_not_found', esc_html__( 'Task not found', 'devs-accounting' ), array( 'status' => 404 ) );
        }
    }    
    
    public function delete_single_contact($request) {
        global $wpdb;

        $table_name = $wpdb->prefix . 'dac_contacts';

        $contact_id = isset($request['id']) ? intval($request['id']) : 0;

        if ($contact_id <= 0) {
            return new WP_Error( 'invalid_item_id', esc_html__( 'Invalid item ID', 'devs-accounting' ), array( 'status' => 400 ) );
        }

        $existing_contact = $wpdb->get_row(
            $wpdb->prepare(
                "SELECT * FROM $table_name WHERE ID = %d",
                $contact_id
            )
        );

        if (!$existing_contact) {
            return new WP_Error( 'item_not_found', esc_html__( 'Item not found', 'devs-accounting' ), array( 'status' => 404 ) );
        }

        $current_time = gmdate('Y-m-d H:i:s'); 

        $result = $wpdb->update(
            $table_name,
            array( 
                'deleted_at' => $current_time,
                ),
            array( 'id' => $contact_id ),
        );
    
        if ($result === false) {
            return new WP_Error( 'soft_delete_failed', esc_html__( 'Failed to soft delete item', 'devs-accounting' ), array( 'status' => 500 ) );
        }

        return rest_ensure_response( array( 'message' => esc_html__('Item soft deleted successfully', 'devs-accounting') ) );
    }



    public function save_contact_data($request) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'dac_contacts';

        $name    = sanitize_text_field($request['name']);
        $type    = sanitize_text_field($request['type']);
        $email   = sanitize_email($request['email']);
        $address = sanitize_text_field($request['address']);
        $phone   = sanitize_text_field($request['phone']);
        $country = sanitize_text_field($request['country']);
        $states  = sanitize_text_field($request['states']);

        $errors = array();

        if (empty($name)) {
            $errors['name'] = esc_html__('Contact name is required.', 'devs-accounting');
        }
        if (empty($type)) {
            $errors['type'] = esc_html__('Contact type is required.', 'devs-accounting');
        }

        if (!empty($errors)) {
            return new WP_REST_Response([
                'message' => esc_html__('Validation errors occurred.', 'devs-accounting'),
                'errors'  => $errors,
            ], 400);
        }

        // Check if contact with same email already exists
        $existing_contact = null;
        if (!empty($email)) {
            $existing_contact = $wpdb->get_row(
                $wpdb->prepare("SELECT * FROM $table_name WHERE email = %s AND type = %s AND deleted_at IS NULL", $email, $type)
            );
        }

        $insert_data = [
            'name'    => $name,
            'type'    => $type,
            'email'   => $email,
            'address' => $address,
            'phone'   => $phone,
            'states'  => $states,
            'country' => $country,
        ];

        if ($existing_contact) {
            // Update existing contact
            $wpdb->update($table_name, $insert_data, ['id' => $existing_contact->id]);
            $contact = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table_name WHERE id = %d", $existing_contact->id));
            $response = [
                'message' => esc_html__('Contact updated successfully!', 'devs-accounting'),
                'data'    => $contact,
            ];
        } else {
            // Insert new contact
            $wpdb->insert($table_name, $insert_data);
            $insert_id = $wpdb->insert_id;
            $contact = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table_name WHERE id = %d", $insert_id));
            $response = [
                'message' => esc_html__('Contact created successfully!', 'devs-accounting'),
                'data'    => $contact,
            ];
        }

        return new WP_REST_Response($response, 200);
    }


    public function export_contacts($request) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'dac_contacts';
        
        $allowed_table = $wpdb->prefix . 'dac_contacts';
if ($table_name !== $allowed_table) {
    return new WP_Error('invalid_table', __('Invalid table name.', 'devs-accounting'), array('status' => 400));
}
$results = $wpdb->get_results("SELECT type, name, email, tax_number, address, phone, country, states  FROM $table_name WHERE deleted_at IS NULL", ARRAY_A);
        
        if (empty($results)) {
            return new WP_Error('no_contacts', __('No contacts found for export.', 'devs-accounting'), array('status' => 404));
        }
        
        $header = array_keys($results[0]);
        $header = array_filter($header, fn($key) => !empty($key));
        
        $filename = 'contacts_export_' . date('Ymd_His') . '.csv';
        
        header('Content-Type: text/csv; charset=utf-8');
        header("Content-Disposition: attachment; filename={$filename}");
        
        $output = fopen('php://output', 'w');
        
        fputcsv($output, $header);
        
     
        foreach ($results as $row) {
            $row_data = array_intersect_key($row, array_flip($header));
            fputcsv($output, $row_data);
        }
        
        fclose($output);
        exit;
    }
    
    public function import_contacts() {
        global $wpdb;
        $table_name = $wpdb->prefix . 'dac_contacts';
    
        if (empty($_FILES['file'])) {
            return new WP_REST_Response([
                'success' => false,
                'message' => 'No file uploaded.',
            ], 400);
        }
    
        $file = $_FILES['file'];
    
        if ($file['error'] !== UPLOAD_ERR_OK) {
            return new WP_REST_Response([
                'success' => false,
                'message' => 'File upload error.',
            ], 400);
        }
    
        $csv_data = file_get_contents($file['tmp_name']);
        
        $csv_data = preg_replace('/^\xEF\xBB\xBF/', '', $csv_data);
    
        $rows = array_map('str_getcsv', preg_split('/\r\n|\n|\r/', $csv_data));
    
        if (empty($rows) || count($rows) < 2) {
            return new WP_REST_Response([
                'success' => false,
                'message' => 'Empty or invalid CSV file.',
            ], 400);
        }
    
        $header = array_map('sanitize_text_field', array_shift($rows));
    
        $idIndex = array_search('id', $header);
        if ($idIndex !== false) {
            unset($header[$idIndex]);
            $header = array_values($header);
        }
    
        $imported = 0;
    
        foreach ($rows as $row) {
            // Skip empty rows
            if (!is_array($row) || count(array_filter($row)) === 0) {
                continue;
            }
    
            if ($idIndex !== false && isset($row[$idIndex])) {
                unset($row[$idIndex]);
                $row = array_values($row);
            }
    
            $row = array_pad($row, count($header), '');
    
            $data = array_combine($header, array_slice($row, 0, count($header)));
            if (!$data) {
                continue;
            }
    
            $name = sanitize_text_field($data['name'] ?? '');
            $type = sanitize_text_field($data['type'] ?? '');
    
            if (empty($name) || empty($type)) {
                error_log('Skipping row because name or type missing: ' . print_r($data, true));
                continue;
            }
    
            $inserted = $wpdb->insert($table_name, [
                'name'        => sanitize_text_field($data['name'] ?? ''),
                'type'        => sanitize_text_field($data['type'] ?? ''),
                'email'       => sanitize_email($data['email'] ?? ''),
                'tax_number'  => sanitize_text_field($data['tax_number'] ?? ''),
                'address'     => sanitize_text_field($data['address'] ?? ''),
                'phone'       => sanitize_text_field($data['phone'] ?? ''),
                'country'     => sanitize_text_field($data['country'] ?? ''),
                'states'      => sanitize_text_field($data['states'] ?? ''),
            ]);
    
            if (!$inserted) {
                error_log('Failed to insert row: ' . $wpdb->last_error);
            } else {
                $imported++;
            }
        }
    
        $status = $imported > 0 ? 200 : 400;
        $success = $imported > 0;
        $message = $imported > 0
            ? "$imported contacts imported successfully."
            : 'No contacts were imported.';
    
        return new WP_REST_Response([
            'success' => $success,
            'message' => $message,
        ], $status);
    }
    
    
    
    
    
    
    
    public function download_sample_contacts() {
        $headers = ['type', 'name', 'email', 'tax_number', 'address', 'phone', 'country', 'states'];
        $filename = 'sample_contacts_import.csv';
    
        header('Content-Type: text/csv; charset=utf-8');
        header("Content-Disposition: attachment; filename={$filename}");
    
        $output = fopen('php://output', 'w');
    
        fwrite($output, chr(239) . chr(187) . chr(191));
    
        fputcsv($output, $headers);
    
        fclose($output);
        exit;
    }
    
}

$contacts = new DevsAccounting_Contact(); 