/*
Theme Name: Twenty Twenty-Five
Theme URI: https://wordpress.org/themes/twentytwentyfive/
Author: the WordPress team
Author URI: https://wordpress.org
Description: Twenty Twenty-Five emphasizes simplicity and adaptability. It offers flexible design options, supported by a variety of patterns for different page types, such as services and landing pages, making it ideal for building personal blogs, professional portfolios, online magazines, or business websites. Its templates cater to various blog styles, from text-focused to image-heavy layouts. Additionally, it supports international typography and diverse color palettes, ensuring accessibility and customization for users worldwide.
Requires at least: 6.7
Tested up to: 6.8
Requires PHP: 7.2
Version: 1.3
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: twentytwentyfive
Tags: one-column, custom-colors, custom-menu, custom-logo, editor-style, featured-images, full-site-editing, block-patterns, rtl-language-support, sticky-post, threaded-comments, translation-ready, wide-blocks, block-styles, style-variations, accessibility-ready, blog, portfolio, news
*/

/*
 * Link styles
 * https://github.com/WordPress/gutenberg/issues/42319
 */
a {
	text-decoration-thickness: 1px !important;
	text-underline-offset: .1em;
}

/* Focus styles */
:where(.wp-site-blocks *:focus) {
	outline-width: 2px;
	outline-style: solid;
}

/* Increase the bottom margin on submenus, so that the outline is visible. */
.wp-block-navigation .wp-block-navigation-submenu .wp-block-navigation-item:not(:last-child) {
	margin-bottom: 3px;
}

/* Increase the outline offset on the parent menu items, so that the outline does not touch the text. */
.wp-block-navigation .wp-block-navigation-item .wp-block-navigation-item__content {
	outline-offset: 4px;
}

/* Remove outline offset from the submenus, otherwise the outline is visible outside the submenu container. */
.wp-block-navigation .wp-block-navigation-item ul.wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	outline-offset: 0;
}

/*
 * Progressive enhancement to reduce widows and orphans
 * https://github.com/WordPress/gutenberg/issues/55190
 */
h1, h2, h3, h4, h5, h6, blockquote, caption, figcaption, p {
	text-wrap: pretty;
}

/*
 * Change the position of the more block on the front, by making it a block level element.
 * https://github.com/WordPress/gutenberg/issues/65934
*/
.more-link {
	display: block;
}
function create_processing_directories() {
    $upload_dir = wp_upload_dir();
    $input_dir = $upload_dir['basedir'] . '/document-input';
    $output_dir = $upload_dir['basedir'] . '/processed';
    
    if (!file_exists($input_dir)) {
        wp_mkdir_p($input_dir);
    }
    
    if (!file_exists($output_dir)) {
        wp_mkdir_p($output_dir);
    }
    
    // Create .htaccess to allow file access
    $htaccess_content = "Options -Indexes\n<Files *.csv>\n    Allow from all\n</Files>\n<Files *.xlsx>\n    Allow from all\n</Files>";
    file_put_contents($output_dir . '/.htaccess', $htaccess_content);
}
add_action('after_switch_theme', 'create_processing_directories');

// Register REST API endpoints
add_action('rest_api_init', function () {
    // File upload endpoint
    register_rest_route('custom/v1', '/upload', array(
        'methods' => 'POST',
        'callback' => 'handle_file_upload',
        'permission_callback' => '__return_true', // You may want to add proper authentication
    ));
    
    // Process completion notification endpoint
    register_rest_route('custom/v1', '/process-complete', array(
        'methods' => 'POST',
        'callback' => 'handle_process_complete',
        'permission_callback' => '__return_true',
    ));
    
    // Download processed file endpoint
    register_rest_route('custom/v1', '/download/(?P<filename>[^/]+)', array(
        'methods' => 'GET',
        'callback' => 'handle_file_download',
        'permission_callback' => '__return_true',
    ));
    
    // List processed files endpoint
    register_rest_route('custom/v1', '/files', array(
        'methods' => 'GET',
        'callback' => 'list_processed_files',
        'permission_callback' => '__return_true',
    ));
});

