<?php
/**
 * @package     MefisAssetBridge
 * @subpackage  Joomla_Administrator_Component
 *
 * @copyright   Copyright (C) 2025 Goran Usljebrka. All rights reserved.
 * @license     Proprietary — No resale or incorporation into other projects without explicit written permission. see LICENSE.txt
 */

namespace Mefi\Component\MefisAssetBridge\Administrator\Controller;

defined('_JEXEC') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Log\Log;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Session\Session;
use Joomla\CMS\Response\JsonResponse;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\MVC\Controller\BaseController;
use Mefi\Component\MefisAssetBridge\Administrator\Traits\CoreBridgeTrait;

/**
 * Auth Controller
 *
 * @since  1.0.0
 */
class AuthController extends BaseController
{
    use CoreBridgeTrait;
    /**
     * Authentication helper
     *
     * @var    AuthHelper
     * @since  1.0.0
     */
    protected $authHelper;

    /**
     * Constructor.
     *
     * @param   array                $config   An optional associative array of configuration settings.
     * @param   MVCFactoryInterface  $factory  The factory.
     * @param   CMSApplication       $app      The JApplication for the dispatcher
     * @param   Input                $input    Input
     *
     * @since   1.0.0
     */
    public function __construct($config = [], $factory = null, $app = null, $input = null)
    {
        parent::__construct($config, $factory, $app, $input);

        if (! $this->isAppRegistered()) {
            $this->setRedirect(Route::_('index.php?option=com_mefisassetbridge&view=problems', false), Text::_('COM_MEFISASSETBRIDGE_APP_NOT_REGISTERED'), 'error');
            return;
        }

    }

    /**
     * Authenticate with the remote server
     *
     * @return void
     *
     * @since 1.0.0
     */
    public function authenticate()
    {

        $app   = $this->app;
        $input = $app->input;

        $format = trim($input->getString('format', 'html'));

        // Check form token
        if ($format === 'json') {

            if (! Session::checkToken('request')) {
                echo new JsonResponse(null, Text::_('JINVALID_TOKEN'), true); $app->close(); return;
            }

        } else {
            $this->checkToken();
        }

        // Get form data
        $email     = trim($input->getString('email', ''));
        $password  = trim($input->getString('password', ''));
        $masterKey = trim($input->getString('master_key', ''));

        $remember = ComponentHelper::getComponent('com_mefisassetbridge')->getParams()->get('keep_signed_in', false);

        if (empty($masterKey) || strlen($masterKey) < 4 || strlen($masterKey) > 16) {

            if ($format === 'json') {
                echo new JsonResponse(null, Text::_('COM_MEFISASSETBRIDGE_AUTH_MASTER_KEY_REQUIRED_ERROR'), true); $app->close();
                return;
            }

            $app->enqueueMessage(Text::_('COM_MEFISASSETBRIDGE_AUTH_MASTER_KEY_REQUIRED_ERROR'), 'error');
            $this->setRedirect(
                Route::_('index.php?option=com_mefisassetbridge&view=auth&tab=login&email=' . urlencode($email) . '&returnurl=' . urlencode($input->getString('returnurl', '')), false)
            );
            return;
        }

        // master key must not contain dot "."
        if (strpos($masterKey, '.') !== false) {

            if ($format === 'json') {
                echo new JsonResponse(null, Text::_('COM_MEFISASSETBRIDGE_AUTH_MASTER_KEY_DOT_ERROR'), true); $app->close();
                return;
            }

            $app->enqueueMessage(Text::_('COM_MEFISASSETBRIDGE_AUTH_MASTER_KEY_DOT_ERROR'), 'error');
            $this->setRedirect(
                Route::_('index.php?option=com_mefisassetbridge&view=auth&tab=login&email=' . urlencode($email) . '&returnurl=' . urlencode($input->getString('returnurl', '')), false)
            );
            return;
        }

        // trim to 16 chars
        $masterKey = substr(trim($masterKey), 0, 16);

        $returnUrl = $input->getString('returnurl', Route::_('index.php?option=com_mefisassetbridge&view=dashboard', false));
        if ($returnUrl == '') {
            $returnUrl = Route::_('index.php?option=com_mefisassetbridge&view=dashboard', false);
        }
        try {
            // Use the trait method to perform login - returns AuthenticatedUserDto
            $userDto = $this->coreLogin($email, $password);

            $userDto->setMasterKey($masterKey);

            // Store in session
            $this->setDataToSession($userDto);

            if ($remember) {
                $this->setMefisCookie($userDto->getToken()->getRefreshToken() . '.' . $masterKey);
            }

            if ($format === 'json') {
                echo new JsonResponse([
                    'user'         => $userDto->getUser() ? $userDto->getUser()->toArray() : null,
                    'subscription' => $userDto->getSubscription() ? $userDto->getSubscription()->toArray() : null,
                ], Text::_('COM_MEFISASSETBRIDGE_AUTH_SUCCESS'), false); $app->close();
                return;
            }

            $app->enqueueMessage(Text::_('COM_MEFISASSETBRIDGE_AUTH_SUCCESS'), 'success');

            // Redirect to dashboard
            $this->setRedirect($returnUrl);

        } catch (\Exception $e) {

            // force logout
            if ($e->getMessage() == 'Unauthorized') {
                $message      = 'Website Not Authorized. If this error persists, please contact support.';
                $messageLevel = 'info';
                $app->getSession()->set('mefisAssetBridge.auth', null);
                $app->getSession()->set('mefisAssetBridge.authenticated', false);
            } else {
                $message      = $e->getMessage();
                $messageLevel = 'error';
            }

            if ($format === 'json') {
                echo new JsonResponse(null, $message, true); $app->close(); return;
            } else {
                $app->enqueueMessage($message, $messageLevel);
                $this->setRedirect(
                    Route::_('index.php?option=com_mefisassetbridge&view=auth&tab=login&email=' . urlencode($email) . '&returnurl=' . urlencode($returnUrl), false)
                );
            }


        }
    }

