<script>
  import { settings, flexConnected, rotorConnected, soundEnabled } from '../stores/satstore.js'
  import { Go } from '../lib/wails.js'
  import { maidenheadToLatLon, latLonToMaidenhead } from '../lib/maidenhead.js'

  let saving = false
  let flexStatus = ''
  let rotorStatus = ''
  let tleStatus = ''
  let qraError = ''
  let qraInput = ''
  let rxSlice = 0  // Slice A = RX downlink
  let txSlice = 1  // Slice B = TX uplink

  // Voice selection
  let availableVoices = []
  let selectedVoiceName = ''

  // Load slice config on mount
  import { onMount } from 'svelte'
  onMount(async () => {
    // Always load from persisted settings
    rxSlice = $settings.rxSlice ?? 0
    txSlice = $settings.txSlice ?? 1

    // Load available TTS voices
    const loadVoices = () => {
      const voices = window.speechSynthesis?.getVoices() || []
      availableVoices = voices.filter(v => v.lang.startsWith('en'))
      // Also include all voices if no English ones found
      if (availableVoices.length === 0) availableVoices = voices
      selectedVoiceName = $settings.ttsVoiceName || ''
    }
    loadVoices()
    // Chrome/Wails loads voices async
    if (window.speechSynthesis) {
      window.speechSynthesis.onvoiceschanged = loadVoices
    }
    // Apply to Go if already connected
    if ($flexConnected) {
      await Go.SetSliceConfig(rxSlice, txSlice)
    }
  })

  async function applySlices() {
    await Go.SetSliceConfig(rxSlice, txSlice)
    settings.update(s => ({ ...s, rxSlice, txSlice }))
    flexStatus = `Slices: RX=Slice ${'ABCDEFGH'[rxSlice]}, TX=Slice ${'ABCDEFGH'[txSlice]}`
  }

  function saveVoice() {
    settings.update(s => ({ ...s, ttsVoiceName: selectedVoiceName }))
  }

  // Load once - do NOT subscribe reactively (would overwrite user edits)
  let local = { ...$settings }

  $: qraFromCoords = (local.qthLat && local.qthLon)
    ? latLonToMaidenhead(local.qthLat, local.qthLon)
    : ''

  function applyQRA() {
    qraError = ''
    const result = maidenheadToLatLon(qraInput)
    if (!result) { qraError = 'Invalid locator (e.g. JN03ef)'; return }
    local.qthLat = result.lat
    local.qthLon = result.lon
  }

  async function saveQTH() {
    saving = true
    settings.update(s => ({ ...s, qthLat: local.qthLat, qthLon: local.qthLon, qthAlt: local.qthAlt }))
    await Go.SetObserverLocation(local.qthLat, local.qthLon, local.qthAlt)
    saving = false
  }

  async function connectFlex() {
    flexStatus = 'Connecting…'
    // Persist host/port before connecting
    settings.update(s => ({ ...s, flexHost: local.flexHost, flexPort: local.flexPort }))
    const res = await Go.ConnectFlexRadio(local.flexHost, local.flexPort)
    if (res === 'OK') {
      flexConnected.set(true)
      flexStatus = 'Connected ✓'
      await Go.SetSatelliteFrequencies(local.downlinkHz, local.uplinkHz)
    } else { flexStatus = res || 'Error' }
  }

  async function disconnectFlex() {
    await Go.DisconnectFlexRadio()
    flexConnected.set(false)
    flexStatus = 'Disconnected'
  }

  async function connectRotor() {
    rotorStatus = 'Connecting…'
    settings.update(s => ({ ...s, rotorHost: local.rotorHost, rotorPort: local.rotorPort, rotorAzOnly: local.rotorAzOnly }))
    const res = await Go.ConnectRotor(local.rotorHost, local.rotorPort)
    if (res === 'OK') {
      rotorConnected.set(true); rotorStatus = '✓ Connected'
      await Go.SetRotorAzOnly(local.rotorAzOnly ?? true)
    }
    else { rotorStatus = res || 'Error' }
  }

  async function disconnectRotor() {
    await Go.DisconnectRotor()
    rotorConnected.set(false)
    rotorStatus = 'Disconnected'
  }

  async function refreshTLE() {
    tleStatus = 'Downloading…'
    const res = await Go.RefreshTLE()
    tleStatus = res === 'OK' ? 'Updated ✓' : res
    setTimeout(() => tleStatus = '', 3000)
  }

  function toggleAutoFlex() {
    local.autoConnectFlex = !local.autoConnectFlex
    settings.update(s => ({ ...s, autoConnectFlex: local.autoConnectFlex }))
  }

  function toggleAutoRotor() {
    local.autoConnectRotor = !local.autoConnectRotor
    settings.update(s => ({ ...s, autoConnectRotor: local.autoConnectRotor }))
  }
