<template>
  <div>
    <div class="page-header">
      <h2>{{ isEdit ? 'Edit Application' : 'New Application' }}</h2>
    </div>

    <div class="card">
      <div v-if="loading" class="loading">Loading...</div>

      <form v-else @submit.prevent="saveApplication">
        <div class="form-row">
          <div class="form-group">
            <label for="appname">Application Name *</label>
            <input
              id="appname"
              v-model="form.appname"
              type="text"
              class="form-control"
              required
            />
          </div>

          <div class="form-group">
            <label for="supportteamid">Support Team</label>
            <select
              id="supportteamid"
              v-model="form.supportteamid"
              class="form-control"
            >
              <option value="">Select team...</option>
              <option
                v-for="team in supportTeams"
                :key="team.supportteamid"
                :value="team.supportteamid"
              >
                {{ team.teamname }}
              </option>
            </select>
          </div>
        </div>

        <div class="form-group">
          <label for="appdescription">Description</label>
          <textarea
            id="appdescription"
            v-model="form.appdescription"
            class="form-control"
            rows="2"
          ></textarea>
        </div>

        <h4 style="margin-top: 1.5rem; margin-bottom: 1rem;">Application Flags</h4>

        <div class="form-row">
          <div class="form-group checkbox-group">
            <label>
              <input type="checkbox" v-model="form.isinstallable" />
              Installable
            </label>
            <label>
              <input type="checkbox" v-model="form.islicenced" />
              Licensed
            </label>
            <label>
              <input type="checkbox" v-model="form.isprinter" />
              Printer App
            </label>
            <label>
              <input type="checkbox" v-model="form.isrequired" />
              Required on all PCs
            </label>
            <label>
              <input type="checkbox" v-model="form.ishidden" />
              Hidden
            </label>
          </div>
        </div>

        <h4 style="margin-top: 1.5rem; margin-bottom: 1rem;">Links & Paths</h4>

        <div class="form-row">
          <div class="form-group">
            <label for="applicationlink">Application Link</label>
            <input
              id="applicationlink"
              v-model="form.applicationlink"
              type="text"
              class="form-control"
              placeholder="https://..."
            />
          </div>

          <div class="form-group">
            <label for="documentationpath">Documentation Path</label>
            <input
              id="documentationpath"
              v-model="form.documentationpath"
              type="text"
              class="form-control"
              placeholder="URL or file path"
            />
          </div>
        </div>

        <div class="form-group">
          <label for="installpath">Install Path</label>
          <input
            id="installpath"
            v-model="form.installpath"
            type="text"
            class="form-control"
            placeholder="Network path or URL to install files"
          />
          <small class="form-hint">
            A share path or URL, or upload the installer below and this fills
            itself in.
          </small>
        </div>

        <div class="form-group">
          <label for="packagefile">Installer</label>
          <div v-if="uploadedPackage" class="upload-current">
            <span class="upload-name">{{ uploadedPackage }}</span>
            <button type="button" class="btn btn-sm btn-secondary" @click="removePackage"
                    :disabled="busyPackage">Remove installer</button>
          </div>
          <input id="packagefile" type="file" class="form-control"
                 :accept="PACKAGE_ACCEPT" @change="onPackagePicked" />
          <div v-if="packageProgress !== null" class="upload-progress">
            <div class="upload-bar"><span :style="{ width: packageProgress + '%' }"></span></div>
            <span>{{ packageProgress }}%</span>
          </div>
          <small class="form-hint">
            Up to 500MB. Anything larger belongs on the share - put its path in
            Install Path instead. Downloads require a login.
          </small>
        </div>

        <div class="form-group">
          <label for="imagefile">Image</label>
          <div v-if="imagePreview" class="upload-current">
            <img :src="imagePreview" alt="" class="upload-thumb" />
            <button type="button" class="btn btn-sm btn-secondary" @click="removeImage"
                    :disabled="busyImage">Remove image</button>
          </div>
          <input id="imagefile" type="file" class="form-control"
                 accept="image/*" @change="onImagePicked" />
          <small class="form-hint">
            PNG, JPG, GIF, WEBP, SVG or ICO. Replaces whatever is there now.
          </small>
        </div>

        <div class="form-group">
          <label for="image">Image path</label>
          <input
            id="image"
            v-model="form.image"
            type="text"
            class="form-control"
            placeholder="filled in by the upload above"
          />
          <small class="form-hint">
            Set by the upload. Older entries hold a bare filename served from
            /images/applications/, and those still work - leave them alone
            unless you are replacing the image.
          </small>
        </div>

        <h4 style="margin-top: 1.5rem; margin-bottom: 1rem;">Notes</h4>

        <div class="form-group">
          <label for="applicationnotes">Application Notes (HTML supported)</label>
          <textarea
            id="applicationnotes"
            v-model="form.applicationnotes"
            class="form-control"
            rows="6"
            placeholder="Enter notes... HTML tags like <BR>, <a>, <strong> are supported"
          ></textarea>
        </div>

        <div v-if="error" class="error-message">{{ error }}</div>

        <div style="display: flex; gap: 0.5rem; margin-top: 1.5rem;">
          <button type="submit" class="btn btn-primary" :disabled="saving">
            {{ saving ? 'Saving...' : 'Save Application' }}
          </button>
          <router-link to="/applications" class="btn btn-secondary">Cancel</router-link>
        </div>
      </form>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { applicationsApi, supportteamsApi } from '@/api'
