<?php
/**
 * ANCP Core - Repositories Table (GEDCOM REPO, spec-00 5.2).
 *
 * @package    AncestorPress\Core
 * @subpackage AncestorPress\Core\DB
 * @since      0.7.0
 */

namespace AncestorPress\Core;

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

class Repositories_Table {

	public static function table() {
		return Tables::repositories();
	}

	/**
	 * Fetch a repository by tree + repoID.
	 *
	 * @param  string $gedcom Tree identifier.
	 * @param  string $repoID Repository reference (e.g. R1).
	 * @return object|null
	 */
	public static function get_by_ref( $gedcom, $repoID ) {
		global $wpdb;
		return $wpdb->get_row( $wpdb->prepare( 'SELECT * FROM %i WHERE gedcom = %s AND repoID = %s LIMIT 1', self::table(), $gedcom, $repoID ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
	}

	/**
	 * All repositories for a tree.
	 *
	 * @param  string $gedcom Tree identifier.
	 * @return array
	 */
	public static function get_by_tree( $gedcom ) {
		global $wpdb;
		return $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i WHERE gedcom = %s ORDER BY reponame ASC, repoID ASC', self::table(), $gedcom ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
	}

	/**
	 * Count repositories in a tree.
	 *
	 * @param  string $gedcom Tree identifier.
	 * @return int
	 */
	public static function count_by_tree( $gedcom ) {
		global $wpdb;
		return (int) $wpdb->get_var( $wpdb->prepare( 'SELECT COUNT(*) FROM %i WHERE gedcom = %s', self::table(), $gedcom ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
	}

	/**
	 * Insert a repository record.
	 *
	 * @param  array $data Field => value pairs.
	 * @return int|false   New row ID or false.
	 */
	public static function insert( $data ) {
		global $wpdb;
		$now  = Tables::now();
		$data = array_merge(
			array(
				'created_by_user_id' => get_current_user_id(),
				'created_at'         => $now,
				'updated_at'         => $now,
			),
			$data
		);
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- core table write.
		$result = $wpdb->insert( self::table(), $data );
		return $result ? (int) $wpdb->insert_id : false;
	}

	/**
	 * Update a repository by row ID.
	 *
	 * @param  int   $id   Row ID.
	 * @param  array $data Field => value pairs.
	 * @return int|false
	 */
	public static function update( $id, $data ) {
		global $wpdb;
		$data['updated_at'] = Tables::now();
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- core table write.
		return $wpdb->update( self::table(), $data, array( 'id' => absint( $id ) ) );
	}

	/**
	 * Delete a repository (sources keep their repoID string; display code
	 * treats a missing repository as unlinked).
	 *
	 * @param  int $id Row ID.
	 * @return int|false
	 */
	public static function delete( $id ) {
		global $wpdb;
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- core table write.
		return $wpdb->delete( self::table(), array( 'id' => absint( $id ) ) );
	}

	/**
	 * Delete all repositories for a tree.
	 *
	 * @param  string $gedcom Tree identifier.
	 * @return void
	 */
	public static function delete_by_gedcom( $gedcom ) {
		global $wpdb;
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- core table write.
		$wpdb->delete( self::table(), array( 'gedcom' => $gedcom ) );
	}

	/**
	 * Next manual repository ID (R-1, R-2... - GEDCOM imports use R-series).
	 *
	 * @param  string $gedcom Tree identifier.
	 * @return string
	 */
	public static function next_manual_id( $gedcom ) {
		global $wpdb;
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- LIKE prefix is a trusted literal.
		$rows = $wpdb->get_col( $wpdb->prepare( 'SELECT repoID FROM %i WHERE gedcom = %s AND repoID LIKE %s', self::table(), $gedcom, $wpdb->esc_like( 'R-' ) . '%' ) );
		$max  = 0;
		foreach ( $rows as $rid ) {
			$n = (int) substr( $rid, 2 );
			if ( $n > $max ) {
				$max = $n;
			}
		}
		return 'R-' . ( $max + 1 );
	}
}
