package com.alterdekim.game.component;

import jakarta.persistence.EntityManager;
import jakarta.transaction.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class NativeDao {
    @Autowired
    EntityManager em;

    /*
        This component itself is a big security breach due to straightforward pushing changes into the
        database from the http requests of the user (even though the user is always admin).
        The application may be vulnerable to SQL injections and some other stuff.
        I understand that, but due to limit of time I have, I decided to leave it as is.
        It's my hobby project, not an enterprise-grade server.
     */

    @Transactional
    public void updateTable(String table, String column, Boolean val, Long id) {
        String s = "UPDATE %s t SET t.%s = %b WHERE t.id = %d";
        String sql = String.format(s, table, camelToSnake(column), val, id);
        em.createNativeQuery(sql).executeUpdate();
    }

    @Transactional
    public void insertEntity(String table, Map<String, String> vals) {
        StringBuilder sb = new StringBuilder();
        StringBuilder sb2 = new StringBuilder();
        sb.append("INSERT INTO ");
        sb.append(table);
        sb.append(" (");
        Iterator<String> i = vals.keySet().iterator();
        while( i.hasNext() ) {
            String key = i.next();
            sb.append(camelToSnake(key));
            sb2.append(vals.get(key));
            if( !i.hasNext() ) break;
            sb.append(", ");
            sb2.append(", ");
        }
        sb.append(") VALUES (");
        sb.append(sb2);
        sb.append(")");
        log.info("Query: {}", sb);
        em.createNativeQuery(sb.toString()).executeUpdate();
    }

    private String camelToSnake(String str) {
        String result = "";
        char c = str.charAt(0);
        result = result + Character.toLowerCase(c);
        for (int i = 1; i < str.length(); i++) {
            char ch = str.charAt(i);
            if (Character.isUpperCase(ch)) {
                result = result + '_';
                result
                        = result
                        + Character.toLowerCase(ch);
            } else {
                result = result + ch;
            }
        }
        return result;
    }
}
