<?php
/**
 * Class Cookie_Controller file.
 *
 * @package WebToffee
 */

namespace WebToffee\CookieConsent\Lite\Admin\Modules\Cookies\Includes;

use WebToffee\CookieConsent\Lite\Includes\Base_Controller;
use WebToffee\CookieConsent\Lite\Includes\Filesystem;
use WebToffee\CookieConsent\Lite\Includes\Cache;
use stdClass;
use Exception;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

/**
 * Handles Cookies Operation
 *
 * @class       Cookie_Controller
 * @version     3.0.0
 * @package     WebToffee
 */
class Cookie_Controller extends Base_Controller {

	/**
	 * Instance of the current class
	 *
	 * @var object
	 */
	private static $instance;

	/**
	 * Cache group
	 *
	 * @var array
	 */
	protected $cache_group = 'cookies';

	/**
	 * Table versioning option name.
	 *
	 * @var string
	 */
	protected $table_option = 'cookie';

	/**
	 * Cateogory identifier key.
	 *
	 * @var string
	 */
	protected $id = 'cookie_id';

	/**
	 * API path for cookies.
	 *
	 * @var string
	 */
	protected $path = 'cookies';

	/**
	 * Return the current instance of the class
	 *
	 * @return object
	 */
	public static function get_instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Return a list of Cookies tables
	 *
	 * @return array Cookies tables.
	 */
	protected function get_tables() {
		global $wpdb;
		$tables = array(
			"{$wpdb->prefix}wcc_cookies",
		);
		return $tables;
	}

	/**
	 * Load default banner
	 *
	 * @return void
	 */
	protected function load_default() {
	}

	/**
	 * Get table schema
	 *
	 * @return string
	 */
	protected function get_schema() {
		global $wpdb;

		$collate = '';

		if ( $wpdb->has_cap( 'collation' ) ) {
			$collate = $wpdb->get_charset_collate();
		}

		$tables = "
        CREATE TABLE {$wpdb->prefix}wcc_cookies (
			cookie_id bigint(20) NOT NULL AUTO_INCREMENT,
			name varchar(190) NOT NULL DEFAULT '',
			slug varchar(190) NOT NULL DEFAULT '',
			description longtext NOT NULL,
			duration text NOT NULL,
			domain varchar(190) NOT NULL DEFAULT '',
			category bigint(20) NOT NULL,
			type text NOT NULL,
			discovered int(11) NOT NULL default 0,
			url_pattern varchar(190) NULL default '',
			meta longtext,
			cookie_status  int(11) NOT NULL default 0,
			date_created datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
			date_modified datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
			PRIMARY KEY  (cookie_id)
        ) $collate;
	";
		return $tables;
	}