// Handle file upload
function handle_file_upload($request) {
    $files = $request->get_file_params();
    $body = $request->get_body_params();
    
    if (empty($files['file'])) {
        return new WP_Error('no_file', 'No file uploaded', array('status' => 400));
    }
    
    $file = $files['file'];
    $allowed_types = array('application/pdf', 'image/jpeg', 'image/png', 'image/jpg');
    
    if (!in_array($file['type'], $allowed_types)) {
        return new WP_Error('invalid_file_type', 'File type not allowed', array('status' => 400));
    }
    
    // Move file to input directory
    $upload_dir = wp_upload_dir();
    $input_dir = $upload_dir['basedir'] . '/document-input';
    $timestamp = current_time('timestamp');
    $filename = $timestamp . '_' . sanitize_file_name($file['name']);
    $filepath = $input_dir . '/' . $filename;
    
    if (!move_uploaded_file($file['tmp_name'], $filepath)) {
        return new WP_Error('upload_failed', 'Failed to move uploaded file', array('status' => 500));
    }
    
    // Store file info in database for tracking
    $file_data = array(
        'original_name' => $file['name'],
        'filename' => $filename,
        'filepath' => $filepath,
        'file_type' => $file['type'],
        'file_size' => $file['size'],
        'upload_time' => current_time('mysql'),
        'status' => 'uploaded',
        'processed_files' => ''
    );
    
    global $wpdb;
    $table_name = $wpdb->prefix . 'document_processing';
    
    // Create table if it doesn't exist
    create_processing_table();
    
    $wpdb->insert($table_name, $file_data);
    $file_id = $wpdb->insert_id;
    
    // Trigger n8n webhook
    $n8n_webhook_url = get_option('n8n_webhook_url', 'http://localhost:5678/webhook/process-document');
    $webhook_data = array(
        'fileId' => $file_id,
        'fileName' => $file['name'],
        'filePath' => $filepath,
        'fileUrl' => $upload_dir['baseurl'] . '/document-input/' . $filename,
        'fileType' => $file['type'],
        'contentType' => $file['type'],
        'timestamp' => current_time('c'),
        'webhookUrl' => home_url()
    );
    
    // Send webhook asynchronously
    wp_remote_post($n8n_webhook_url, array(
        'body' => json_encode($webhook_data),
        'headers' => array('Content-Type' => 'application/json'),
        'timeout' => 30,
        'blocking' => false, // Non-blocking request
    ));
    
    // Update file status
    $wpdb->update($table_name, array('status' => 'processing'), array('id' => $file_id));
    
    return rest_ensure_response(array(
        'success' => true,
        'message' => 'File uploaded and processing started',
        'fileId' => $file_id,
        'filename' => $filename
    ));
}

// Handle processing completion notification
function handle_process_complete($request) {
    $params = $request->get_json_params();
    
    if (empty($params['originalFile'])) {
        return new WP_Error('missing_params', 'Missing required parameters', array('status' => 400));
    }
    
    global $wpdb;
    $table_name = $wpdb->prefix . 'document_processing';
    
    // Find the file record
    $file_record = $wpdb->get_row($wpdb->prepare(
        "SELECT * FROM $table_name WHERE original_name = %s AND status = 'processing'",
        $params['originalFile']
    ));
    
    if (!$file_record) {
        return new WP_Error('file_not_found', 'File record not found', array('status' => 404));
    }
    
    // Update file status
    $processed_files = array();
    if (!empty($params['csvFile'])) {
        $processed_files[] = $params['csvFile'];
    }
    if (!empty($params['excelFile'])) {
        $processed_files[] = $params['excelFile'];
    }
    
    $wpdb->update($table_name, array(
        'status' => 'completed',
        'processed_files' => json_encode($processed_files),
        'completion_time' => current_time('mysql')
    ), array('id' => $file_record->id));
    
    return rest_ensure_response(array(
        'success' => true,
        'message' => 'Processing status updated'
    ));
}

