<?php
/**
 * Membership card records (CRUD).
 *
 * @package TonItaliaRegistration
 */

defined( 'ABSPATH' ) || exit;

/**
 * Class TON_Reg_Membership_Cards
 */
class TON_Reg_Membership_Cards {

	/**
	 * @return string
	 */
	public static function table_name() {
		global $wpdb;
		return $wpdb->prefix . 'ton_reg_membership_cards';
	}

	/**
	 * Create membership cards table.
	 */
	public static function create_table() {
		global $wpdb;

		$table   = self::table_name();
		$charset = $wpdb->get_charset_collate();

		$sql = "CREATE TABLE {$table} (
			id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
			registration_id bigint(20) unsigned NOT NULL,
			user_id bigint(20) unsigned DEFAULT NULL,
			year smallint(5) unsigned NOT NULL,
			attachment_id bigint(20) unsigned NOT NULL,
			template_attachment_id bigint(20) unsigned NOT NULL DEFAULT 0,
			layout_snapshot longtext NULL,
			generation_context varchar(20) NOT NULL DEFAULT 'manual',
			created_at datetime NOT NULL,
			created_by bigint(20) unsigned NOT NULL DEFAULT 0,
			PRIMARY KEY  (id),
			UNIQUE KEY registration_year (registration_id, year),
			KEY user_id (user_id),
			KEY year (year)
		) {$charset};";

		require_once ABSPATH . 'wp-admin/includes/upgrade.php';
		dbDelta( $sql );
	}

	/**
	 * @param array<string,mixed> $data Row data.
	 * @return int|false
	 */
	public static function insert( $data ) {
		global $wpdb;

		if ( empty( $data['created_at'] ) ) {
			$data['created_at'] = current_time( 'mysql', true );
		}

		$result = $wpdb->insert( self::table_name(), $data );
		return false === $result ? false : (int) $wpdb->insert_id;
	}

	/**
	 * @param int                  $id   Card ID.
	 * @param array<string,mixed> $data Data.
	 * @return bool
	 */
	public static function update( $id, $data ) {
		global $wpdb;

		return false !== $wpdb->update(
			self::table_name(),
			$data,
			array( 'id' => $id ),
			null,
			array( '%d' )
		);
	}

	/**
	 * @param int $id Card ID.
	 * @return object|null
	 */
	public static function get( $id ) {
		global $wpdb;

		return $wpdb->get_row(
			$wpdb->prepare(
				'SELECT * FROM ' . self::table_name() . ' WHERE id = %d',
				$id
			)
		);
	}

	/**
	 * @param int $registration_id Registration ID.
	 * @param int $year            Card year.
	 * @return object|null
	 */
	public static function get_by_registration_year( $registration_id, $year ) {
		global $wpdb;

		return $wpdb->get_row(
			$wpdb->prepare(
				'SELECT * FROM ' . self::table_name() . ' WHERE registration_id = %d AND year = %d',
				$registration_id,
				$year
			)
		);
	}

	/**
	 * @param int $registration_id Registration ID.
	 * @return array<int,object>
	 */
	public static function get_by_registration( $registration_id ) {
		global $wpdb;

		return $wpdb->get_results(
			$wpdb->prepare(
				'SELECT * FROM ' . self::table_name() . ' WHERE registration_id = %d ORDER BY year DESC',
				$registration_id
			)
		);
	}

	/**
	 * @param int $user_id WordPress user ID.
	 * @return array<int,object>
	 */
	public static function get_by_user_id( $user_id ) {
		global $wpdb;

		if ( ! $user_id ) {
			return array();
		}

		return $wpdb->get_results(
			$wpdb->prepare(
				'SELECT * FROM ' . self::table_name() . ' WHERE user_id = %d ORDER BY year DESC',
				$user_id
			)
		);
	}

	/**
	 * @param int $id Card ID.
	 * @return bool
	 */
	public static function delete( $id ) {
		global $wpdb;

		return false !== $wpdb->delete(
			self::table_name(),
			array( 'id' => $id ),
			array( '%d' )
		);
	}

	/**
	 * Delete card row and its attachment.
	 *
	 * @param int $id Card ID.
	 */
	public static function delete_with_attachment( $id ) {
		$card = self::get( $id );
		if ( ! $card ) {
			return;
		}

		if ( ! empty( $card->attachment_id ) ) {
			wp_delete_attachment( (int) $card->attachment_id, true );
		}

		self::delete( $id );
	}
}