	/**
	 * Get a list of banners from localhost.
	 *
	 * @param array $args Array of arguments.
	 * @return array
	 */
	public function get_item_from_db( $args = array() ) {

		global $wpdb;
		$items = array();
		if ( false === $this->table_exist() ) {
			return $items;
		}

		if ( isset( $args['id'] ) && '' !== $args['id'] ) {
			$results = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM `{$wpdb->prefix}wcc_cookies` WHERE `cookie_id` = %d", stripslashes( absint( $args['id'] ) ) ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
		} elseif ( isset( $args['category'] ) && '' !== $args['category'] ) {
			$results = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `{$wpdb->prefix}wcc_cookies` WHERE `category` = %d", stripslashes( absint( $args['category'] ) ) ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
		} else {
			$results = $wpdb->get_results( "SELECT * FROM `{$wpdb->prefix}wcc_cookies`" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
		}

		if ( isset( $results ) && ! empty( $results ) ) {
			if ( true === is_array( $results ) ) {
				foreach ( $results as $data ) {
					$item = $this->prepare_item( $data );
					if ( ! empty( $item ) ) {
						$items[ $item->{$this->id} ] = $item;
						wp_cache_set( $this->cache_group . '_' . $item->{$this->id}, $item, $this->cache_group );
					}
				}
			} else {
				$items = $this->prepare_item( $results );
				wp_cache_set( $this->cache_group . '_' . $items->{$this->id}, $items, $this->cache_group );
			}
		}
		return $items;
	}

	/**
	 * Get a single item.
	 *
	 * @param integer $id Item ID.
	 * @return array|object
	 */
	public function get_item( $id ) {
		if ( ! $id ) {
			return array();
		}
		$cache_key = $this->cache_group . '_' . $id;
		$cached    = wp_cache_get( $cache_key, $this->cache_group );
		if ( false !== $cached ) {
			return $cached;
		}
		$item = $this->get_item_from_db( array( 'id' => $id ) );
		return $item;
	}

	/**
	 * Get cookies based on the category.
	 *
	 * @param boolean|integer $category Category id.
	 * @return array
	 */
	public function get_items_by_category( $category = false ) {
		if ( ! $category ) {
			return array();
		}
		$cache_key = $this->cache_group . '_category_' . $category;
		$cached    = wp_cache_get( $cache_key, $this->cache_group );
		if ( false !== $cached ) {
			return $cached;
		}
		$items = $this->get_item_from_db( array( 'category' => $category ) );
		wp_cache_set( $cache_key, $items, $this->cache_group );
		return $items;
	}

	/**
	 * Create a new category
	 *
	 * @param object $cookie Category object.
	 * @return void
	 */
	public function create_item( $cookie ) {
		global $wpdb;
		$date_created = current_time( 'mysql' );
		$cookie->set_date_created( $date_created );
		$cookie->set_date_modified( $date_created );

		$wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery
			$wpdb->prefix . 'wcc_cookies',
			array(
				'name'          => $cookie->get_name(),
				'slug'          => $cookie->get_slug(),
				'description'   => wp_json_encode( $cookie->get_description() ),
				'duration'      => wp_json_encode( $cookie->get_duration() ),
				'domain'        => $cookie->get_domain(),
				'category'      => $cookie->get_category(),
				'type'          => $cookie->get_type(),
				'discovered'    => ( true === $cookie->is_discovered() ? 1 : 0 ),
				'url_pattern'   => $cookie->get_url_pattern(),
				'meta'          => wp_json_encode( $cookie->get_meta() ),
				'cookie_status' => ( true === $cookie->get_cookie_status() ? 1 : 0 ),
				'date_created'  => $cookie->get_date_created(),
				'date_modified' => $cookie->get_date_modified(),
			),
			array(
				'%s',
				'%s',
				'%s',
				'%s',
				'%s',
				'%s',
				'%s',
				'%d',
				'%s',
				'%s',
				'%d',
				'%s',
				'%s',
			)
		);
		$cookie->set_id( $wpdb->insert_id );
		do_action( 'wcc_after_update_cookie' );
	}

