<script lang="ts">
  import _ from 'lodash';
  import FormStyledButton from '../buttons/FormStyledButton.svelte';
  import Link from '../elements/Link.svelte';
  import TabControl from '../elements/TabControl.svelte';
  import CheckboxField from '../forms/CheckboxField.svelte';

  import FormCheckboxField from '../forms/FormCheckboxField.svelte';
  import FormFieldTemplateLarge from '../forms/FormFieldTemplateLarge.svelte';
  import FormSelectField from '../forms/FormSelectField.svelte';
  import FormTextField from '../forms/FormTextField.svelte';
  import FormValues from '../forms/FormValues.svelte';
  import SelectField from '../forms/SelectField.svelte';
  import SettingsFormProvider from '../forms/SettingsFormProvider.svelte';
  import TextField from '../forms/TextField.svelte';
  import FontIcon from '../icons/FontIcon.svelte';

  import ModalBase from '../modals/ModalBase.svelte';
  import { closeCurrentModal } from '../modals/modalTools';
  import { EDITOR_KEYBINDINGS_MODES, EDITOR_THEMES, FONT_SIZES } from '../query/AceEditor.svelte';
  import SqlEditor from '../query/SqlEditor.svelte';
  import {
    currentEditorFontSize,
    currentEditorWrapEnabled,
    currentEditorTheme,
    currentEditorKeybindigMode,
    extensions,
    selectedWidget,
    lockedDatabaseMode,
    visibleWidgetSideBar,
  } from '../stores';
  import { isMac } from '../utility/common';
  import getElectron from '../utility/getElectron';
  import ThemeSkeleton from './ThemeSkeleton.svelte';
  import { isProApp } from '../utility/proTools';
  import FormTextAreaField from '../forms/FormTextAreaField.svelte';
  import { apiCall } from '../utility/api';
  import { useSettings } from '../utility/metadataLoaders';
  import { derived } from 'svelte/store';
  import { safeFormatDate } from 'dbgate-tools';
  import FormDefaultActionField from './FormDefaultActionField.svelte';

  const electron = getElectron();
  let restartWarning = false;
  let licenseKeyCheckResult = null;

  export let selectedTab = 0;

  const sqlPreview = `-- example query
SELECT
  MAX(Album.AlbumId) AS max_album,
  MAX(Album.Title) AS max_title,
  Artist.ArtistId,
  'album' AS test_string,
  123 AS test_number
FROM
  Album
  INNER JOIN Artist ON Album.ArtistId = Artist.ArtistId
GROUP BY
  Artist.ArtistId
ORDER BY
  Artist.Name ASC
  `;

  function openThemePlugins() {
    closeCurrentModal();
    $selectedWidget = 'plugins';
    $visibleWidgetSideBar = true;
  }

  const settings = useSettings();
  const settingsValues = derived(settings, $settings => {
    if (!$settings) {
      return {};
    }
    return $settings;
  });

  $: licenseKey = $settingsValues['other.licenseKey'];
  let checkedLicenseKey = false;
  $: if (licenseKey && !checkedLicenseKey) {
    checkedLicenseKey = true;
    apiCall('config/check-license', { licenseKey }).then(result => {
      licenseKeyCheckResult = result;
    });
  }
</script>

