<?php

/**
 * Class TableController
 * 
 * Controller for managing database tables
 */
class TableController extends Controller
{
    /**
     * Construct this object by extending the basic Controller class
     */
    public function __construct()
    {
        parent::__construct();
        
        // Only admin users can access the table manager
        Auth::checkAuthentication();
        Auth::checkAdminAuthentication();
    }

    /**
     * Show table content with pagination
     * @param string $database_name
     * @param string $table_name
     * @param int $page
     */
    public function show($database_name = null, $table_name = null, $page = 1)
    {
        if (!$database_name) {
            $database_name = Config::get('DB_NAME');
        }
        
        if (!$table_name) {
            Redirect::to('database/show/' . urlencode($database_name));
            return;
        }

        $page = (int)$page;
        $per_page = 20;
        
        $this->View->renderDbManager('table/show', array(
            'database_name' => $database_name,
            'table_name' => $table_name,
            'columns' => TableModel::getTableColumns($database_name, $table_name),
            'rows' => TableModel::getTableRows($database_name, $table_name, $page, $per_page),
            'total_rows' => TableModel::getTableRowCount($database_name, $table_name),
            'current_page' => $page,
            'per_page' => $per_page,
            'table_info' => TableModel::getTableInfo($database_name, $table_name)
        ));
    }

    /**
     * Create a new table
     * @param string $database_name
     */
    public function create($database_name = null)
    {
        if (!$database_name) {
            $database_name = Config::get('DB_NAME');
        }

        if (Request::post('submit_create_table')) {
            $table_name = Request::post('table_name');
            $columns = Request::post('columns');
            
            if ($this->isAjaxRequest()) {
                header('Content-Type: application/json');
                
                if (TableModel::createTable($database_name, $table_name, $columns)) {
                    echo json_encode([
                        'success' => true,
                        'message' => 'Table created successfully',
                        'redirect' => Config::get('URL') . 'table/show/' . urlencode($database_name) . '/' . urlencode($table_name)
                    ]);
                } else {
                    echo json_encode([
                        'success' => false,
                        'message' => 'Failed to create table'
                    ]);
                }
                return;
            }
            
            if (TableModel::createTable($database_name, $table_name, $columns)) {
                Redirect::to('table/show/' . urlencode($database_name) . '/' . urlencode($table_name));
            } else {
                Redirect::to('database/show/' . urlencode($database_name));
            }
            return;
        }

        // Show create table form
        $this->View->renderDbManager('table/create', array(
            'database_name' => $database_name
        ));
    }

    /**
     * Show table structure
     * @param string $database_name
     * @param string $table_name
     */
    public function structure($database_name = null, $table_name = null)
    {
        if (!$database_name) {
            $database_name = Config::get('DB_NAME');
        }
        
        if (!$table_name) {
            Redirect::to('database/show/' . urlencode($database_name));
            return;
        }

        $this->View->renderDbManager('table/structure', array(
            'database_name' => $database_name,
            'table_name' => $table_name,
            'columns' => TableModel::getTableColumns($database_name, $table_name),
            'indexes' => TableModel::getTableIndexes($database_name, $table_name),
            'table_info' => TableModel::getTableInfo($database_name, $table_name)
        ));
    }

    /**
     * Add a column to a table
     * @param string $database_name
     * @param string $table_name
     */
    public function addColumn($database_name = null, $table_name = null)
    {
        if (!$database_name) {
            $database_name = Config::get('DB_NAME');
        }
        
        if (!$table_name) {
            Redirect::to('database/show/' . urlencode($database_name));
            return;
        }

        if (Request::post('submit_add_column')) {
            $column_name = Request::post('column_name');
            $column_type = Request::post('column_type');
            $column_null = Request::post('column_null');
            $column_key = Request::post('column_key');
            $column_default = Request::post('column_default');
            $column_extra = Request::post('column_extra');
            
            if ($this->isAjaxRequest()) {
                header('Content-Type: application/json');
                
                if (TableModel::addColumn($database_name, $table_name, $column_name, $column_type, $column_null, $column_key, $column_default, $column_extra)) {
                    echo json_encode([
                        'success' => true,
                        'message' => 'Column added successfully',
                        'reload' => true
                    ]);
                } else {
                    echo json_encode([
                        'success' => false,
                        'message' => 'Failed to add column'
                    ]);
                }
                return;
            }
            
            if (TableModel::addColumn($database_name, $table_name, $column_name, $column_type, $column_null, $column_key, $column_default, $column_extra)) {
                Redirect::to('table/structure/' . urlencode($database_name) . '/' . urlencode($table_name));
            } else {
                Redirect::to('table/structure/' . urlencode($database_name) . '/' . urlencode($table_name));
            }
            return;
        }

        // Show add column form
        $this->View->renderDbManager('table/add_column', array(
            'database_name' => $database_name,
            'table_name' => $table_name
        ));
    }