// Handle file download
function handle_file_download($request) {
    $filename = $request['filename'];
    $upload_dir = wp_upload_dir();
    $file_path = $upload_dir['basedir'] . '/processed/' . $filename;
    
    if (!file_exists($file_path)) {
        return new WP_Error('file_not_found', 'File not found', array('status' => 404));
    }
    
    // Security check - ensure file is in processed directory and has allowed extension
    $allowed_extensions = array('csv', 'xlsx');
    $file_extension = pathinfo($filename, PATHINFO_EXTENSION);
    
    if (!in_array($file_extension, $allowed_extensions)) {
        return new WP_Error('invalid_file', 'Invalid file type', array('status' => 403));
    }
    
    // Set headers for file download
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="' . basename($filename) . '"');
    header('Content-Length: ' . filesize($file_path));
    
    readfile($file_path);
    exit;
}

// List processed files
function list_processed_files($request) {
    global $wpdb;
    $table_name = $wpdb->prefix . 'document_processing';
    
    $files = $wpdb->get_results(
        "SELECT * FROM $table_name WHERE status = 'completed' ORDER BY completion_time DESC LIMIT 50"
    );
    
    $processed_files = array();
    foreach ($files as $file) {
        $processed_files_list = json_decode($file->processed_files, true) ?: array();
        $processed_files[] = array(
            'id' => $file->id,
            'originalName' => $file->original_name,
            'uploadTime' => $file->upload_time,
            'completionTime' => $file->completion_time,
            'processedFiles' => $processed_files_list
        );
    }
    
    return rest_ensure_response($processed_files);
}

// Create database table for tracking files
function create_processing_table() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'document_processing';
    
    $charset_collate = $wpdb->get_charset_collate();
    
    $sql = "CREATE TABLE IF NOT EXISTS $table_name (
        id int(11) NOT NULL AUTO_INCREMENT,
        original_name varchar(255) NOT NULL,
        filename varchar(255) NOT NULL,
        filepath varchar(500) NOT NULL,
        file_type varchar(100) NOT NULL,
        file_size bigint(20) NOT NULL,
        upload_time datetime NOT NULL,
        completion_time datetime NULL,
        status varchar(50) NOT NULL DEFAULT 'uploaded',
        processed_files text NULL,
        PRIMARY KEY (id),
        KEY status (status),
        KEY upload_time (upload_time)
    ) $charset_collate;";
    
    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($sql);
}

// Add admin menu for configuration
add_action('admin_menu', 'document_processing_admin_menu');

function document_processing_admin_menu() {
    add_options_page(
        'Document Processing Settings',
        'Document Processing',
        'manage_options',
        'document-processing',
        'document_processing_admin_page'
    );
}

function document_processing_admin_page() {
    if (isset($_POST['submit'])) {
        update_option('n8n_webhook_url', sanitize_url($_POST['n8n_webhook_url']));
        update_option('pdf_co_api_key', sanitize_text_field($_POST['pdf_co_api_key']));
        update_option('openai_api_key', sanitize_text_field($_POST['openai_api_key']));
        echo '<div class="notice notice-success"><p>Settings saved!</p></div>';
    }
    
    $n8n_url = get_option('n8n_webhook_url', 'http://localhost:5678/webhook/process-document');
    $pdf_co_key = get_option('pdf_co_api_key', '');
    $openai_key = get_option('openai_api_key', '');
    ?>

```
<div class="wrap">
	<h1>Document Processing Settings</h1>
	<form method="post" action="">
		<table class="form-table">
			<tr>
				<th scope="row">n8n Webhook URL</th>
				<td>
					<input type="url" name="n8n_webhook_url" value="<?php echo esc_attr($n8n_url); ?>" class="regular-text" />
					<p class="description">The webhook URL from your n8n workflow</p>
				</td>
			</tr>
			<tr>
				<th scope="row">PDF.co API Key</th>
				<td>
					<input type="password" name="pdf_co_api_key" value="<?php echo esc_attr($pdf_co_key); ?>" class="regular-text" />
					<p class="description">Your PDF.co API key for PDF processing</p>
				</td>
			</tr>
			<tr>
				<th scope="row">OpenAI API Key</th>
				<td>
					<input type="password" name="openai_api_key" value="<?php echo esc_attr($openai_key); ?>" class="regular-text" />
					<p class="description">Your OpenAI API key for AI data extraction</p>
				</td>
			</tr>
		</table>
		<?php submit_button(); ?>
	</form>

	<h2>Recent Files</h2>
	<?php
    global $wpdb;
    $table_name = $wpdb->prefix . 'document_processing';
    $files = $wpdb->get_results("SELECT * FROM $table_name ORDER BY upload_time DESC LIMIT 10");
    
    if ($files) {
        echo '<table class="wp-list-table widefat fixed striped">';
        echo '<thead><tr><th>File Name</th><th>Status</th><th>Upload Time</th><th>Completion Time</th><th>Processed Files</th></tr></thead><tbody>';
        foreach ($files as $file) {
            $processed_files = json_decode($file->processed_files, true) ?: array();
            echo '<tr>';
            echo '<td>' . esc_html($file->original_name) . '</td>';
            echo '<td><span class="status-' . esc_attr($file->status) . '">' . esc_html($file->status) . '</span></td>';
            echo '<td>' . esc_html($file->upload_time) . '</td>';
            echo '<td>' . esc_html($file->completion_time ?: 'N/A') . '</td>';
            echo '<td>' . esc_html(implode(', ', $processed_files)) . '</td>';
            echo '</tr>';
        }
        echo '</tbody></table>';
    } else {
        echo '<p>No files processed yet.</p>';
    }
    ?>
</div>

<style>
	.status-uploaded {
		color: #0073aa;
	}

	.status-processing {
		color: #d63638;
	}

	.status-completed {
		color: #00a32a;
	}

	.status-error {
		color: #d63638;
	}
</style>
<?php
```

}

