<?php

namespace Drupal\straker_translate\Controller;

use Drupal\straker_translate\Form\StrakerTranslateSettingsAccountForm;
use Drupal\straker_translate\Form\StrakerTranslateSettingsWorkflowsForm;
use Drupal\straker_translate\Form\StrakerTranslateSettingsConnectForm;
use Drupal\straker_translate\Form\StrakerTranslateSettingsDefaultsForm;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;

/**
 * Returns responses for straker_translate module setup routes.
 */
class StrakerTranslateSetupController extends StrakerTranslateControllerBase {

  /**
   * Presents a connection page to Straker Translate Services.
   *
   * @return array
   *   The connection form.
   */
  public function accountPage() {
    if ($this->setupCompleted()) {
      return $this->formBuilder->getForm(StrakerTranslateSettingsAccountForm::class);
    }
    return [
      '#type' => 'markup',
      'markup' => $this->formBuilder->getForm(StrakerTranslateSettingsConnectForm::class),
    ];
  }

  /**
   *
   */
  public function handshake(Request $request) {
    $access_token = $request->get('access_token');
    if ($access_token != NULL and $access_token != "") {
      $accountConfig = \Drupal::configFactory()->getEditable('straker_translate.account');

      // Keep track of old access token to restore it if the new one is invalid.
      $old_access_token = $accountConfig->get('access_token');

      // Save new access token, poll account info and save it.
      $accountConfig->set('access_token', $access_token);
      $accountConfig->save();

      $account_info = $this->fetchAccountInfo();

      // If newly saved token/info is valid, proceed to community page.
      if ($accountConfig->get('access_token') && !empty($account_info)) {
        $this->logger->notice('Account connected to Straker Translate.');
        $this->messenger()->addStatus($this->t('Your account settings have been saved.'));
        return $this->redirect('straker_translate.setup_workflow');
      }

      \Drupal::messenger()->deleteAll();
      // If new token/info is invalid, poll account info for old token.
      $accountConfig->set('access_token', $old_access_token);
      $accountConfig->save();
      $account_info = $this->fetchAccountInfo();

      // If old token's info is valid, save it the corresponding account info.
      if ($account_info) {
        $this->saveAccountInfo($account_info);
        \Drupal::messenger()->addError(t('Your configuration has not been changed. Please try again.'));
      }
      else {
        // If old token's info is invalid, wipe out the invalid token and info from system.
        $accountConfig->set('access_token', NULL);
        $accountConfig->save();
        $this->saveAccountInfo(NULL);
        \Drupal::messenger()->addError(t('Invalid access token. This indicates either no access token has been set up yet or that the previously used token has expired. Kindly generate a new access token using the link provided in the section below.'));
      }
      return $this->redirect('straker_translate.access_token_update');
    }
    return new JsonResponse([
      'status' => FALSE,
      'message' => 'Account not connected to Straker Translate.',
    ]);
  }

  /**
   *
   */
  public function workflowPage() {
    if ($redirect = $this->checkSetup()) {
      $this->messenger()->deleteAll();
      $this->messenger()->addError($this->t('There was a problem connecting your account. Please ensure your access token is valid. If unsure, please generate a new access token from the link provided in the section below.'));
      return $redirect;
    }
    $workflows = $this->straker_translate->getWorkflows(TRUE);
    if (empty($workflows)) {
      $this->logger->error('Account not connected to Straker Translate.');
      return $this->redirect('straker_translate.access_token_update');
    }
    $accountConfig = \Drupal::configFactory()->getEditable('straker_translate.account');
    $accountConfig->set('resources.workflow', $workflows);
    $accountConfig->save();
    if (count($workflows) == 1) {
      // No choice necessary. Save and advance to next page.
      $accountConfig->set('default.workflow', current(array_keys($workflows)));
      $accountConfig->save();
      // Update resources based on newly selected community.
      return $this->redirect('straker_translate.setup_defaults');
    }
    return [
      '#type' => 'markup',
      'markup' => $this->formBuilder->getForm(StrakerTranslateSettingsWorkflowsForm::class),
    ];
  }

  /**
   *
   */
  public function defaultsPage() {
    if ($redirect = $this->checkSetup()) {
      return $redirect;
    }
    $resources = $this->straker_translate->getResources();

    return [
      '#type' => 'markup',
      'markup' => $this->formBuilder->getForm(StrakerTranslateSettingsDefaultsForm::class),
    ];
  }

  /**
   *
   */
  protected function saveToken($token) {
    if (!empty($token)) {
      \Drupal::configFactory()->getEditable('straker_translate.account')->set('access_token', $token)->save();
    }
  }

  /**
   *
   */
  protected function saveAccountInfo($account_info) {
    if (!empty($account_info)) {
      $accountConfig = \Drupal::configFactory()->getEditable('straker_translate.account');
      $accountConfig->set('access_token', $account_info['access_token']);
      $accountConfig->save();
    }
  }

  /**
   *
   */
  protected function fetchAccountInfo() {
    return $this->straker_translate->getAccountInfo();
  }

}
