import { html, LitElement, type TemplateResult } from 'lit'
import app, { APP_ID } from '../store/app.ts'
import {
  getTheme,
  setTheme,
  type StoreImportMethods,
  type Theme,
} from '@civility/ui'
import { icon } from '../utils/icon.ts'

/** Offered as an autocomplete suggestion; the field stays free-text. */
const SYNC_SERVER = 'https://civility.cloud'

export class SettingsPage extends LitElement {
  #theme: Theme = getTheme()

  protected override createRenderRoot() {
    return this
  }

  #onAppUpdate = () => this.requestUpdate()

  override connectedCallback() {
    super.connectedCallback()
    app.addEventListener(this.#onAppUpdate)
  }

  override disconnectedCallback() {
    super.disconnectedCallback()
    app.removeEventListener(this.#onAppUpdate)
  }

  override render(): TemplateResult {
    return html`
      <section>
        <h2>About</h2>
        <ui-pwa-version></ui-pwa-version>
        <ui-pwa-install></ui-pwa-install>
      </section>

      <section>
        <h2>Appearance</h2>
        <label class="settings-toggle-label">
          <div>
            <span>Theme</span>
            <div class="settings-nav-link-meta">
              Follow your device's setting, or pick one.
            </div>
          </div>
          <select class="settings-select" @change="${this.#handleThemeChange}">
            ${(['system', 'light', 'dark'] as Theme[]).map((t) =>
              html`
                <option value="${t}" ?selected="${this.#theme === t}">
                  ${t[0].toUpperCase() + t.slice(1)}
                </option>
              `
            )}
          </select>
        </label>
      </section>

      <section>
        <h2>Map</h2>
        <nav class="settings-nav-list">
          <a class="settings-nav-link" href="#!/settings/downloads">
            <div>
              <span>Offline Maps</span>
              <div class="settings-nav-link-meta">
                Download regions for offline use
              </div>
            </div>
            ${icon('download', '18px')}
          </a>
        </nav>
        <label class="settings-toggle-label">
          <div>
            <span>Online map detail</span>
            <div class="settings-nav-link-meta">
              Stream street-level detail for areas you haven't downloaded. Downloaded
              regions are always used first. Paused automatically while your device
              is in data-saver mode or on a slow connection.
            </div>
          </div>
          <input
            type="checkbox"
            .checked="${app.onlineTilesEnabled}"
            @change="${this.#handleOnlineTilesToggle}"
          >
        </label>
      </section>

      <section>
        <h2>Privacy</h2>
        <label class="settings-toggle-label">
          <div>
            <span>Online search</span>
            <div class="settings-nav-link-meta">
              Search for places using OpenStreetMap's Nominatim service. Disable to
              rely only on your saved bookmarks.
            </div>
          </div>
          <input
            type="checkbox"
            .checked="${app.onlineSearchEnabled}"
            @change="${this.#handleOnlineSearchToggle}"
          >
        </label>
        <label class="settings-toggle-label">
          <div>
            <span>Location lookup on Bookmark</span>
            <div class="settings-nav-link-meta">
              When dropping a pin, reverse-geocode coordinates using OpenStreetMap's
              Nominatim service to suggest a place name
            </div>
          </div>
          <input
            type="checkbox"
            .checked="${app.geocodingBookmarksEnabled}"
            @change="${this.#handleGeocodingToggle}"
          >
        </label>
        <label class="settings-toggle-label">
          <div>
            <span>Find my location on load</span>
            <div class="settings-nav-link-meta">
              Automatically start tracking your location when the map opens.
            </div>
          </div>
          <input
            type="checkbox"
            .checked="${app.trackOnInitialLoad}"
            @change="${this.#handleTrackOnInitialLoadToggle}"
          >
        </label>
      </section>

      <section>
        <h2>Sync</h2>
        <civ-sync-input
          app-id="${APP_ID}"
          .synced="${app.synced}"
          .servers="${[{ label: 'Civility Cloud', url: SYNC_SERVER }]}"
        ></civ-sync-input>
        <civ-sync-state .synced="${app.synced}"></civ-sync-state>
        <civ-usage .synced="${app.synced}"></civ-usage>
      </section>

      <section>
        <h2>Data</h2>
        <civ-store-import
          allow-replace
          .methods="${{
            export: (filename?: string) => app.exportStore(filename),
            import: (opts) => app.importStore(opts),
            deleteAll: () => app.deleteAllData(),
          } as StoreImportMethods}"
          @on-imported="${() => {
            globalThis.dispatchEvent(new CustomEvent('pmtiles-updated'))
          }}"
        ></civ-store-import>
      </section>

      <section>
        <h2>Info</h2>
        <nav class="settings-nav-list">
          <a class="settings-nav-link" href="#!/settings/about">
            <div>
              <span>About</span>
              <div class="settings-nav-link-meta">App info and acknowledgements</div>
            </div>
            ${icon('book', '18px')}
          </a>
        </nav>
      </section>
    `
  }

  #handleThemeChange = (e: Event): void => {
    this.#theme = (e.target as HTMLSelectElement).value as Theme
    setTheme(this.#theme)
    this.requestUpdate()
  }

  #handleOnlineSearchToggle(e: Event): void {
    app.setOnlineSearchEnabled((e.target as HTMLInputElement).checked)
  }

  #handleOnlineTilesToggle(e: Event): void {
    app.setOnlineTilesEnabled((e.target as HTMLInputElement).checked)
  }

  #handleGeocodingToggle(e: Event): void {
    app.setGeocodingBookmarksEnabled((e.target as HTMLInputElement).checked)
  }

  #handleTrackOnInitialLoadToggle(e: Event): void {
    app.setTrackOnInitialLoad((e.target as HTMLInputElement).checked)
  }
}

customElements.define('r-settings', SettingsPage)
