<?php

declare(strict_types=1);

namespace PortalPeople\datadash\controllers;

use PortalPeople\datadash\models\ConfigForm;
use Yii;
use yii\filters\AccessControl;
use yii\filters\VerbFilter;
use yii\web\Controller;
use yii\web\Response;
use yii\widgets\ActiveForm;

/**
 * ConfigController
 *
 * Provides the web-based setup UI for the ngauge-datadash external database
 * connection.  Accessible at /ngauge-datadash/config/index.
 */
class ConfigController extends Controller
{
    public function behaviors(): array
    {
        return [
            'access' => [
                'class' => AccessControl::class,
                'rules' => [
                    [
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                ],
            ],
            'verbs' => [
                'class' => VerbFilter::class,
                'actions' => [
                    'validate'       => ['POST'],
                    'test-connection'=> ['POST'],
                    'list-tables'    => ['POST'],
                    'save'           => ['POST'],
                ],
            ],
        ];
    }

    // ─── Index ─────────────────────────────────────────────────────────────────

    /**
     * Display and handle the configuration form.
     *
     * @return string|Response
     */
    public function actionIndex()
    {
        $model = new ConfigForm();
        $model->loadFromParams();

        $request = Yii::$app->request;

        if ($model->load($request->post()) && $model->validate()) {
            if ($model->saveToParams()) {
                Yii::$app->session->setFlash('success', 'DataDash database configuration saved successfully.');
                return $this->refresh();
            }

            Yii::$app->session->setFlash('error', 'Failed to write configuration — check params-local.php file permissions.');
        }

        return $this->render('index', ['model' => $model]);
    }

    // ─── AJAX validation ───────────────────────────────────────────────────────

    /**
     * Return ActiveForm JSON validation errors.
     *
     * @return array<string, list<string>>
     */
    public function actionValidate(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;

        $model = new ConfigForm();
        if ($model->load(Yii::$app->request->post())) {
            return ActiveForm::validate($model);
        }

        return [];
    }

    // ─── Test connection ───────────────────────────────────────────────────────

    /**
     * Attempt a live PDO connection with posted form values.
     * Returns a JSON response suitable for front-end display.
     *
     * @return array{success: bool, message: string, details?: array<string, mixed>}
     */
    public function actionTestConnection(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;

        $model = new ConfigForm();
        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
            return $model->testConnection();
        }

        return [
            'success' => false,
            'message' => 'Invalid form data — please correct the errors and try again.',
            'errors'  => $model->errors,
        ];
    }

    // ─── List tables ───────────────────────────────────────────────────────────

    /**
     * Connect with posted (or saved) credentials and return a table-size report.
     *
     * @return array{success: bool, message: string, tables?: list<array<string, mixed>>}
     */
    public function actionListTables(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;

        $model = new ConfigForm();

        // Accept live form values if posted; fall back to saved config
        $post = Yii::$app->request->post();
        if (!empty($post)) {
            $model->load($post);
        } else {
            $model->loadFromParams();
        }

        if (!$model->validate()) {
            return [
                'success' => false,
                'message' => 'Invalid configuration — please correct the errors and try again.',
                'errors'  => $model->errors,
            ];
        }

        return $model->listTables();
    }
}
