<script setup lang="ts">
import { onMounted, reactive, ref } from "vue";
import GmWindow from "./GmWindow.vue";
import { fetchBalance, updateBalance } from "../../api";
import type { BalanceSettings } from "../../contractsBalance";

const emit = defineEmits<{ close: [] }>();

type FieldMeta = {
  key: keyof BalanceSettings;
  label: string;
  description: string;
  step: number;
  min: number;
};

const FIELDS: FieldMeta[] = [
  { key: "simulationSpeedMultiplier", label: "Sim Speed Multiplier", description: "Global speed factor applied to every tick", step: 0.1, min: 0.01 },
  { key: "arrivalThreshold",          label: "Arrival Threshold",     description: "Distance at which a ship is considered arrived", step: 1, min: 0.1 },
  { key: "miningRate",                label: "Mining Rate",           description: "Units of ore extracted per mining cycle", step: 1, min: 0 },
  { key: "miningCycleSeconds",        label: "Mining Cycle (s)",      description: "Duration of one mining cycle", step: 0.1, min: 0.1 },
  { key: "transferRate",              label: "Transfer Rate",         description: "Cargo units transferred per second", step: 1, min: 0 },
  { key: "dockingDuration",           label: "Docking Duration (s)",  description: "Time for a ship to complete docking", step: 0.1, min: 0.1 },
  { key: "undockingDuration",         label: "Undocking Duration (s)", description: "Time for a ship to complete undocking", step: 0.1, min: 0.1 },
  { key: "undockDistance",            label: "Undock Distance",       description: "Distance traveled when undocking", step: 1, min: 0 },
  { key: "yPlane",                    label: "Y Plane",               description: "Vertical height for spatial placement", step: 0.5, min: 0 },
];

const draft = reactive<BalanceSettings>({
  simulationSpeedMultiplier: 1,
  yPlane: 0,
  arrivalThreshold: 0,
  miningRate: 0,
  miningCycleSeconds: 0,
  transferRate: 0,
  dockingDuration: 0,
  undockingDuration: 0,
  undockDistance: 0,
});

const loadError = ref<string | null>(null);
const saveError = ref<string | null>(null);
const saveStatus = ref<"idle" | "saving" | "saved">("idle");
const loaded = ref(false);
let savedTimer: ReturnType<typeof setTimeout> | null = null;

onMounted(async () => {
  try {
    const data = await fetchBalance();
    Object.assign(draft, data);
    loadError.value = null;
    loaded.value = true;
  } catch {
    loadError.value = "Failed to load settings";
  }
});

function sanitizeDraft() {
  for (const field of FIELDS) {
    const value = draft[field.key];
    draft[field.key] = Number.isFinite(value) ? Math.max(field.min, value) : field.min;
  }
}

async function save() {
  sanitizeDraft();
  saveStatus.value = "saving";
  saveError.value = null;
  try {
    const saved = await updateBalance({ ...draft });
    Object.assign(draft, saved);
    saveStatus.value = "saved";
    if (savedTimer !== null) clearTimeout(savedTimer);
    savedTimer = setTimeout(() => { saveStatus.value = "idle"; }, 2500);
  } catch {
    saveError.value = "Failed to save settings";
    saveStatus.value = "idle";
  }
}
</script>

<template>
  <GmWindow
    title="Settings"
    :initial-width="480"
    :initial-height="460"
    :initial-x="260"
    :initial-y="100"
    @close="emit('close')"
  >
    <div class="gm-settings flex h-full flex-col">
      <div v-if="loadError" class="gm-settings-error mx-4 mt-3 rounded px-3 py-2 text-xs">
        {{ loadError }}
      </div>

      <div class="gm-settings-body min-h-0 flex-1 overflow-auto px-4 py-3">
        <div class="gm-settings-section-title mb-3">Balance</div>

        <div class="gm-settings-grid">
          <template v-for="field in FIELDS" :key="field.key">
            <label :for="`gm-setting-${field.key}`" class="gm-settings-label">
              {{ field.label }}
            </label>
            <div class="gm-settings-field-group">
              <input
                :id="`gm-setting-${field.key}`"
                v-model.number="draft[field.key]"
                type="number"
                class="gm-settings-input"
                :step="field.step"
                :min="field.min"
              />
              <span class="gm-settings-desc">{{ field.description }}</span>
            </div>
          </template>
        </div>
      </div>

      <div class="gm-settings-footer flex items-center gap-3 px-4 py-3">
        <span v-if="saveError" class="gm-settings-error-inline flex-1 text-xs">{{ saveError }}</span>
        <span v-else-if="saveStatus === 'saved'" class="gm-settings-saved flex-1 text-xs">Saved</span>
        <span v-else class="flex-1" />
        <button
          type="button"
          class="gm-settings-save-btn"
          :disabled="saveStatus === 'saving' || !loaded"
          @click="save"
        >
          {{ saveStatus === 'saving' ? 'Saving…' : 'Apply' }}
        </button>
      </div>
    </div>
  </GmWindow>
</template>
