import os

def generate_php_api(script_name, table_structure):
    """
    Gera o conteudo de um script PHP de API RESTful com base na estrutura da tabela.
    """
    table_name_raw = None
    columns = []
    
    # Extrair nome da tabela e colunas da estrutura SQL
    lines = table_structure.split('\n')
    for line in lines:
        line = line.strip()
        if line.startswith('CREATE TABLE'):
            table_name_raw = line.split('`')[1] # Captura o nome da tabela
        elif '`' in line and not line.startswith('PRIMARY KEY'):
            parts = line.split('`')
            column_name = parts[1]
            if 'VARCHAR' in line:
                length_start = line.find('VARCHAR(') + len('VARCHAR(')
                length_end = line.find(')', length_start)
                max_length = line[length_start:length_end]
                columns.append({'name': column_name, 'type': 'string', 'max_length': int(max_length)})
            elif 'INT' in line:
                columns.append({'name': column_name, 'type': 'int'})
            # Adicione outros tipos de coluna conforme necessario

    if not table_name_raw:
        print("Erro: Nao foi possivel extrair o nome da tabela da estrutura SQL.")
        return None
    
    # Remove "eqp_" ou "eq_" se existir para o nome interno da API
    if table_name_raw.startswith('eqp_'):
        internal_name = table_name_raw[4:]
    elif table_name_raw.startswith('eq_'):
        internal_name = table_name_raw[3:]
    else:
        internal_name = table_name_raw

    # Capitaliza a primeira letra do nome interno para mensagens
    internal_name_capitalized = internal_name.capitalize()

    # Filtra as colunas para incluir apenas as que sao passiveis de CRUD (excluindo 'id')
    crud_columns = [col for col in columns if col['name'] != 'id']

    # Gerar a lista de campos para INSERT/UPDATE
    insert_fields = ", ".join([f"`{col['name']}`" for col in crud_columns])
    insert_values = ", ".join([f":{col['name']}" for col in crud_columns])
    update_set_fields = ", ".join([f"`{col['name']}` = :{col['name']}" for col in crud_columns])

    # Gerar a validacao de dados para create/update
    validation_code = ""
    for col in crud_columns:
        validation_code += f"    if (!isset($data['{col['name']}'])) {{\n"
        validation_code += f"        http_response_code(400);\n"
        validation_code += f"        echo json_encode(['error' => 'Campo \"{col['name']}\" faltando']);\n"
        validation_code += f"        return;\n"
        validation_code += f"    }}\n"
        if col['type'] == 'string' and 'max_length' in col:
            validation_code += f"    if (strlen($data['{col['name']}']) > {col['max_length']}) {{\n"
            validation_code += f"        http_response_code(400);\n"
            validation_code += f"        echo json_encode(['error' => 'O campo \"{col['name']}\" deve ter no maximo {col['max_length']} caracteres']);\n"
            validation_code += f"        return;\n"
            validation_code += f"    }}\n"
        validation_code += "\n"

    # Gerar os parâmetros para execute
    execute_params_create = ", ".join([f"':{col['name']}' => $data['{col['name']}']" for col in crud_columns])
    execute_params_update = ", ".join([f"':{col['name']}' => $data['{col['name']}']" for col in crud_columns])
    if execute_params_update: # Adiciona o ':id' ao final, se houver outros parâmetros
        execute_params_update += f", ':id' => $id"
    else: # Se nao houver outros parâmetros, apenas o ':id'
        execute_params_update = f"':id' => $id"


    php_code = f"""<?php
header("Content-Type: application/json");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE");
header("Access-Control-Allow-Headers: Content-Type");

// Conexao com o .env
$dotenv = parse_ini_file(__DIR__ . '../../.env');
$dbHost = $dotenv['DB_HOST'];
$dbUser = $dotenv['DB_USER'];
$dbPass = $dotenv['DB_PASSWORD'];
$dbName = $dotenv['DB_NAME'];

// Conexao com o banco de dados
try {{
    $pdo = new PDO("mysql:host=$dbHost;dbname=$dbName;charset=utf8", $dbUser, $dbPass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}} catch (PDOException $e) {{
    http_response_code(500);
    echo json_encode(['error' => 'Falha na conexao com o banco de dados: ' . $e->getMessage()]);
    exit;
}}

// Roteamento
$method = $_SERVER['REQUEST_METHOD'];
$id = isset($_GET['id']) ? (int)$_GET['id'] : null;

// Verifica se o script esta sendo acessado diretamente
if (basename($_SERVER['SCRIPT_FILENAME']) === '{script_name}') {{
    switch ($method) {{
        case 'GET':
            if ($id) {{
                get{internal_name_capitalized}($pdo, $id);
            }} else {{
                getAll{internal_name_capitalized}s($pdo);
            }}
            break;
        case 'POST':
            create{internal_name_capitalized}($pdo);
            break;
        case 'PUT':
            if ($id) {{
                update{internal_name_capitalized}($pdo, $id);
            }} else {{
                http_response_code(400);
                echo json_encode(['error' => 'ID do {internal_name} nao especificado']);
            }}
            break;
        case 'DELETE':
            if ($id) {{
                delete{internal_name_capitalized}($pdo, $id);
            }} else {{
                http_response_code(400);
                echo json_encode(['error' => 'ID do {internal_name} nao especificado']);
            }}
            break;
        default:
            http_response_code(405);
            echo json_encode(['error' => 'Metodo nao permitido']);
    }}
}} else {{
    http_response_code(404);
    echo json_encode(['error' => 'Endpoint nao encontrado']);
}}

// Funcoes CRUD

function getAll{internal_name_capitalized}s($pdo) {{
    try {{
        $stmt = $pdo->query("SELECT * FROM {table_name_raw}");
        ${internal_name}s = $stmt->fetchAll(PDO::FETCH_ASSOC);
        echo json_encode(${internal_name}s);
    }} catch (PDOException $e) {{
        http_response_code(500);
        echo json_encode(['error' => 'Erro ao buscar {internal_name}s: ' . $e->getMessage()]);
    }}
}}

function get{internal_name_capitalized}($pdo, $id) {{
    try {{
        $stmt = $pdo->prepare("SELECT * FROM {table_name_raw} WHERE id = ?");
        $stmt->execute([$id]);
        ${internal_name} = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (${internal_name}) {{
            echo json_encode(${internal_name});
        }} else {{
            http_response_code(404);
            echo json_encode(['error' => '{internal_name_capitalized} nao encontrado']);
        }}
    }} catch (PDOException $e) {{
        http_response_code(500);
        echo json_encode(['error' => 'Erro ao buscar {internal_name}: ' . $e->getMessage()]);
    }}
}}

function create{internal_name_capitalized}($pdo) {{
    $data = json_decode(file_get_contents('php://input'), true);
    
    if (!$data) {{
        http_response_code(400);
        echo json_encode(['error' => 'Dados invalidos']);
        return;
    }}
    
{validation_code}
    try {{
        $sql = "INSERT INTO {table_name_raw} ({insert_fields}) VALUES ({insert_values})";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([
            {execute_params_create}
        ]);
        
        $id = $pdo->lastInsertId();
        http_response_code(201);
        echo json_encode(['id' => $id, 'message' => '{internal_name_capitalized} criado com sucesso']);
    }} catch (PDOException $e) {{
        http_response_code(500);
        echo json_encode(['error' => 'Erro ao criar {internal_name}: ' . $e->getMessage()]);
    }}
}}

function update{internal_name_capitalized}($pdo, $id) {{
    $data = json_decode(file_get_contents('php://input'), true);
    
    if (!$data) {{
        http_response_code(400);
        echo json_encode(['error' => 'Dados invalidos']);
        return;
    }}
    
{validation_code}
    try {{
        // Verifica se o {internal_name} existe
        $check = $pdo->prepare("SELECT id FROM {table_name_raw} WHERE id = ?");
        $check->execute([$id]);
        
        if (!$check->fetch()) {{
            http_response_code(404);
            echo json_encode(['error' => '{internal_name_capitalized} nao encontrado']);
            return;
        }}
        
        $sql = "UPDATE {table_name_raw} SET {update_set_fields} WHERE id = :id";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([
            {execute_params_update}
        ]);
        
        echo json_encode(['message' => '{internal_name_capitalized} atualizado com sucesso']);
    }} catch (PDOException $e) {{
        http_response_code(500);
        echo json_encode(['error' => 'Erro ao atualizar {internal_name}: ' . $e->getMessage()]);
    }}
}}

function delete{internal_name_capitalized}($pdo, $id) {{
    try {{
        // Verifica se o {internal_name} existe
        $check = $pdo->prepare("SELECT id FROM {table_name_raw} WHERE id = ?");
        $check->execute([$id]);
        
        if (!$check->fetch()) {{
            http_response_code(404);
            echo json_encode(['error' => '{internal_name_capitalized} nao encontrado']);
            return;
        }}
        
        $stmt = $pdo->prepare("DELETE FROM {table_name_raw} WHERE id = ?");
        $stmt->execute([$id]);
        
        echo json_encode(['message' => '{internal_name_capitalized} deletado com sucesso']);
    }} catch (PDOException $e) {{
        http_response_code(500);
        echo json_encode(['error' => 'Erro ao deletar {internal_name}: ' . $e->getMessage()]);
    }}
}}
?>"""
    return php_code

def main():
    script_name = input("Qual o nome do script? (ex: eqp_tamanho.php) ")

    print("Cole a estrutura da tabela e na outra linha digite END e tecle Enter:")
    table_structure_lines = []
    while True:
        line = input()
        if line.strip().upper() == "END":
            break
        table_structure_lines.append(line)
    table_structure = "\n".join(table_structure_lines)

    php_content = generate_php_api(script_name, table_structure)

    if php_content:
        # Garante que a pasta 'routers' existe
        if not os.path.exists('routers'):
            os.makedirs('routers')

        file_path = os.path.join('routers', script_name)
        with open(file_path, 'w') as f:
            f.write(php_content)
        print(f"\nAPI RESTful '{script_name}' gerada com sucesso em 'routers/{script_name}'")
    else:
        print("\nNao foi possivel gerar a API RESTful.")

if __name__ == "__main__":
    main()