<?php

namespace Drupal\session_management\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\session_management\Utilities;

/**
 * Login setting configuration form.
 */
class LoginSettingsForm extends ConfigFormBase
{

  public const SETTINGS = 'session_management.settings';

  /**
   * {@inheritDoc}
   */
  protected function getEditableConfigNames()
  {
    return [static::SETTINGS];
  }

  /**
   * {@inheritDoc}
   */
  public function getFormId()
  {
    return 'login-settings-form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state)
  {
    $config = $this->config(static::SETTINGS);

    $premium_tag = Utilities::getPremiumBadge();

    $form['libraries'] = [
      '#attached' => [
        'library' => [
          "session_management/session_management.mo_session",
        ],
      ],
    ];

    $form['login_restriction'] = [
      '#type' => 'details',
      '#open' => TRUE,
      '#title' => ('Login Restriction & Flood Control <a href="https://plugins.miniorange.com/configure-login-restriction-in-drupal-session-management" target="_blank">How to configure?</a>'),
    ];


    $form['login_restriction']['restriction'] = [
      '#type' => 'vertical_tabs',
    ];

    $form['flood_control'] = [
      '#type' => 'details',
      '#group' => 'restriction',
      '#title' => ('Flood control settings'),
      // '#description' => $this->t('Manage settings to prevent users from attempting too many login attempts in a short period of time.'),
    ];

    $form['flood_control']['enable_flood_control'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Enable flood control ' . $premium_tag),
      '#description' => $this->t('Enable automatic protection that temporarily blocks users or IPs that make too many requests in a short time (e.g. repeated failed logins).'),
      '#default_value' => 0, // Default to enabled.
      '#disabled' => false,
    ];

    $form['flood_control']['login_attempts_limit'] = [
      '#type' => 'textfield',
      '#title' => ('Login attempts limit'),
      '#description' => $this->t('Set the maximum number of login attempts allowed before triggering flood control.'),
      '#default_value' => '5',
      '#states' => [
        'visible' => [
          ':input[name="enable_flood_control"]' => ['checked' => TRUE],
        ],
      ],
      '#attributes' => [
        'placeholder' => 'e.g., 5',
      ],
      '#disabled' => true,
    ];

    $form['flood_control']['time_window'] = [
      '#type' => 'textfield',
      '#title' => ('Time window (minutes)'),
      '#description' => $this->t('Set the time window (in minutes) during which the login attempts limit is enforced.'),
      '#default_value' => '15',
      '#states' => [
        'visible' => [
          ':input[name="enable_flood_control"]' => ['checked' => TRUE],
        ],
      ],
      '#attributes' => [
        'placeholder' => 'e.g., 15',
      ],
      '#disabled' => true,
    ];

    $form['flood_control']['block_duration'] = [
      '#type' => 'textfield',
      '#title' => ('Block duration (minutes)'),
      '#description' => $this->t('Set the duration (in minutes) for which a user will be blocked from logging in after exceeding the login attempts limit.'),
      '#default_value' => '30',
      '#states' => [
        'visible' => [
          ':input[name="enable_flood_control"]' => ['checked' => TRUE],
        ],
      ],
      '#attributes' => [
        'placeholder' => 'e.g., 30',
      ],
      '#disabled' => true,
    ];

    $form['flood_control']['flood_message'] = [
      '#type' => 'textarea',
      '#title' => ('Custom error message'),
      '#description' => $this->t('Enter a custom error message to display when a user is blocked due to too many login attempts.'),
      '#default_value' => $this->t('Access denied due to too many failed login attempts. Please try again later.'),
      '#states' => [
        'visible' => [
          ':input[name="enable_flood_control"]' => ['checked' => TRUE],
        ],
      ],
      '#rows' => 1,
      '#disabled' => true,
    ];

    // Admin Bypass
    $form['flood_control']['admin_bypass'] = [
      '#type' => 'checkbox',
      '#title' => ('Admin bypass'),
      '#description' => $this->t('Allow users with administrative roles to bypass flood control.'),
      '#default_value' => 0,
      '#states' => [
        'visible' => [
          ':input[name="enable_flood_control"]' => ['checked' => TRUE],
        ],
      ],
      '#disabled' => true,
    ];

    // Notification
    $form['flood_control']['notify_admin'] = [
      '#type' => 'checkbox',
      '#title' => ('Notify admin on block'),
      '#description' => $this->t('Send a notification to the site administrator when a user is blocked.'),
      '#default_value' => 0,
      '#states' => [
        'visible' => [
          ':input[name="enable_flood_control"]' => ['checked' => TRUE],
        ],
      ],
      '#disabled' => true,
    ];

    // IP Whitelisting
    $form['flood_control']['whitelisted_ips'] = [
      '#type' => 'textarea',
      '#title' => ('Whitelisted IP addresses'),
      '#description' => $this->t('Enter IP addresses that are allowed to bypass flood control, one per line.'),
      '#default_value' => '',
      '#states' => [
        'visible' => [
          ':input[name="enable_flood_control"]' => ['checked' => TRUE],
        ],
      ],
      '#rows' => 3,
      '#attributes' => [
        'placeholder' => 'e.g., 192.168.0.1',
      ],
      '#disabled' => true,
    ];

    // Logging
    $form['flood_control']['enable_logging'] = [
      '#type' => 'checkbox',
      '#title' => ('Enable logging'),
      '#description' => $this->t('Log flood control events for review and auditing.'),
      '#default_value' => 0,
      '#states' => [
        'visible' => [
          ':input[name="enable_flood_control"]' => ['checked' => TRUE],
        ],
      ],
      '#disabled' => true,
    ];

    // IP-Based Restriction
    $form['ip_restriction'] = [
      '#type' => 'details',
      '#title' => ('IP-based restriction'),
      '#description' => $this->t('Control user access by allowing logins only from specific IP addresses or ranges. This helps ensure that only users from approved locations can access your site.'),
      '#group' => 'restriction',
      '#disabled' => false,
    ];

    $form['ip_restriction']['ip_login_restriction'] = [
      '#type' => 'checkbox',
      '#title' => ('Enable IP-based login restriction.'),
      '#default_value' => $config->get('ip_login_restriction') ?? false,
    ];

    $form['ip_restriction']['ip_range_list'] = [
      '#type' => 'textarea',
      '#title' => ("Allowed IP ranges"),
      '#description' => '<i>' . $this->t('List of allowed IP addresses or ranges (one per line). Example: 192.168.0.1 or 192.168.0.0/24') . '</i>',
      '#rows' => 2,
      '#default_value' => is_array($config->get('ip_range_list')) ? implode("\n", $config->get('ip_range_list')) : '',
    ];

    $form['ip_restriction']['ip_message'] = [
      '#type' => 'textarea',
      '#title' => ("Error message"),
      '#description' => $this->t('Error message shown when a user tries to log in from an unauthorized IP address.'),
      '#default_value' => !empty($config->get('ip_message')) ? $config->get('ip_message') : $this->t('Access denied. Your IP address is not authorized to access this site.'),
      '#rows' => 1,
    ];

    // Country-Based Restriction
    $form['country_restriction'] = [
      '#type' => 'details',
      '#title' => ('Country-based restriction'),
      '#group' => 'restriction',
      '#disabled' => true,
    ];

    $form['country_restriction']['country_login_restriction'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Enable Country-based login restriction. ' . $premium_tag),
      '#default_value' => $config->get('country_login_restriction') ?? false,
      '#disabled' => true,
      '#description' => $this->t('Limit user logins based on their geographical location. Only users from selected countries will be able to log in, providing an extra layer of security.'),
    ];

    $form['country_restriction']['allowed_countries'] = [
      '#type' => 'select',
      '#title' => ('Select countries'),
      '#description' => $this->t('Select countries.'),
      '#options' => $this->getCountryOptions(),
      '#default_value' => $config->get('allowed_countries') ?? [],
      '#multiple' => TRUE,
      '#size' => 10,
      '#disabled' => true,
    ];

    // Default access behavior.
    $form['country_restriction']['default_behavior'] = [
      '#type' => 'radios',
      '#title' => ('Default access behavior'),
      '#description' => $this->t('Choose the default behavior for login access.'),
      '#options' => [
        'allow' => $this->t('Allow login from all countries except the selected ones.'),
        'restrict' => $this->t('Restrict login to only the selected countries.'),
      ],
      '#default_value' => $config->get('default_behavior') ?? 'allow',
      '#disabled' => true,
    ];

    $form['country_restriction']['country_message'] = [
      '#type' => 'textarea',
      '#title' => ("Error message"),
      '#description' => $this->t('Error message shown when a user tries to log in from a restricted country.'),
      '#default_value' => $this->t('Access denied. Logins from your country are not permitted.'),
      '#rows' => 1,
      '#disabled' => true,
    ];

    // Device-Based Restriction
    $form['device_restriction'] = [
      '#type' => 'details',
      '#title' => ('Device-based restriction'),
      '#group' => 'restriction',
      '#disabled' => true,
    ];

    $form['device_restriction']['device_login_restriction'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Enable Device-based login restriction. ' . $premium_tag),
      '#default_value' => $config->get('device_login_restriction') ?? false,
      '#disabled' => true,
      '#description' => $this->t('Manage user access by restricting logins to approved devices. Users can only log in from devices that have been authorized, enhancing site security.'),
    ];

    $form['device_restriction']['device_list'] = [
      '#type' => 'textarea',
      '#title' => ('Allowed devices'),
      '#description' => '<i>' . $this->t('List of allowed devices (one per line). Example: iPhone, Windows PC') . '</i>',
      '#rows' => 2,
    ];

    $form['device_restriction']['device_message'] = [
      '#type' => 'textarea',
      '#title' => ("Error message"),
      '#description' => $this->t('Error message shown when a user tries to log in from an unauthorized device.'),
      '#default_value' => $this->t('Access denied. Your device is not authorized to access this site.'),
      '#rows' => 1,
      '#disabled' => true,
    ];


    //Time based access control

    $form['time_based_access_control'] = [
      '#type' => 'details',
      '#group' => 'restriction',
      '#title' => ('Time-based access control ' . $premium_tag),
    ];

    $form['time_based_access_control']['absolute_access_control'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Enable absolute time-based access control ' . $premium_tag),
      '#description' => $this->t('When enabled, you can set a fixed start and end date/time so the resource is available only during that exact period.'),
      '#disabled' => true,
    ];

    $form['time_based_access_control']['absolute_access_control_start'] = [
      '#type' => 'datetime',
      '#title' => ('Start date/time'),
      '#states' => [
        'visible' => [
          ':input[name="absolute_access_control"]' => ['checked' => TRUE],
        ],
      ],
      '#disabled' => true
    ];

    $form['time_based_access_control']['absolute_access_control_end'] = [
      '#type' => 'datetime',
      '#title' => ('End date/time'),
      '#states' => [
        'visible' => [
          ':input[name="absolute_access_control"]' => ['checked' => TRUE],
        ],
      ],
      '#disabled' => true
    ];

    $form['time_based_access_control']['periodic_access_control'] = [
      '#type' => 'checkbox',
      '#title' =>$this->t('Enable periodic time-based access control' . $premium_tag),
      '#description' => $this->t('Set access rules based on recurring schedules (e.g., daily, weekly).'),
      '#default_value' => 0,
      '#disabled' => false
    ];

    $form['time_based_access_control']['periodic_access_control_frequency'] = [
      '#type' => 'select',
      '#title' => ('Schedule frequency'),
      '#options' => [
        'daily' => $this->t('Daily'),
        'weekly' => $this->t('Weekly'),
        'monthly' => $this->t('Monthly'),
      ],
      '#states' => [
        'visible' => [
          ':input[name="periodic_access_control"]' => ['checked' => TRUE],
        ],
      ],
      '#disabled' => false
    ];

    $form['time_based_access_control']['periodic_access_control_time_range'] = [
      '#type' => 'fieldset',
      '#title' => ('Time range'),
      '#states' => [
        'visible' => [
          ':input[name="periodic_access_control"]' => ['checked' => TRUE],
        ],
      ],
    ];

    $form['time_based_access_control']['periodic_access_control_time_range']['periodic_access_control_start'] = [
      '#type' => 'datetime',
      '#title' => ('Start date/time'),
      '#states' => [
        'visible' => [
          ':input[name="periodic_access_control"]' => ['checked' => TRUE],
        ],
      ],
      '#disabled' => true
    ];

    $form['time_based_access_control']['periodic_access_control_time_range']['periodic_access_control_end'] = [
      '#type' => 'datetime',
      '#title' => ('End date/time'),
      '#states' => [
        'visible' => [
          ':input[name="periodic_access_control"]' => ['checked' => TRUE],
        ],
      ],
      '#disabled' => true
    ];


    $form['time_based_access_control']['periodic_access_control_time_range']['start_time'] = [
      '#type' => 'time',
      '#title' => ('Start time'),
    ];

    $form['time_based_access_control']['periodic_access_control_time_range']['end_time'] = [
      '#type' => 'time',
      '#title' => ('End time'),
    ];

    $form['time_based_access_control']['periodic_access_control_days'] = [
      '#type' => 'checkboxes',
      '#title' => ('Days of the week'),
      '#options' => [
        'monday' => $this->t('Monday'),
        'tuesday' => $this->t('Tuesday'),
        'wednesday' => $this->t('Wednesday'),
        'thursday' => $this->t('Thursday'),
        'friday' => $this->t('Friday'),
        'saturday' => $this->t('Saturday'),
        'sunday' => $this->t('Sunday'),
      ],
      '#states' => [
        'visible' => [
          ':input[name="periodic_access_control_frequency"]' => ['value' => 'weekly'],
        ],
      ],
      '#disabled' => true
    ];

    $form['login_restriction']['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Save configuration'),
      '#button_type' => 'primary',  
    ];

    Utilities::addSupportButton($form, $form_state);

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {}

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state)
  {
    $form_values = $form_state->getValues();
    $config = $this->configFactory()->getEditable(self::SETTINGS);

    $config->set('ip_login_restriction', $form_values['ip_login_restriction'])
      ->set('ip_range_list', $this->linesToArray($form_values['ip_range_list']))
      ->set('ip_message', $form_values['ip_message'])
      ->save();

    $this->messenger()->addStatus($this->t("Configuration saved successfully."));
  }

  public function linesToArray(string $lines): array
  {
    $lines = trim($lines);
    $splitLines = [];

    if ($lines) {
      $splitLines = preg_split('/[\n\r]+/', $lines);
      if ($splitLines !== FALSE) {
        foreach ($splitLines as $i => $value) {
          $splitLines[$i] = trim($value);
        }
      }
    }

    return $splitLines;
  }
  /**
   * Helper function to get the list of country options.
   */
  protected function getCountryOptions()
  {
    return \Drupal::service('country_manager')->getList();
  }
}
