<!--
Copyright (c) 2026 Sidero Labs, Inc.

Use of this software is governed by the Business Source License
included in the LICENSE file.
-->
<script lang="ts">
import type { HardwareType } from '@/views/InstallationMedia/useFormState'

const flows = {
  metal: [
    'InstallationMediaCreateTalosVersion',
    'InstallationMediaCreateMachineArch',
    'InstallationMediaCreateSystemExtensions',
    'InstallationMediaCreateExtraArgs',
    'InstallationMediaCreateConfirmation',
  ] as const,
  cloud: [
    'InstallationMediaCreateTalosVersion',
    'InstallationMediaCreateCloudProvider',
    'InstallationMediaCreateMachineArch',
    'InstallationMediaCreateSystemExtensions',
    'InstallationMediaCreateExtraArgs',
    'InstallationMediaCreateConfirmation',
  ] as const,
  sbc: [
    'InstallationMediaCreateTalosVersion',
    'InstallationMediaCreateSBCType',
    'InstallationMediaCreateSystemExtensions',
    'InstallationMediaCreateExtraArgs',
    'InstallationMediaCreateConfirmation',
  ] as const,
} satisfies Record<HardwareType, string[]>
</script>

<script setup lang="ts">
import { useSessionStorage } from '@vueuse/core'
import { computed, ref, watch, watchEffect } from 'vue'
import { useRoute, useRouter } from 'vue-router'

import TButton from '@/components/Button/TButton.vue'
import TIcon from '@/components/Icon/TIcon.vue'
import PageContainer from '@/components/PageContainer/PageContainer.vue'
import Stepper from '@/components/Stepper/Stepper.vue'
import Tooltip from '@/components/Tooltip/Tooltip.vue'
import { showSuccess } from '@/notification'
import SavePresetModal from '@/views/InstallationMedia/SavePresetModal.vue'
import { useFormState } from '@/views/InstallationMedia/useFormState'

definePage({
  name: 'InstallationMediaCreate',
  redirect: {
    name: 'InstallationMediaCreateEntry',
  },
})

const router = useRouter()
const route = useRoute()

const { formState, isStepValid: isStepValidFn } = useFormState()
const isSaved = useSessionStorage('_installation_media_form_saved', false)

watch(
  formState,
  () => {
    // Clear saved state if we modify the form in any way
    isSaved.value = false
  },
  { deep: true },
)

const currentStepName = computed(() => route.name)
const isStepValid = computed(() =>
  currentStepName.value ? isStepValidFn(currentStepName.value) : true,
)

watchEffect(() => {
  if (currentStepName.value === 'InstallationMediaCreateEntry' || formState.value.hardwareType)
    return

  // Fail-safe to return to the start of the form if we load a future step with a blank form state.
  if (window.history.length > 1) {
    // Using go(-1) to programmatically reverse backwards from history till we are out of this state.
    // This prevents having to use browser back multiple times and getting stuck in a history trap.
    router.go(-1)
    return
  }

  // In case of no history (e.g. opening a direct link), replace current route.
  router.replace({ name: 'InstallationMediaCreateEntry' })
})

const currentFlowSteps = computed(() =>
  formState.value.hardwareType ? flows[formState.value.hardwareType] : null,
)

const stepCount = computed(() => currentFlowSteps.value?.length ?? 0)
const currentStep = computed(() => {
  if (!currentStepName.value || !currentFlowSteps.value) {
    return 0
  }

  return (currentFlowSteps.value as string[]).indexOf(currentStepName.value as string) + 1
})

const isFirstStep = computed(() => currentStep.value === 0)

const isLastStep = computed(() =>
  currentFlowSteps.value ? currentStep.value === stepCount.value : false,
)

const nextStep = computed(() =>
  !isLastStep.value ? currentFlowSteps.value?.[currentStep.value] : undefined,
)

const prevStep = computed(() =>
  currentStep.value > 1
    ? currentFlowSteps.value?.[currentStep.value - 2]
    : 'InstallationMediaCreateEntry',
)

function onStepperChange(stepperValue?: number) {
  if (!currentFlowSteps.value || !stepperValue) return

  // Stepper is not 0 indexed
  const requestedStepIndex = stepperValue - 1

  // All steps leading up to the requested step must be valid
  if (!currentFlowSteps.value.slice(0, requestedStepIndex).every(isStepValidFn)) {
    return
  }

  router.push({ name: currentFlowSteps.value[requestedStepIndex] })
}

const savePresetModalOpen = ref(false)

function onSaved(name: string) {
  showSuccess(`Preset saved as ${name}`)

  isSaved.value = true
  savePresetModalOpen.value = false
}
</script>

<template>
  <PageContainer disable-padding class="flex h-full flex-col">
    <div class="flex grow flex-col gap-6 overflow-auto p-6">
      <h1 class="shrink-0 text-xl font-medium text-naturals-n14">Create New Media</h1>
      <RouterView v-model="formState" />
    </div>

    <div
      class="flex w-full shrink-0 items-center gap-4 border-t border-naturals-n4 bg-naturals-n1 px-4 max-md:flex-col max-md:p-4 md:h-16 md:justify-end"
    >
      <div v-if="currentFlowSteps && !isFirstStep" class="flex grow gap-4">
        <Tooltip description="Reset wizard">
          <button
            type="button"
            class="group isolate size-6 shrink-0 overflow-hidden rounded-sm border border-red-r1 p-0.5 text-red-r1 transition hover:bg-red-r1 hover:text-naturals-n1 active:brightness-75"
            @click="formState = {}"
          >
            <TIcon icon="close" class="size-full" aria-label="reset wizard" />
          </button>
        </Tooltip>

        <Stepper
          :linear="false"
          :model-value="currentStep"
          :step-count="stepCount"
          class="mx-auto grow"
          @update:model-value="onStepperChange"
        />
      </div>

      <div class="flex items-center gap-2 max-md:self-end">
        <TButton
          is="router-link"
          v-if="currentFlowSteps && !isFirstStep"
          :disabled="isSaved"
          :to="{ name: prevStep }"
        >
          Back
        </TButton>

        <TButton
          is="router-link"
          v-if="!isLastStep"
          variant="highlighted"
          :disabled="!nextStep || !isStepValid"
          :to="{ name: nextStep }"
        >
          Next
        </TButton>

        <TButton
          is="router-link"
          v-else-if="isSaved"
          variant="highlighted"
          :to="{ name: 'InstallationMedia' }"
        >
          Finished
        </TButton>

        <TButton v-else variant="highlighted" @click="savePresetModalOpen = true">Save</TButton>
      </div>
    </div>

    <SavePresetModal
      :open="savePresetModalOpen"
      :form-state
      @close="savePresetModalOpen = false"
      @saved="onSaved"
    />
  </PageContainer>
</template>
