<?php

declare(strict_types=1);

namespace OCA\Mitgliederverwaltung\Db;

use OCP\IDBConnection;

/**
 * Platform-aware SQL expression generator.
 *
 * Provides methods that return raw SQL fragments appropriate for the
 * current database backend (MySQL/MariaDB, PostgreSQL, SQLite).
 * All column references are hardcoded — never pass user input as $col.
 *
 * Part of Issue #192.
 */
class PlatformHelper {

    /**
     * Generate an expression that computes the number of full years
     * between a DATE column and the current date.
     *
     * This is the portable replacement for MySQL's
     *   TIMESTAMPDIFF(YEAR, col, CURDATE())
     *
     * @param IDBConnection $db The database connection
     * @param string $col The fully-qualified column reference (e.g. 'm.geburtsdatum')
     * @return string Raw SQL expression returning an integer year difference
     */
    public static function getYearDiffExpression(IDBConnection $db, string $col): string {
        $platform = $db->getDatabaseProvider();

        return match ($platform) {
            IDBConnection::PLATFORM_POSTGRES =>
                "EXTRACT(YEAR FROM AGE(CURRENT_DATE, $col))::integer",
            IDBConnection::PLATFORM_SQLITE =>
                // SQLite: compute raw year difference, then subtract 1 if the
                // birthday/anniversary hasn't occurred yet this year.
                "("
                . "CAST(strftime('%Y', 'now') AS INTEGER) - CAST(strftime('%Y', $col) AS INTEGER)"
                . " - CASE WHEN strftime('%m-%d', 'now') < strftime('%m-%d', $col) THEN 1 ELSE 0 END"
                . ")",
            // MySQL / MariaDB (default)
            default =>
                "TIMESTAMPDIFF(YEAR, $col, CURDATE())",
        };
    }

    /**
     * Generate an expression that extracts the month (1-12) from a DATE column.
     *
     * Portable replacement for MySQL's MONTH(col).
     *
     * @param IDBConnection $db The database connection
     * @param string $col The fully-qualified column reference (e.g. 'm.geburtsdatum')
     * @return string Raw SQL expression returning the month as an integer
     */
    public static function getMonthExpression(IDBConnection $db, string $col): string {
        $platform = $db->getDatabaseProvider();

        return match ($platform) {
            IDBConnection::PLATFORM_POSTGRES =>
                "EXTRACT(MONTH FROM $col)::integer",
            IDBConnection::PLATFORM_SQLITE =>
                "CAST(strftime('%m', $col) AS INTEGER)",
            // MySQL / MariaDB (default)
            default =>
                "MONTH($col)",
        };
    }

    /**
     * Generate an expression that extracts the four-digit year from a DATE column.
     *
     * Portable replacement for MySQL's YEAR(col).
     *
     * @param IDBConnection $db The database connection
     * @param string $col The fully-qualified column reference (e.g. 'l.startdatum')
     * @return string Raw SQL expression returning the year as an integer
     */
    public static function getYearExpression(IDBConnection $db, string $col): string {
        $platform = $db->getDatabaseProvider();

        return match ($platform) {
            IDBConnection::PLATFORM_POSTGRES =>
                "EXTRACT(YEAR FROM $col)::integer",
            IDBConnection::PLATFORM_SQLITE =>
                "CAST(strftime('%Y', $col) AS INTEGER)",
            // MySQL / MariaDB (default)
            default =>
                "YEAR($col)",
        };
    }
}