	/**
	 * Update an existing category on a local db.
	 *
	 * @param object $cookie category object.
	 * @return void
	 */
	public function update_item( $cookie ) {
		global $wpdb;
		$wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery
			$wpdb->prefix . 'wcc_cookies',
			array(
				'slug'          => $cookie->get_slug(),
				'description'   => wp_json_encode( $cookie->get_description() ),
				'duration'      => wp_json_encode( $cookie->get_duration() ),
				'domain'        => $cookie->get_domain(),
				'category'      => $cookie->get_category(),
				'type'          => $cookie->get_type(),
				'discovered'    => ( true === $cookie->is_discovered() ? 1 : 0 ),
				'url_pattern'   => $cookie->get_url_pattern(),
				'meta'          => wp_json_encode( $cookie->get_meta() ),
				'cookie_status' => ( true === $cookie->get_cookie_status() ? 1 : 0 ),
				'date_created'  => $cookie->get_date_created(),
				'date_modified' => $cookie->get_date_modified(),
				'name'          => $cookie->get_name(),
			),
			array( 'cookie_id' => $cookie->get_id() ), // Use cookie id to find the existing cookie
			array(
				'%s',
				'%s',
				'%s',
				'%s',
				'%s',
				'%s',
				'%d',
				'%s',
				'%s',
				'%d',
				'%s',
				'%s',
				'%s',
			)
		);
		do_action( 'wcc_after_update_cookie' );
	}


	/**
	 * Delete a cookie from the database.
	 *
	 * @param object $cookie Cookie object.
	 * @return void
	 */
	public function delete_item( $cookie ) {
		global $wpdb;
		$wpdb->delete( // phpcs:ignore WordPress.DB.DirectDatabaseQuery
			$wpdb->prefix . 'wcc_cookies',
			array(
				'cookie_id' => $cookie->get_id(),
			)
		);
		do_action( 'wcc_after_update_cookie' );
	}

	/**
	 * Properly sanitize category data before sending to the controllers.
	 *
	 * @param object $item Category raw data.
	 * @return object
	 */
	public function prepare_item( $item ) {

		if ( false === is_object( $item ) ) {
			return false;
		}
		$object                = new stdClass();
		$object->cookie_id     = isset( $item->cookie_id ) ? absint( $item->cookie_id ) : 0;
		$object->name          = isset( $item->name ) ? sanitize_text_field( $item->name ) : '';
		$object->slug          = isset( $item->slug ) ? sanitize_text_field( $item->slug ) : '';
		$object->description   = isset( $item->description ) ? wcc_sanitize_content( $this->prepare_json( $item->description ) ) : array();
		$object->duration      = isset( $item->duration ) ? wcc_sanitize_content( $this->prepare_json( $item->duration ) ) : array();
		$object->domain        = isset( $item->domain ) ? sanitize_text_field( $item->domain ) : '';
		$object->category      = isset( $item->category ) ? absint( $item->category ) : '';
		$object->type          = isset( $item->type ) ? sanitize_text_field( $item->type ) : '';
		$object->discovered    = isset( $item->discovered ) ? absint( $item->discovered ) : 0;
		$object->url_pattern   = isset( $item->url_pattern ) ? sanitize_textarea_field( $item->url_pattern ) : '';
		$object->meta          = isset( $item->meta ) ? wcc_sanitize_content( $this->prepare_json( $item->meta ) ) : array();
		$object->cookie_status = isset( $item->cookie_status ) ? absint( $item->cookie_status ) : 0;
		$object->date_created  = isset( $item->date_created ) ? sanitize_text_field( $item->date_created ) : '';
		$object->date_modified = isset( $item->date_modified ) ? sanitize_text_field( $item->date_modified ) : '';
		return $object;
	}
	/**
	 * Export cookies data to a CSV file.
	 *
	 * @since 3.3.0
	 * @return array
	 */
	public function export() {
		global $wpdb;

		// Table name
		$table_name = $wpdb->prefix . 'wcc_cookies';

		// Query to get the data
		$results = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM %i", $table_name ), ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery

		// Check if any rows exist
		if ( empty( $results ) ) {
			wp_die( 'No data found in the table to export.' );
		}

		$uploads_dir    = Filesystem::get_instance()->get_uploads_dir( 'webtoffee' );
		$date_timestamp = wp_date( 'Y-m-d' ) . '_' . strtotime( wp_date( 'Y-m-d H:i:s' ) );
		// Format the timestamp for the file name

		// Custom column headers
		$csv_filename = "wtcookie_list_$date_timestamp.csv";
		$csv_path     = $uploads_dir['path'] . $csv_filename;
		if ( ! is_dir( $uploads_dir['path'] ) ) {
			wp_mkdir_p( $uploads_dir['path'] );
		}

		// Get headers (column names) from the first row
		$headers = array_keys( $results[0] );
		
		// Initialize WP_Filesystem
		global $wp_filesystem;
		if ( empty( $wp_filesystem ) ) {
			require_once ABSPATH . '/wp-admin/includes/file.php';
			WP_Filesystem();
		}
		
		// Build CSV content
		$csv_content = '';
		
		// Add CSV headers
		$csv_content .= implode( ',', array_map( function( $header ) {
			return '"' . str_replace( '"', '""', $header ) . '"';
		}, $headers ) ) . "\n";
		
		// Add CSV data rows
		foreach ( $results as $row ) {
			$csv_content .= implode( ',', array_map( function( $value ) {
				return '"' . str_replace( '"', '""', $value ) . '"';
			}, $row ) ) . "\n";
		}
		
		// Write CSV content to file using WP_Filesystem
		$wp_filesystem->put_contents( $csv_path, $csv_content );
		return array(
			'csv_url'   => $uploads_dir['url'] . $csv_filename,
			'file_name' => $csv_filename,
		);
	}

	/**
	 * Import cookies data from a CSV file.
	 *
	 * @since 3.3.0
	 * @return array
	 */
	function import_cookies() {
		// Check if file was uploaded
		if ( ! isset( $_FILES['file'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
			return array(
				'success' => false,
				'message' => __( 'No file was uploaded.', 'webtoffee-cookie-consent' ),
			);
		}

		$file = $_FILES['file']; // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

		// Basic validation
		if ( $file['error'] !== UPLOAD_ERR_OK ) {
			return array(
				'success' => false,
				'message' => sprintf(
					/* translators: %s: file upload error code */
					__( 'File upload failed with error: %s', 'webtoffee-cookie-consent' ),
					$file['error']
				),
			);
		}

		$csv_file_path = $file['tmp_name'];

		// Check file exists and is readable
		if ( ! file_exists( $csv_file_path ) || ! is_readable( $csv_file_path ) ) {
			return array(
				'success' => false,
				'message' => __( 'Uploaded file is not accessible.', 'webtoffee-cookie-consent' ),
			);
		}

		// Single file type validation using wp_check_filetype
		$file_type = wp_check_filetype( $file['name'] );
		$valid_csv = ( $file_type['ext'] === 'csv' && $file['type'] === 'text/csv' );

		if ( ! $valid_csv ) {
			return array(
				'success' => false,
				'message' => __( 'Invalid file type. Please upload a CSV file.', 'webtoffee-cookie-consent' ),
			);
		}

		// Process CSV file
		// Initialize WP_Filesystem
		global $wp_filesystem;
		if ( empty( $wp_filesystem ) ) {
			require_once ABSPATH . '/wp-admin/includes/file.php';
			WP_Filesystem();
		}
		
		if ( $wp_filesystem->exists( $csv_file_path ) ) {
			$csv_content = $wp_filesystem->get_contents( $csv_file_path );
			$lines = explode( "\n", $csv_content );
			
			// Get header from first line
			$header = str_getcsv( $lines[0] );
			$expected_headers = array(
				'cookie_id',
				'name',
				'slug',
				'description',
				'duration',
				'domain',
				'category',
				'type',
				'discovered',
				'url_pattern',
				'meta',
				'cookie_status',
				'date_created',
				'date_modified',
			);

			// Validate headers
			if ( $header !== $expected_headers ) {
				return array(
					'success' => false,
					'message' => __( 'CSV headers do not match expected format.', 'webtoffee-cookie-consent' ),
				);
			}

			$success_count = 0;
			$error_count   = 0;

			$rows_count = count( $lines );
			// Process data rows (skip header row)
			for ( $i = 1; $i < $rows_count; $i++ ) {
				$line = trim( $lines[ $i ] );
				if ( empty( $line ) ) {
					continue; // Skip empty lines
				}
				
				$row = str_getcsv( $line );
				if ( count( $row ) !== count( $expected_headers ) ) {
					++$error_count;
					continue; // Skip malformed rows
				}
				
				try {
					list(
						$cookie_id, $name, $slug, $description, $duration, $domain,
						$category, $type, $discovered, $url_pattern,
						$meta, $cookie_status, $date_created, $date_modified
					) = $row;

					// Check for exact combination of slug, name and category
					global $wpdb;
					// phpcs:ignore WordPress.DB.DirectDatabaseQuery
					$existing_cookie = $wpdb->get_row(
						$wpdb->prepare(
							"SELECT * FROM {$wpdb->prefix}wcc_cookies 
							WHERE slug = %s 
							AND name = %s 
							AND category = %s",
							sanitize_text_field( $slug ),
							sanitize_text_field( $name ),
							sanitize_text_field( $category )
						)
					);

					if ( $existing_cookie ) {
						++$error_count;
						continue; // Skip this cookie and move to next one
					}

					$cookie = new Cookie();
					$cookie->set_name( sanitize_text_field( $name ) );
					$cookie->set_slug( sanitize_text_field( $slug ) );
					$cookie->set_description( json_decode( $description, true ) );
					$cookie->set_duration( json_decode( $duration, true ) );
					$cookie->set_domain( sanitize_text_field( $domain ) );
					$cookie->set_category( sanitize_text_field( $category ) );
					$cookie->set_type( sanitize_text_field( $type ) );
					$cookie->set_discovered( filter_var( $discovered, FILTER_VALIDATE_BOOLEAN ) );
					$cookie->set_url_pattern( sanitize_text_field( $url_pattern ) );
					$cookie->set_meta( json_decode( $meta, true ) );
					$cookie->set_cookie_status( filter_var( $cookie_status, FILTER_VALIDATE_BOOLEAN ) );
					$this->create_item( $cookie );
					++$success_count;
				} catch ( Exception $e ) {
					++$error_count;
				}
			}

			return array(
				'success' => true,
				'message' => sprintf(
					/* translators: %1$s: number of successful imports, %2$s: number of failed imports */
					__( '%1$s cookies imported successfully, %2$s rows failed.', 'webtoffee-cookie-consent' ),
					$success_count,
					$error_count
				),
			);
		}

		return array(
			'success' => false,
			'message' => __( 'Failed to open CSV file.', 'webtoffee-cookie-consent' ),
		);
	}


	/**
	 * Decode a JSON string if necessary
	 *
	 * @param string $data String data.
	 * @return array
	 */
	public function prepare_json( $data ) {
		return is_string( $data ) ? json_decode( ( $data ), true ) : $data;
	}
}