<SettingsFormProvider>
  <ModalBase {...$$restProps} noPadding>
    <div slot="header">Settings</div>

    <FormValues let:values>
      <TabControl
        bind:value={selectedTab}
        isInline
        tabs={[
          { label: 'General', slot: 1 },
          isProApp() && electron && { label: 'License', slot: 7 },
          { label: 'Connection', slot: 2 },
          { label: 'Themes', slot: 3 },
          { label: 'Default Actions', slot: 4 },
          { label: 'Confirmations', slot: 5 },
          { label: 'Other', slot: 6 },
        ]}
      >
        <svelte:fragment slot="1">
          {#if electron}
            <div class="heading">Appearance</div>
            <FormCheckboxField
              name="app.useNativeMenu"
              label={isMac() ? 'Use native window title' : 'Use system native menu'}
              on:change={() => {
                restartWarning = true;
              }}
            />
            {#if restartWarning}
              <div class="ml-5 mb-3">
                <FontIcon icon="img warn" /> Native menu settings will be applied after app restart
              </div>
            {/if}
          {/if}

          <div class="heading">Data grid</div>
          <FormTextField
            name="dataGrid.pageSize"
            label="Page size (number of rows for incremental loading, must be between 5 and 1000)"
            defaultValue="100"
          />
          <FormCheckboxField name="dataGrid.showHintColumns" label="Show foreign key hints" defaultValue={true} />
          <!-- <FormCheckboxField name="dataGrid.showHintColumns" label="Show foreign key hints" defaultValue={true} /> -->

          <FormCheckboxField name="dataGrid.thousandsSeparator" label="Use thousands separator for numbers" />

          <FormTextField
            name="dataGrid.defaultAutoRefreshInterval"
            label="Default grid auto refresh interval in seconds"
            defaultValue="10"
          />

          <div class="heading">SQL editor</div>

          <div class="flex">
            <div class="col-3">
              <FormSelectField
                label="SQL commands case"
                name="sqlEditor.sqlCommandsCase"
                isNative
                defaultValue="upperCase"
                options={[
                  { value: 'upperCase', label: 'UPPER CASE' },
                  { value: 'lowerCase', label: 'lower case' },
                ]}
              />
            </div>
            <div class="col-3">
              <FormFieldTemplateLarge label="Editor keybinds" type="combo">
                <SelectField
                  isNative
                  defaultValue="default"
                  options={EDITOR_KEYBINDINGS_MODES.map(mode => ({ label: mode.label, value: mode.value }))}
                  value={$currentEditorKeybindigMode}
                  on:change={e => ($currentEditorKeybindigMode = e.detail)}
                />
              </FormFieldTemplateLarge>
            </div>
            <div class="col-3">
              <FormFieldTemplateLarge label="Enable word wrap" type="combo">
                <CheckboxField
                  checked={$currentEditorWrapEnabled}
                  on:change={e => ($currentEditorWrapEnabled = e.target.checked)}
                />
              </FormFieldTemplateLarge>
            </div>
          </div>
        </svelte:fragment>
        <svelte:fragment slot="2">
          <div class="heading">Connection</div>

          <FormFieldTemplateLarge
            label="Show only tabs from selected database"
            type="checkbox"
            labelProps={{
              onClick: () => {
                $lockedDatabaseMode = !$lockedDatabaseMode;
              },
            }}
          >
            <CheckboxField checked={$lockedDatabaseMode} on:change={e => ($lockedDatabaseMode = e.target.checked)} />
          </FormFieldTemplateLarge>

          <FormCheckboxField
            name="connection.autoRefresh"
            label="Automatic refresh of database model on background"
            defaultValue={false}
          />
          <FormTextField
            name="connection.autoRefreshInterval"
            label="Interval between automatic DB structure reloads in seconds"
            defaultValue="30"
            disabled={values['connection.autoRefresh'] === false}
          />

          <div class="heading">Query sessions</div>
          <FormCheckboxField
            name="session.autoClose"
            label="Automatic close query sessions after period without any activity"
            defaultValue={true}
          />
          <FormTextField
            name="session.autoCloseTimeout"
            label="Interval, after which query session without activity is closed (in minutes)"
            defaultValue="15"
            disabled={values['session.autoClose'] === false}
          />
        </svelte:fragment>

        <svelte:fragment slot="3">
          <div class="heading">Application theme</div>
          <div class="themes">
            {#each $extensions.themes as theme}
              <ThemeSkeleton {theme} />
            {/each}
          </div>

          <div class="m-5">
            More themes are available as <Link onClick={openThemePlugins}>plugins</Link>
            <br />
            After installing theme plugin (try search "theme" in available extensions) new themes will be available here.
          </div>

          <div class="heading">Editor theme</div>

          <div class="flex">
            <div class="col-3">
              <FormFieldTemplateLarge label="Theme" type="combo">
                <SelectField
                  isNative
                  notSelected="(use theme default)"
                  options={EDITOR_THEMES.map(theme => ({ label: theme, value: theme }))}
                  value={$currentEditorTheme}
                  on:change={e => ($currentEditorTheme = e.detail)}
                />
              </FormFieldTemplateLarge>
            </div>

            <div class="col-3">
              <FormFieldTemplateLarge label="Font size " type="combo">
                <SelectField
                  isNative
                  notSelected="(default)"
                  options={FONT_SIZES}
                  value={FONT_SIZES.find(x => x.value == $currentEditorFontSize) ? $currentEditorFontSize : 'custom'}
                  on:change={e => ($currentEditorFontSize = e.detail)}
                />
              </FormFieldTemplateLarge>
            </div>

            <div class="col-3">
              <FormFieldTemplateLarge label="Custom size " type="text">
                <TextField
                  value={$currentEditorFontSize == 'custom' ? '' : $currentEditorFontSize}
                  on:change={e => ($currentEditorFontSize = e.target['value'])}
                  disabled={!!FONT_SIZES.find(x => x.value == $currentEditorFontSize) &&
                    $currentEditorFontSize != 'custom'}
                />
              </FormFieldTemplateLarge>
            </div>

            <div class="col-3">
              <FormTextField name="editor.fontFamily" label="Editor font family" />
            </div>
          </div>

          <div class="editor">
            <SqlEditor value={sqlPreview} readOnly />
          </div>
        </svelte:fragment>
        <svelte:fragment slot="4">
          <div class="heading">Default actions</div>
          <FormCheckboxField name="defaultAction.useLastUsedAction" label="Use last used action" defaultValue={true} />

          <FormDefaultActionField
            label="Table click"
            objectTypeField="tables"
            disabled={values['defaultAction.useLastUsedAction'] !== false}
          />
          <FormDefaultActionField
            label="View click"
            objectTypeField="views"
            disabled={values['defaultAction.useLastUsedAction'] !== false}
          />
          <FormDefaultActionField
            label="Materialized view click"
            objectTypeField="matviews"
            disabled={values['defaultAction.useLastUsedAction'] !== false}
          />
          <FormDefaultActionField
            label="Procedure click"
            objectTypeField="procedures"
            disabled={values['defaultAction.useLastUsedAction'] !== false}
          />
          <FormDefaultActionField
            label="Function click"
            objectTypeField="functions"
            disabled={values['defaultAction.useLastUsedAction'] !== false}
          />
        </svelte:fragment>
        <svelte:fragment slot="5">
          <div class="heading">Confirmations</div>

          <FormCheckboxField name="skipConfirm.tableDataSave" label="Skip confirmation when saving table data (SQL)" />
          <FormCheckboxField
            name="skipConfirm.collectionDataSave"
            label="Skip confirmation when saving collection data (NoSQL)"
          />
        </svelte:fragment>
        <svelte:fragment slot="6">
          <div class="heading">Other</div>

          <FormTextField name="other.gistCreateToken" label="API token for creating error gists" defaultValue="" />

          <FormSelectField
            label="Auto update application"
            name="app.autoUpdateMode"
            isNative
            defaultValue=""
            options={[
              { value: 'skip', label: 'Do not check for new versions' },
              { value: '', label: 'Check for new versions' },
              { value: 'download', label: 'Check and download new versions' },
            ]}
          />
        </svelte:fragment>

        <svelte:fragment slot="7">
          <div class="heading">License</div>
          <FormTextAreaField
            name="other.licenseKey"
            label="License key"
            rows={7}
            onChange={async value => {
              licenseKeyCheckResult = await apiCall('config/check-license', { licenseKey: value });
            }}
          />
          {#if licenseKeyCheckResult}
            <div class="m-3 ml-5">
              {#if licenseKeyCheckResult.status == 'ok'}
                <div>
                  <FontIcon icon="img ok" /> License key is valid
                </div>
                {#if licenseKeyCheckResult.validTo}
                  <div>
                    License valid to: {licenseKeyCheckResult.validTo}
                  </div>
                {/if}
                {#if licenseKeyCheckResult.expiration}
                  <div>License key expiration: <b>{safeFormatDate(licenseKeyCheckResult.expiration)}</b></div>
                {/if}
              {:else if licenseKeyCheckResult.status == 'error'}
                <FontIcon icon="img error" /> License key is invalid
              {/if}
            </div>
          {/if}
        </svelte:fragment>
      </TabControl>
    </FormValues>

    <div slot="footer">
      <!-- <FormSubmit value="OK" on:click={handleOk} /> -->
      <FormStyledButton value="Close" on:click={closeCurrentModal} />
    </div>
  </ModalBase>
</SettingsFormProvider>

<style>
  .heading {
    font-size: 20px;
    margin: 5px;
    margin-left: var(--dim-large-form-margin);
    margin-top: var(--dim-large-form-margin);
  }

  .themes {
    overflow-x: scroll;
    display: flex;
  }

  .editor {
    position: relative;
    height: 200px;
    width: 400px;
    margin-left: var(--dim-large-form-margin);
  }
</style>