    public function register()
    {

        $app    = $this->app;
        $input  = $app->input;
        $format = trim($input->getString('format', 'html'));

        // Check form token
        if ($format === 'json') {

            if (! Session::checkToken('request')) {
                echo new JsonResponse(null, Text::_('JINVALID_TOKEN'), true);
                $app->close(); return;
            }

        } else {
            $this->checkToken();
        }

        $name            = trim($input->getString('name', ''));
        $email           = trim($input->getString('email', ''));
        $password        = trim($input->getString('password', ''));
        $passwordConfirm = trim($input->getString('password_confirm', ''));

        try {
            // Use the trait method to register
            $response = $this->coreRegister($name, $email, $password, $passwordConfirm);

            if ($response->isSuccess()) {

                if ($format === 'json') {
                    echo new JsonResponse(null, Text::_('COM_MEFISASSETBRIDGE_AUTH_REGISTER_SUCCESS'), false); $app->close();
                    return;
                }

                // continue for html view
                $app->enqueueMessage(Text::_('COM_MEFISASSETBRIDGE_AUTH_REGISTER_SUCCESS'), 'success');

                // Redirect to login tab
                $this->setRedirect(
                    Route::_('index.php?option=com_mefisassetbridge&view=auth&tab=login', false)
                );
            } else {
                $message = $response->getMessage() ?: Text::_('COM_MEFISASSETBRIDGE_AUTH_REGISTER_FAILED');
                if($response->getStatusCode() == 409) {
                    $message = Text::_('COM_MEFISASSETBRIDGE_AUTH_REGISTER_EMAIL_EXISTS');
                }
                if ($format === 'json') {
                    echo new JsonResponse(null, $message, true); $app->close();
                    return;
                }


                $app->enqueueMessage($message, 'error');
                $this->setRedirect(
                    Route::_(
                        'index.php?option=com_mefisassetbridge&view=auth&tab=register'
                        . '&name=' . urlencode($name)
                        . '&email=' . urlencode($email),
                        false
                    )
                );
            }
        } catch (\Exception $e) {

            $message = $e->getMessage();

            if ($format === 'json') {
                echo new JsonResponse(null, $message, true); $app->close();
                return;
            }


            $app->enqueueMessage($message, 'error');
            $this->setRedirect(
                Route::_(
                    'index.php?option=com_mefisassetbridge&view=auth&tab=register'
                    . '&name=' . urlencode($name)
                    . '&email=' . urlencode($email),
                    false
                )
            );
        }
    }

    public function reset()
    {

        $app   = $this->app;
        $input = $app->input;
        $format = trim($input->getString('format', 'html'));
        // Check form token
        if ($format === 'json') {

            if (! Session::checkToken('request')) {
                echo new JsonResponse(null, Text::_('JINVALID_TOKEN'), true); $app->close();
                $app->close();
            }

        } else {
            $this->checkToken();
        }
        // Get form data
        $email = trim($input->getString('email', ''));

        try {
            // Use the trait method to register
            $response = $this->coreReset($email);

            if ($response->isSuccess()) {

                // if json request, end here
                if ($format === 'json') {
                    echo new JsonResponse(null, Text::_('COM_MEFISASSETBRIDGE_AUTH_RESET_SUCCESS'), false); $app->close();
                    return;
                }

                $app->enqueueMessage(Text::_('COM_MEFISASSETBRIDGE_AUTH_RESET_SUCCESS'), 'success');

                // Redirect to login tab
                $this->setRedirect(
                    Route::_('index.php?option=com_mefisassetbridge&view=auth&tab=login', false)
                );
            } else {
                $message = $response->getMessage() ?: Text::_('COM_MEFISASSETBRIDGE_AUTH_RESET_FAILED');

                // if json request, end here
                if ($format === 'json') {
                    echo new JsonResponse(null, $message, true); $app->close();
                    return;
                }

                $app->enqueueMessage($message, 'error');
                $this->setRedirect(
                    Route::_(
                        'index.php?option=com_mefisassetbridge&view=auth&tab=reset'
                        . '&email=' . urlencode($email),
                        false
                    )
                );
            }
        } catch (\Exception $e) {
            $message = $e->getMessage();
            // if json request, end here
            if ($format === 'json') {
                echo new JsonResponse(null, $message, true); $app->close();
                return;
            }
            $app->enqueueMessage($message, 'error');
            $this->setRedirect(
                Route::_(
                    'index.php?option=com_mefisassetbridge&view=auth&tab=reset'
                    . '&email=' . urlencode($email),
                    false
                )
            );
        }
    }

    /**
     * Logout from the system
     *
     * @return  void
     *
     * @since   1.0.0
     */
    public function logout()
    {
        $app = $this->app;

        $userDto = $this->getDataFromSession();

        if ($userDto === null) {
            $this->setRedirect(
                Route::_('index.php?option=com_mefisassetbridge&view=auth', false)
            );
            return;
        }

        // Store in session
        $this->app->getSession()->set('mefisAssetBridge.auth', null);

        // Set authenticated flag for quick checking
        $this->app->getSession()->set('mefisAssetBridge.authenticated', false);

        // kill cookie
        $this->clearMefisCookie();

        $app->enqueueMessage(Text::_('COM_MEFISASSETBRIDGE_LOGOUT_SUCCESS'), 'info');

        $returnUrl = $this->app->input->getString('returnurl', Route::_('index.php?option=com_mefisassetbridge&view=auth', false));

        // Redirect to auth page
        $this->setRedirect(
            Route::_($returnUrl, false)
        );
    }
}