import { apiError } from '@/utils/apiError'

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

const isEdit = computed(() => !!route.params.id)

const loading = ref(true)
const saving = ref(false)
const error = ref('')

const form = ref({
  appname: '',
  appdescription: '',
  supportteamid: '',
  isinstallable: false,
  islicenced: false,
  isprinter: false,
  isrequired: false,
  ishidden: false,
  applicationlink: '',
  documentationpath: '',
  installpath: '',
  image: '',
  applicationnotes: ''
})

const supportTeams = ref([])

// Files are chosen before the application exists, so they are held here and
// uploaded once there is an id to attach them to (see saveApplication).
const pendingImage = ref(null)
const pendingPackage = ref(null)
const imagePreview = ref('')
const uploadedPackage = ref('')
const packageProgress = ref(null)
const busyImage = ref(false)
const busyPackage = ref(false)

const PACKAGE_ACCEPT = '.exe,.msi,.msp,.zip,.7z,.cab,.iso,.appx,.msix,.ps1,.bat,.txt,.pdf'
const MAX_PACKAGE_BYTES = 500 * 1024 * 1024

function onImagePicked(event) {
  const file = event.target.files?.[0]
  if (!file) return
  pendingImage.value = file
  // Show the chosen file immediately rather than after a round trip.
  imagePreview.value = URL.createObjectURL(file)
}

function onPackagePicked(event) {
  const file = event.target.files?.[0]
  if (!file) return
  if (file.size > MAX_PACKAGE_BYTES) {
    error.value = `${file.name} is ${(file.size / 1048576).toFixed(0)}MB; the limit is 500MB. `
      + 'Put it on the share and use Install Path instead.'
    event.target.value = ''
    return
  }
  error.value = ''
  pendingPackage.value = file
  uploadedPackage.value = file.name
}

async function removeImage() {
  pendingImage.value = null
  imagePreview.value = ''
  form.value.image = ''
  if (isEdit.value) {
    busyImage.value = true
    try { await applicationsApi.removeImage(route.params.id) }
    catch (err) { error.value = apiError(err, 'Failed to remove the image') }
    finally { busyImage.value = false }
  }
}

async function removePackage() {
  pendingPackage.value = null
  uploadedPackage.value = ''
  if (isEdit.value) {
    busyPackage.value = true
    try {
      const response = await applicationsApi.removePackage(route.params.id)
      form.value.installpath = response.data.data.installpath || ''
    } catch (err) {
      error.value = apiError(err, 'Failed to remove the installer')
    } finally { busyPackage.value = false }
  }
}

