<?php

namespace Antimanual;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class GenerationJobs {
	private static $table_name = 'antimanual_generation_jobs';
	private static $table_exists = null;

	public static function create_table() {
		global $wpdb;
		$table   = $wpdb->prefix . self::$table_name;
		$charset = $wpdb->get_charset_collate();

		$sql = "CREATE TABLE $table (
			id VARCHAR(36) NOT NULL,
			status VARCHAR(20) NOT NULL DEFAULT 'pending',
			params LONGTEXT,
			result LONGTEXT,
			attempts TINYINT NOT NULL DEFAULT 0,
			last_error TEXT,
			created_by BIGINT UNSIGNED NOT NULL DEFAULT 0,
			created_at DATETIME NOT NULL,
			started_at DATETIME,
			executed_at DATETIME,
			PRIMARY KEY (id),
			KEY status (status),
			KEY created_at (created_at)
		) $charset;";

		require_once ABSPATH . 'wp-admin/includes/upgrade.php';
		dbDelta( $sql );
		self::$table_exists = true;
	}

	private static function ensure_table_exists() {
		if ( self::$table_exists ) {
			return;
		}
		global $wpdb;
		$table = $wpdb->prefix . self::$table_name;
		if ( $wpdb->get_var( "SHOW TABLES LIKE '$table'" ) !== $table ) {
			self::create_table();
		} else {
			self::$table_exists = true;
		}
	}

	public static function insert( string $job_id, array $params ): bool {
		global $wpdb;
		self::ensure_table_exists();

		$result = $wpdb->insert(
			$wpdb->prefix . self::$table_name,
			array(
				'id'         => $job_id,
				'status'     => 'pending',
				'params'     => wp_json_encode( $params ),
				'attempts'   => 0,
				'created_by' => get_current_user_id(),
				'created_at' => current_time( 'mysql' ),
			),
			array( '%s', '%s', '%s', '%d', '%d', '%s' )
		);

		return false !== $result;
	}

	public static function get( string $job_id ): ?array {
		global $wpdb;
		self::ensure_table_exists();

		$row = $wpdb->get_row(
			$wpdb->prepare(
				'SELECT * FROM ' . $wpdb->prefix . self::$table_name . ' WHERE id = %s',
				$job_id
			),
			ARRAY_A
		);

		if ( ! $row ) {
			return null;
		}

		$row['params'] = $row['params'] ? json_decode( $row['params'], true ) : array();
		$row['result'] = $row['result'] ? json_decode( $row['result'], true ) : null;

		return $row;
	}

	public static function update( string $job_id, array $data ): bool {
		global $wpdb;
		self::ensure_table_exists();

		$allowed = array( 'status', 'result', 'attempts', 'last_error', 'started_at', 'executed_at' );
		$update  = array();
		$formats = array();

		foreach ( $allowed as $field ) {
			if ( ! array_key_exists( $field, $data ) ) {
				continue;
			}
			if ( 'result' === $field && is_array( $data[ $field ] ) ) {
				$update[ $field ] = wp_json_encode( $data[ $field ] );
			} else {
				$update[ $field ] = $data[ $field ];
			}
			$formats[] = '%s';
		}

		if ( empty( $update ) ) {
			return false;
		}

		$result = $wpdb->update(
			$wpdb->prefix . self::$table_name,
			$update,
			array( 'id' => $job_id ),
			$formats,
			array( '%s' )
		);

		return false !== $result;
	}

	public static function delete( string $job_id ): bool {
		global $wpdb;
		$result = $wpdb->delete(
			$wpdb->prefix . self::$table_name,
			array( 'id' => $job_id ),
			array( '%s' )
		);
		return false !== $result;
	}

	/**
	 * Delete completed and failed jobs older than $days days.
	 */
	public static function cleanup( int $days = 7 ): void {
		global $wpdb;
		$wpdb->query(
			$wpdb->prepare(
				'DELETE FROM ' . $wpdb->prefix . self::$table_name .
				" WHERE status IN ('completed', 'failed') AND created_at < DATE_SUB(NOW(), INTERVAL %d DAY)",
				$days
			)
		);
	}
}