    /**
     * Drop a column from a table
     * @param string $database_name
     * @param string $table_name
     * @param string $column_name
     */
    public function dropColumn($database_name, $table_name, $column_name)
    {
        $success = TableModel::dropColumn($database_name, $table_name, $column_name);
        
        if ($this->isAjaxRequest()) {
            header('Content-Type: application/json');
            if ($success) {
                echo json_encode([
                    'success' => true,
                    'message' => 'Column dropped successfully',
                    'reload' => true
                ]);
            } else {
                echo json_encode([
                    'success' => false,
                    'message' => 'Failed to drop column'
                ]);
            }
            return;
        }
        
        Redirect::to('table/structure/' . urlencode($database_name) . '/' . urlencode($table_name));
    }

    /**
     * Delete a table
     * @param string $database_name
     * @param string $table_name
     */
    public function delete($database_name, $table_name)
    {
        $success = TableModel::deleteTable($database_name, $table_name);
        
        if ($this->isAjaxRequest()) {
            header('Content-Type: application/json');
            if ($success) {
                echo json_encode([
                    'success' => true,
                    'message' => 'Table deleted successfully',
                    'redirect' => Config::get('URL') . 'database/show/' . urlencode($database_name)
                ]);
            } else {
                echo json_encode([
                    'success' => false,
                    'message' => 'Failed to delete table'
                ]);
            }
            return;
        }
        
        Redirect::to('database/show/' . urlencode($database_name));
    }

    /**
     * Update a row in the table (AJAX)
     * @param string $database_name
     * @param string $table_name
     */
    public function updateRow($database_name = null, $table_name = null)
    {
        if (!$database_name || !$table_name) {
            if ($this->isAjaxRequest()) {
                header('Content-Type: application/json');
                echo json_encode(['success' => false, 'message' => 'Invalid parameters']);
                return;
            }
            Redirect::to('database/index');
            return;
        }

        $pk_value = Request::post('pk_value');
        $data = Request::post('data');

        if ($this->isAjaxRequest()) {
            header('Content-Type: application/json');

            if (!$pk_value || !$data) {
                echo json_encode(['success' => false, 'message' => 'Missing required data']);
                return;
            }

            if (TableModel::updateRow($database_name, $table_name, $pk_value, $data)) {
                echo json_encode([
                    'success' => true,
                    'message' => 'Row updated successfully'
                ]);
            } else {
                echo json_encode([
                    'success' => false,
                    'message' => 'Failed to update row'
                ]);
            }
            return;
        }

        Redirect::to('table/show/' . urlencode($database_name) . '/' . urlencode($table_name));
    }

    /**
     * Delete a row from the table (AJAX)
     * @param string $database_name
     * @param string $table_name
     */
    public function deleteRow($database_name = null, $table_name = null)
    {
        if (!$database_name || !$table_name) {
            if ($this->isAjaxRequest()) {
                header('Content-Type: application/json');
                echo json_encode(['success' => false, 'message' => 'Invalid parameters']);
                return;
            }
            Redirect::to('database/index');
            return;
        }

        $pk_value = Request::post('pk_value');

        if ($this->isAjaxRequest()) {
            header('Content-Type: application/json');

            if (!$pk_value) {
                echo json_encode(['success' => false, 'message' => 'Missing primary key value']);
                return;
            }

            if (TableModel::deleteRow($database_name, $table_name, $pk_value)) {
                echo json_encode([
                    'success' => true,
                    'message' => 'Row deleted successfully'
                ]);
            } else {
                echo json_encode([
                    'success' => false,
                    'message' => 'Failed to delete row'
                ]);
            }
            return;
        }

        Redirect::to('table/show/' . urlencode($database_name) . '/' . urlencode($table_name));
    }

    /**
     * Insert a new row into the table (AJAX)
     * @param string $database_name
     * @param string $table_name
     */
    public function insertRow($database_name = null, $table_name = null)
    {
        if (!$database_name || !$table_name) {
            if ($this->isAjaxRequest()) {
                header('Content-Type: application/json');
                echo json_encode(['success' => false, 'message' => 'Invalid parameters']);
                return;
            }
            Redirect::to('database/index');
            return;
        }

        $data = Request::post('data');

        if ($this->isAjaxRequest()) {
            header('Content-Type: application/json');

            if (!$data) {
                echo json_encode(['success' => false, 'message' => 'Missing row data']);
                return;
            }

            $insertId = TableModel::insertRow($database_name, $table_name, $data);
            if ($insertId !== false) {
                echo json_encode([
                    'success' => true,
                    'message' => 'Row inserted successfully',
                    'insert_id' => $insertId
                ]);
            } else {
                echo json_encode([
                    'success' => false,
                    'message' => 'Failed to insert row'
                ]);
            }
            return;
        }

        Redirect::to('table/show/' . urlencode($database_name) . '/' . urlencode($table_name));
    }

    /**
     * Check if the request is an AJAX request
     */
    private function isAjaxRequest()
    {
        return isset($_SERVER['HTTP_X_REQUESTED_WITH']) &&
               strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest';
    }

    /**
     * Export table as raw SQL text
     * @param string $database_name
     * @param string $table_name
     */
    public function export($database_name, $table_name)
    {
        header('Content-Type: text/plain; charset=utf-8');
        header('Content-Disposition: inline; filename="' . $table_name . '.sql"');

        echo DatabaseModel::exportTable($database_name, $table_name);
    }
}