package com.realnet.Builders.Services;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import org.springframework.stereotype.Service;

@Service
public class SqlDumpExecutor {

	/**
	 * Executes a massive SQL dump safely.
	 *
	 * @param connection JDBC connection
	 * @param sqlDump    Full SQL dump string from getSql()
	 */
	public void executeDump(Connection connection, String sqlDump) {
		Statement stmt = null;
		try {
			stmt = connection.createStatement();
			connection.setAutoCommit(false);

			// Remove MySQL backticks
			sqlDump = sqlDump.replaceAll("`", "");

			// Remove table-level DEFAULT COLLATE or CHARSET
			sqlDump = sqlDump.replaceAll("(?i)DEFAULT\\s+CHARSET=[^;\\n]+", "");
			sqlDump = sqlDump.replaceAll("(?i)COLLATE=[^;\\n]+", "");

			// Convert data types
			sqlDump = sqlDump.replaceAll("(?i)bigint", "INTEGER");
			sqlDump = sqlDump.replaceAll("(?i)int\\([0-9]+\\)", "INTEGER");
			sqlDump = sqlDump.replaceAll("(?i)varchar\\([0-9]+\\)", "TEXT");
			sqlDump = sqlDump.replaceAll("(?i)bit\\([0-9]+\\)", "INTEGER");
			sqlDump = sqlDump.replaceAll("(?i)longblob", "BLOB");

			// Remove AUTO_INCREMENT (if any)
			sqlDump = sqlDump.replaceAll("(?i)AUTO_INCREMENT", "");

			// Remove MySQL-specific directives
			sqlDump = sqlDump.replaceAll("(?i)SET\\s+[^;]+;", "");
			sqlDump = sqlDump.replaceAll("(?i)ENGINE=\\w+\\s*", "");
			sqlDump = sqlDump.replaceAll("(?i)AUTO_INCREMENT=\\d+", "");
			sqlDump = sqlDump.replaceAll("(?i)CHARSET=\\w+", "");

			// Remove DEFAULT NULL (SQLite allows NULL by default)
			sqlDump = sqlDump.replaceAll("(?i)DEFAULT NULL", "");

			// Convert UNIQUE KEY <name> to UNIQUE
			sqlDump = sqlDump.replaceAll("(?i)UNIQUE KEY [^\\(]+\\(", "UNIQUE(");

			// Remove double commas in CREATE TABLE (,,)
			sqlDump = sqlDump.replaceAll(",\\s*,", ",");

			// Remove _binary prefix in INSERT statements
			sqlDump = sqlDump.replaceAll("(?i)_binary\\s+'", "'");

			String delimiter = ";"; // default delimiter
			StringBuilder sqlStatement = new StringBuilder();

			String[] lines = sqlDump.split("\\r?\\n");
			for (String line : lines) {
				line = line.trim();

				// Skip empty lines and comments
				if (line.isEmpty() || line.startsWith("--") || line.startsWith("//") || line.startsWith("/*")) {
					continue;
				}

				// Detect DELIMITER changes (optional, mostly MySQL)
				if (line.startsWith("DELIMITER ")) {
					delimiter = line.substring("DELIMITER ".length()).trim();
					continue;
				}

				// Remove MySQL-specific comments like /*! ... */
				line = line.replaceAll("/\\*!.*?\\*/", "").trim();
				if (line.isEmpty())
					continue;

				sqlStatement.append(line).append(" ");

				// Check if statement ends with current delimiter
				if (sqlStatement.toString().trim().endsWith(delimiter)) {
					String finalSql = sqlStatement.toString().trim();

					// Remove the delimiter from the end
					if (delimiter.length() > 0 && finalSql.endsWith(delimiter)) {
						finalSql = finalSql.substring(0, finalSql.length() - delimiter.length()).trim();
					}

					try {
						stmt.execute(finalSql);
					} catch (SQLException e) {
						System.err.println("Failed SQL: " + finalSql);
						e.printStackTrace();
					}

					sqlStatement.setLength(0); // reset for next statement
				}
			}

			connection.commit();

		} catch (Exception e) {
			System.err.println("Error executing SQL dump: " + e.getMessage());
			e.printStackTrace();
			try {
				connection.rollback();
			} catch (SQLException ex) {
				System.err.println("Rollback failed: " + ex.getMessage());
			}
		} finally {
			if (stmt != null) {
				try {
					stmt.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			try {
				connection.setAutoCommit(true);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

}