// The image field holds either a served URL (new) or a bare filename from the
// classic site, which is still rendered out of /images/applications/.
function imageSrcFor(value) {
  if (!value) return ''
  return value.startsWith('/api/') || value.startsWith('http')
    ? value
    : `/images/applications/${value}`
}

onMounted(async () => {
  try {
    // Load support teams
    const teamsRes = await supportteamsApi.list()
    supportTeams.value = teamsRes.data.data || []

    // Load application if editing
    if (isEdit.value) {
      const response = await applicationsApi.get(route.params.id)
      const app = response.data.data

      form.value = {
        appname: app.appname || '',
        appdescription: app.appdescription || '',
        supportteamid: app.supportteamid || '',
        isinstallable: app.isinstallable || false,
        islicenced: app.islicenced || false,
        isprinter: app.isprinter || false,
        isrequired: app.isrequired || false,
        ishidden: app.ishidden || false,
        applicationlink: app.applicationlink || '',
        documentationpath: app.documentationpath || '',
        installpath: app.installpath || '',
        image: app.image || '',
        applicationnotes: app.applicationnotes || ''
      }
      imagePreview.value = imageSrcFor(app.image)
      if ((app.installpath || '').startsWith('/api/applications/package/')) {
        uploadedPackage.value = app.installpath.split('/').pop()
      }
    }
  } catch (err) {
    console.error('Error loading data:', err)
    error.value = 'Failed to load data'
  } finally {
    loading.value = false
  }
})

async function saveApplication() {
  error.value = ''
  saving.value = true

  try {
    const appData = {
      appname: form.value.appname,
      appdescription: form.value.appdescription || null,
      supportteamid: form.value.supportteamid || null,
      isinstallable: form.value.isinstallable,
      islicenced: form.value.islicenced,
      isprinter: form.value.isprinter,
      isrequired: form.value.isrequired,
      ishidden: form.value.ishidden,
      applicationlink: form.value.applicationlink || null,
      documentationpath: form.value.documentationpath || null,
      installpath: form.value.installpath || null,
      image: form.value.image || null,
      applicationnotes: form.value.applicationnotes || null
    }

    let appid = route.params.id
    if (isEdit.value) {
      await applicationsApi.update(appid, appData)
    } else {
      const created = await applicationsApi.create(appData)
      appid = created.data.data.appid
    }

    // Uploads come after the save: a new application has no id until it exists,
    // and both endpoints key on it. A failed upload must not lose the record
    // that saved fine, so it reports and stays on the form.
    if (pendingImage.value) {
      await applicationsApi.uploadImage(appid, pendingImage.value)
      pendingImage.value = null
    }
    if (pendingPackage.value) {
      packageProgress.value = 0
      await applicationsApi.uploadPackage(appid, pendingPackage.value,
                                          percent => { packageProgress.value = percent })
      pendingPackage.value = null
      packageProgress.value = null
    }

    router.push('/applications')
  } catch (err) {
    console.error('Error saving application:', err)
    error.value = apiError(err, 'Failed to save application')
    packageProgress.value = null
  } finally {
    saving.value = false
  }
}
</script>

<style scoped>
.upload-current {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 0.5rem;
}
.upload-thumb {
  width: 3rem;
  height: 3rem;
  object-fit: contain;
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  background: var(--bg);
}
.upload-name {
  font-family: ui-monospace, monospace;
  font-size: 0.85rem;
  word-break: break-all;
}
.upload-progress {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.5rem;
  font-size: 0.85rem;
}
.upload-bar {
  flex: 1;
  height: 0.5rem;
  background: var(--border);
  border-radius: 999px;
  overflow: hidden;
}
.upload-bar span {
  display: block;
  height: 100%;
  background: var(--primary);
  transition: width 0.2s ease;
}

.checkbox-group {
  display: flex;
  gap: 1.5rem;
  flex-wrap: wrap;
}

.checkbox-group label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
}

.form-hint {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.8rem;
  color: var(--text-light, #666);
}
</style>