</script>

<div class="sp">
  <div class="sp-scroll">

    <!-- QTH -->
    <section class="card">
      <h3>📍 QTH / Locator</h3>
      <div class="qra-row">
        <div class="field-col">
          <label>Maidenhead Locator</label>
          <div class="inp-btn">
            <input type="text" bind:value={qraInput} placeholder="JN03ef"
              maxlength="8" class="mono upper"
              on:keydown={e => e.key==='Enter' && applyQRA()} />
            <button class="btn-sm" on:click={applyQRA}>Apply</button>
          </div>
          {#if qraError}<span class="err">{qraError}</span>{/if}
        </div>
        <div class="qra-display">
          <label>Current QRA</label>
          <span class="qra-big">{qraFromCoords || '—'}</span>
        </div>
      </div>
      <div class="sep">or enter coordinates manually</div>
      <div class="fg">
        <label>Latitude</label>
        <input type="number" bind:value={local.qthLat} step="0.0001" min="-90" max="90" />
        <label>Longitude</label>
        <input type="number" bind:value={local.qthLon} step="0.0001" min="-180" max="180" />
        <label>Altitude (m)</label>
        <input type="number" bind:value={local.qthAlt} step="1" min="0" />
      </div>
      <button class="btn-primary" on:click={saveQTH} disabled={saving}>
        {saving ? 'Saving…' : '💾 Save QTH'}
      </button>
    </section>

    <!-- FlexRadio -->
    <section class="card">
      <div class="card-head">
        <h3>🔌 FlexRadio</h3>
        <span class="badge {$flexConnected ? 'ok' : 'off'}">{$flexConnected ? 'CONNECTED' : 'OFFLINE'}</span>
      </div>
      <div class="fg">
        <label>Host / IP</label>
        <input type="text" bind:value={local.flexHost} placeholder="192.168.1.x" />
        <label>TCP Port</label>
        <input type="number" bind:value={local.flexPort} />
      </div>
      <div class="toggle-row">
        <button class="toggle {local.autoConnectFlex ? 'toggle-on' : ''}" on:click={toggleAutoFlex}>
          {local.autoConnectFlex ? '✓' : '○'} Auto-connect on startup
        </button>
      </div>
      <div class="btn-row">
        {#if $flexConnected}
          <button class="btn-danger" on:click={disconnectFlex}>Disconnect</button>
        {:else}
          <button class="btn-primary" on:click={connectFlex}>Connect</button>
        {/if}
        {#if flexStatus}
          <span class="status {flexStatus.includes('✓') || flexStatus.includes('Slice') ? 'ok-txt' : 'err-txt'}">{flexStatus}</span>
        {/if}
      </div>

      <!-- Satellite Slice Configuration -->
      <div class="slice-config">
        <div class="slice-label">SATELLITE SLICES</div>
        <div class="slice-row">
          <span class="slice-lbl">↓ RX Downlink</span>
          <select bind:value={rxSlice} class="slice-sel">
            {#each ['A','B','C','D'] as l, i}
              <option value={i}>Slice {l}</option>
            {/each}
          </select>
        </div>
        <div class="slice-row">
          <span class="slice-lbl">↑ TX Uplink</span>
          <select bind:value={txSlice} class="slice-sel">
            {#each ['A','B','C','D'] as l, i}
              <option value={i}>Slice {l}</option>
            {/each}
          </select>
        </div>
        <button class="btn-secondary btn-sm" on:click={applySlices}>Apply slices</button>
        <p class="hint">Default: Slice A = RX downlink, Slice B = TX uplink</p>
      </div>
    </section>

    <!-- PstRotator -->
    <section class="card">
      <div class="card-head">
        <h3>🔄 PstRotator</h3>
        <span class="badge {$rotorConnected ? 'ok' : 'off'}">{$rotorConnected ? 'CONNECTED' : 'OFFLINE'}</span>
      </div>
      <div class="fg">
        <label>Host / IP</label>
        <input type="text" bind:value={local.rotorHost} placeholder="127.0.0.1" />
        <label>UDP Port</label>
        <input type="number" bind:value={local.rotorPort} />
      </div>
      <div class="toggle-row">
        <button class="toggle {local.autoConnectRotor ? 'toggle-on' : ''}" on:click={toggleAutoRotor}>
          {local.autoConnectRotor ? '✓' : '○'} Auto-connect on startup
        </button>
      </div>
      <div class="btn-row">
        {#if $rotorConnected}
          <button class="btn-danger" on:click={disconnectRotor}>Disconnect</button>
        {:else}
          <button class="btn-primary" on:click={connectRotor}>Connect</button>
        {/if}
        {#if rotorStatus}
          <span class="status {rotorStatus.includes('✓') ? 'ok-txt' : 'err-txt'}">{rotorStatus}</span>
        {/if}
      </div>

      <div class="slice-config">
        <div class="slice-label">ROTOR MODE</div>
        <div class="slice-row">
          <span class="slice-lbl">Axes</span>
          <select bind:value={local.rotorAzOnly} class="slice-sel" on:change={() => Go.SetRotorAzOnly(local.rotorAzOnly ?? true)}>
            <option value={true}>Azimuth only</option>
            <option value={false}>Azimuth + Elevation</option>
          </select>
        </div>
        <p class="hint">Select "Azimuth only" if you don't have an elevation rotor</p>
      </div>
    </section>

    <!-- Voice Alerts -->
    <section class="card">
      <div class="card-head">
        <h3>🔊 Voice Alerts</h3>
        <button class="toggle {$soundEnabled ? 'toggle-on' : ''}" on:click={() => soundEnabled.update(v => !v)}>
          {$soundEnabled ? '✓ Enabled' : '○ Disabled'}
        </button>
      </div>
      <div class="fg">
        <label>TTS Voice</label>
        <select bind:value={selectedVoiceName} on:change={saveVoice} disabled={!$soundEnabled}>
          <option value="">— System default —</option>
          {#each availableVoices as v}
            <option value={v.name}>{v.name} ({v.lang})</option>
          {/each}
        </select>
      </div>
      {#if availableVoices.length === 0}
        <p class="hint">No voices detected. Install English voices via Windows Settings → Speech.</p>
      {:else}
        <p class="hint">{availableVoices.length} English voice{availableVoices.length > 1 ? 's' : ''} available. Recommended: Microsoft David or Zira.</p>
      {/if}
      <div class="btn-row">
        <button class="btn-secondary btn-sm" disabled={!$soundEnabled} on:click={() => {
          if (!window.speechSynthesis) return
          const utt = new SpeechSynthesisUtterance('AOS ISS is rising. Pass will last for 8 minutes.')
          utt.lang = 'en-US'
          if (selectedVoiceName) {
            const v = availableVoices.find(v => v.name === selectedVoiceName)
            if (v) utt.voice = v
          }
          window.speechSynthesis.cancel()
          window.speechSynthesis.speak(utt)
        }}>▶ Test voice</button>
      </div>
    </section>

    <!-- TLE -->
    <section class="card">
      <h3>🛰️ TLE Data</h3>
      <p class="hint">Source: Celestrak amateur · Fallback: PE0SAT</p>
      <div class="btn-row">
        <button class="btn-secondary" on:click={refreshTLE}>↻ Refresh TLE</button>
        {#if tleStatus}
          <span class="status {tleStatus.includes('✓') ? 'ok-txt' : 'err-txt'}">{tleStatus}</span>
        {/if}
      </div>
    </section>

    <!-- About -->
    <section class="card">
      <h3>ℹ️ About</h3>
      <p><strong>SatMaster v1.0</strong> — F4BPO</p>
      <p>Amateur satellite tracking · FlexRadio Doppler correction · PstRotator control</p>
      <p class="hint">SGP4 via akhenakh/sgp4 · Go + Wails + Svelte</p>
    </section>

  </div>
</div>

<style>
  .sp { height:100%; background:#f0f2f5; overflow:hidden; font-family:'Inter',sans-serif; }
  .sp-scroll { height:100%; overflow-y:auto; padding:16px 20px; display:flex; flex-direction:column; gap:14px; max-width:680px; margin:0 auto; }
  .sp-scroll::-webkit-scrollbar { width:5px; }
  .sp-scroll::-webkit-scrollbar-thumb { background:#c0ccd8; border-radius:3px; }

  .card { background:white; border:1px solid #e0e8f0; border-radius:12px; padding:16px 18px; display:flex; flex-direction:column; gap:10px; box-shadow:0 1px 3px rgba(0,0,0,0.05); }
  .card-head { display:flex; align-items:center; justify-content:space-between; }

  h3 { font-size:14px; font-weight:600; color:#1a2a3a; margin:0; }

  .badge { font-size:10px; font-weight:700; padding:3px 10px; border-radius:20px; letter-spacing:.04em; }
  .badge.ok  { background:#e0f7ee; color:#1a7a40; }
  .badge.off { background:#fef0f0; color:#c03030; }

  .qra-row { display:flex; gap:16px; align-items:flex-start; }
  .field-col { flex:1; display:flex; flex-direction:column; gap:5px; }
  .inp-btn { display:flex; gap:6px; }
  .qra-display { display:flex; flex-direction:column; gap:4px; min-width:100px; }
  .qra-big { font-size:22px; font-weight:700; color:#1a5a9a; font-family:'Inter',sans-serif; letter-spacing:.1em; }
  .mono { font-family:'Inter',sans-serif; letter-spacing:.08em; text-transform:uppercase; }
  .err { font-size:11px; color:#c03030; }
  .sep { font-size:11px; color:#9ab0c8; text-align:center; padding:4px 0; border-top:1px solid #e8edf2; margin-top:2px; }

  .fg { display:grid; grid-template-columns:130px 1fr; gap:8px 12px; align-items:center; }
  label { font-size:12px; color:#5a7a9a; font-weight:500; }

  input, select {
    background:#f8fafc; border:1.5px solid #d0dce8; color:#1a2a3a;
    padding:8px 10px; border-radius:8px; font-size:13px;
    font-family:'Inter',sans-serif; outline:none; width:100%;
    transition:border-color .15s, box-shadow .15s;
  }
  input:focus, select:focus { border-color:#1a5a9a; box-shadow:0 0 0 3px rgba(26,90,154,0.1); }

  .freq-row { display:flex; gap:8px; align-items:center; }
  .freq-tag { font-size:12px; color:#1a5a9a; font-weight:700; white-space:nowrap; min-width:90px; font-family:'Inter',sans-serif; }

  .toggle-row { display:flex; }
  .toggle { background:#f8fafc; border:1.5px solid #d0dce8; color:#5a7a9a; font-size:12px; padding:7px 12px; border-radius:8px; cursor:pointer; font-family:'Inter',sans-serif; transition:all .15s; }
  .toggle:hover { border-color:#1a5a9a; }
  .toggle.toggle-on { background:#e8f0fa; border-color:#1a5a9a; color:#1a5a9a; font-weight:600; }

  .btn-row { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
  button { padding:8px 18px; border-radius:8px; font-size:13px; font-weight:600; cursor:pointer; border:none; transition:all .15s; font-family:'Inter',sans-serif; }
  button:disabled { opacity:.4; cursor:not-allowed; }
  button:hover:not(:disabled) { filter:brightness(.95); }
  .btn-sm { padding:6px 12px; font-size:12px; }

  .btn-primary   { background:#1a5a9a; color:white; }
  .btn-secondary { background:#f0f4f8; color:#1a5a9a; border:1.5px solid #d0dce8; }
  .btn-apply     { background:#f0f4f8; color:#1a5a9a; border:1.5px solid #d0dce8; padding:7px 12px; }
  .btn-danger    { background:#fff0f0; color:#c03030; border:1.5px solid #f0c0c0; }

  .status { font-size:12px; font-weight:600; }
  .ok-txt  { color:#1a7a40; }
  .err-txt { color:#c03030; }

  .hint { font-size:11px; color:#9ab0c8; }
  p { font-size:13px; color:#5a7a9a; line-height:1.6; }
  strong { color:#1a2a3a; }

  /* Slice config */
  .slice-config { display:flex; flex-direction:column; gap:8px; padding:12px; background:#f8fafc; border:1.5px solid #e0e8f0; border-radius:8px; }
  .slice-label { font-size:10px; font-weight:600; color:#9ab0c8; text-transform:uppercase; letter-spacing:.08em; }
  .slice-row { display:flex; align-items:center; gap:10px; }
  .slice-lbl { font-size:12px; color:#5a7a9a; font-weight:500; width:110px; }
  .slice-sel { background:#f8fafc; border:1.5px solid #d0dce8; color:#1a2a3a; padding:6px 10px; border-radius:6px; font-family:'Inter',sans-serif; font-size:12px; outline:none; cursor:pointer; width:auto; }
</style>