// Add shortcode for the dropbox interface
add_shortcode(‘document_dropbox’, ‘document_dropbox_shortcode’);

function document_dropbox_shortcode($atts) {
$atts = shortcode_atts(array(
‘height’ => ‘800px’,
), $atts);

```
$upload_dir = wp_upload_dir();

ob_start();
?>
<div id="document-processing-container" style="height: <?php echo esc_attr($atts['height']); ?>;">
	<iframe src="<?php echo esc_url(get_template_directory_uri() . '/document-dropbox.html'); ?>" style="width: 100%; height: 100%; border: none; border-radius: 10px;" allowfullscreen>
	</iframe>
</div>
<?php
return ob_get_clean();
```

}

// AJAX handler for file status updates
add_action(‘wp_ajax_check_file_status’, ‘check_file_status’);
add_action(‘wp_ajax_nopriv_check_file_status’, ‘check_file_status’);

function check_file_status() {
$file_id = intval($_POST[‘file_id’]);

```
global $wpdb;
$table_name = $wpdb->prefix . 'document_processing';

$file = $wpdb->get_row($wpdb->prepare(
    "SELECT * FROM $table_name WHERE id = %d",
    $file_id
));

if ($file) {
    wp_send_json_success(array(
        'status' => $file->status,
        'processed_files' => json_decode($file->processed_files, true) ?: array()
    ));
} else {
    wp_send_json_error('File not found');
}
```

}

// Clean up old files (run daily)
add_action(‘wp’, ‘schedule_file_cleanup’);

function schedule_file_cleanup() {
if (!wp_next_scheduled(‘cleanup_old_files’)) {
wp_schedule_event(time(), ‘daily’, ‘cleanup_old_files’);
}
}

add_action(‘cleanup_old_files’, ‘cleanup_old_files’);

function cleanup_old_files() {
global $wpdb;
$table_name = $wpdb->prefix . ‘document_processing’;
$upload_dir = wp_upload_dir();

```
// Get files older than 30 days
$old_files = $wpdb->get_results(
    "SELECT * FROM $table_name WHERE upload_time < DATE_SUB(NOW(), INTERVAL 30 DAY)"
);

foreach ($old_files as $file) {
    // Delete physical files
    if (file_exists($file->filepath)) {
        unlink($file->filepath);
    }
    
    $processed_files = json_decode($file->processed_files, true) ?: array();
    foreach ($processed_files as $processed_file) {
        $processed_path = $upload_dir['basedir'] . '/processed/' . $processed_file;
        if (file_exists($processed_path)) {
            unlink($processed_path);
        }
    }
    
    // Delete database record
    $wpdb->delete($table_name, array('id' => $file->id));
}
```

}