<template>
  <div>
    <div class="page-header">
      <h2>{{ isEdit ? 'Edit Notification' : (isDetail ? 'Notification Details' : 'New Notification') }}</h2>
    </div>

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

      <form v-else @submit.prevent="saveNotification">
        <div class="form-group">
          <label for="notificationtypeid">Type *</label>
          <select
            id="notificationtypeid"
            v-model="form.notificationtypeid"
            class="form-control"
            required
            :disabled="isDetail"
            @change="onTypeChange"
          >
            <option value="">-- Select Type --</option>
            <option
              v-for="type in types"
              :key="type.notificationtypeid"
              :value="type.notificationtypeid"
            >
              {{ type.typename }}
            </option>
          </select>
          <small class="form-hint">Classification type for this notification</small>
        </div>

        <div class="form-group">
          <label for="notification">{{ messageLabel }} *</label>
          <textarea
            id="notification"
            v-model="form.notification"
            class="form-control"
            rows="4"
            required
            :disabled="isDetail"
            :placeholder="messagePlaceholder"
          ></textarea>
        </div>

        <!-- Employee Search - for Recognition and Recertification -->
        <div v-if="isEmployeeType" class="form-group">
          <label>Employee(s) *</label>
          <div class="employee-search-container">
            <input
              v-model="employeeSearch"
              type="text"
              class="form-control"
              placeholder="Search by name..."
              :disabled="isDetail"
              @input="searchEmployees"
              @keydown.enter.prevent="addCustomEmployee"
            />
            <div v-if="employeeResults.length" class="employee-dropdown">
              <div
                v-for="emp in employeeResults"
                :key="emp.SSO"
                class="employee-option"
                @click="selectEmployee(emp)"
              >
                <span class="emp-name">{{ emp.First_Name }} {{ emp.Last_Name }}</span>
                <span class="emp-sso">{{ emp.SSO }}</span>
              </div>
            </div>
          </div>
          <small class="form-hint">Search and pick, or paste multiple SSOs / names separated by commas and press Enter</small>

          <!-- Selected Employees -->
          <div v-if="selectedEmployees.length" class="selected-employees">
            <div
              v-for="(emp, idx) in selectedEmployees"
              :key="idx"
              class="selected-employee"
            >
              <span>{{ emp.name }}</span>
              <button v-if="!isDetail" type="button" class="btn-remove" @click="removeEmployee(idx)">&times;</button>
            </div>
          </div>
        </div>

        <div v-if="!isEmployeeType" class="form-group">
          <label for="businessunitid">Business Unit</label>
          <select
            id="businessunitid"
            v-model="form.businessunitid"
            class="form-control"
            :disabled="isDetail"
          >
            <option value="">-- All Business Units --</option>
            <option
              v-for="bu in businessUnits"
              :key="bu.businessunitid"
              :value="bu.businessunitid"
            >
              {{ bu.businessunit }}
            </option>
          </select>
          <small class="form-hint">Leave blank to apply to all</small>
        </div>

        <div v-if="!isEmployeeType" class="form-group">
          <label for="appid">Related Application</label>
          <select
            id="appid"
            v-model="form.appid"
            class="form-control"
            :disabled="isDetail"
          >
            <option value="">-- No Application --</option>
            <option
              v-for="app in applications"
              :key="app.appid"
              :value="app.appid"
            >
              {{ app.appname }}
            </option>
          </select>
          <small class="form-hint">Link to a specific application (e.g., for software updates)</small>
        </div>

        <div v-if="!isEmployeeType" class="form-group">
          <label for="ticketnumber">Ticket Number</label>
          <input
            id="ticketnumber"
            v-model="form.ticketnumber"
            type="text"
            class="form-control"
            maxlength="50"
            :disabled="isDetail"
            placeholder="GEINC123456 or GECHG123456"
          />
          <small class="form-hint">Optional ServiceNow ticket number</small>
        </div>

        <div class="form-group">
          <label for="link">More Info URL</label>
          <input
            id="link"
            v-model="form.link"
            type="url"
            class="form-control"
            maxlength="500"
            :disabled="isDetail"
            placeholder="https://..."
          />
        </div>

        <!-- Time fields - available for every type. Left blank, the end auto-
             fills to the type's window (recognition = next 8 AM reset,
             recertification = two weeks); set them to override. -->
        <div class="form-row">
          <div class="form-group">
            <label for="starttime">Start Time *</label>
            <div class="input-group">
              <input
                id="starttime"
                v-model="form.starttime"
                type="datetime-local"
                class="form-control"
                required
                :disabled="isDetail"
              />
              <button v-if="!isDetail" type="button" class="btn btn-secondary" @click="setNow('starttime')">
                Now
              </button>
            </div>
            <small class="form-hint">When notification becomes visible ({{ siteTimezone }})</small>
          </div>

          <div class="form-group">
            <label for="endtime">End Time</label>
            <div class="input-group">
              <input
                id="endtime"
                v-model="form.endtime"
                type="datetime-local"
                class="form-control"
                :disabled="isDetail"
              />
              <button v-if="!isDetail" type="button" class="btn btn-secondary" @click="setNow('endtime')">
                Now
              </button>
              <button v-if="!isDetail" type="button" class="btn btn-secondary" @click="form.endtime = ''">
                Clear
              </button>
            </div>
            <small class="form-hint">Leave blank for indefinite</small>
          </div>
        </div>

        <div class="form-row checkbox-row">
          <div class="form-group">
            <label>
              <input
                type="checkbox"
                v-model="form.isactive"
                :disabled="isDetail"
              />
              Active
            </label>
            <small class="form-hint">Uncheck to save as draft</small>
          </div>

          <div class="form-group">
            <label>
              <input
                type="checkbox"
                v-model="form.isshopfloor"
                :disabled="isDetail"
              />
              Show on Shopfloor Dashboard
            </label>
            <small class="form-hint">Display on TV dashboard</small>
          </div>
        </div>

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

        <div class="form-actions">
          <template v-if="isDetail">
            <router-link :to="`/notifications/${route.params.id}/edit`" class="btn btn-primary">
              Edit
            </router-link>
            <router-link to="/notifications" class="btn btn-secondary">Back</router-link>
          </template>
          <template v-else>
            <button type="submit" class="btn btn-primary" :disabled="saving">
              {{ saving ? 'Saving...' : (isEdit ? 'Update' : 'Create') }}
            </button>
            <router-link to="/notifications" class="btn btn-secondary">Cancel</router-link>
          </template>
        </div>
      </form>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, computed, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { notificationsApi, applicationsApi, businessUnitsApi, employeesApi, settingsApi } from '@/api'
import { apiError } from '@/utils/apiError'
import { zonedInputFromUtc, utcFromZonedInput, DEFAULT_TZ } from '@/utils/datetime'

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

const isEdit = computed(() => route.name === 'notification-edit')
const isDetail = computed(() => route.name === 'notification-detail')

const loading = ref(true)
const saving = ref(false)
const error = ref('')
const types = ref([])
const businessUnits = ref([])
const applications = ref([])

// Employee search
const employeeSearch = ref('')
const employeeResults = ref([])
const selectedEmployees = ref([])

const form = ref({
  notification: '',
  notificationtypeid: '',
  businessunitid: '',
  appid: '',
  ticketnumber: '',
  link: '',
  starttime: '',
  endtime: '',
  isactive: true,
  // Ticked for a NEW notification: the shopfloor board is where these are
  // meant to be seen, and leaving it off by default meant most were written
  // and then never appeared there. Editing an EXISTING notification still
  // loads its own stored value (see loadNotification), so this never flips a
  // setting somebody deliberately turned off.
  isshopfloor: true,
  employeesso: ''
})

// Site timezone (settings key site_timezone) so form times show/enter in the
// site's wall clock, not the viewer's browser zone. Loaded in onMounted.
const siteTimezone = ref(DEFAULT_TZ)

function selectedTypeName() {
  const selectedType = types.value.find(t => t.notificationtypeid === parseInt(form.value.notificationtypeid))
  return selectedType?.typename?.toLowerCase() || ''
}

// Recognition and recertification are the employee-photo types: both show the
// employee picker, hide the time/BU/app fields, and get a server-computed
// display window.
const isRecognition = computed(() => selectedTypeName() === 'recognition')
const isRecertification = computed(() => selectedTypeName() === 'recertification')
const isEmployeeType = computed(() => isRecognition.value || isRecertification.value)

const messageLabel = computed(() =>
  isRecertification.value ? 'Recertification Message'
    : isRecognition.value ? 'Recognition Message'
      : 'Notification'
)
const messagePlaceholder = computed(() =>
  isRecertification.value ? 'Enter the recertification message...'
    : isRecognition.value ? 'Enter the recognition message...'
      : 'Enter the notification message...'
)

onMounted(async () => {
  try {
    // Load dropdown data + the site timezone in parallel. Resolve the tz FIRST
    // (before any formatDateForInput) so times render in the site's zone.
    const [typesRes, buRes, appsRes, tzRes] = await Promise.all([
      notificationsApi.types.list(),
      businessUnitsApi.list().catch(() => ({ data: { data: [] } })),
      // listAll: perpage is clamped to 100 server-side, and the catalogue is
      // already past that, so this dropdown was missing its tail.
      applicationsApi.listAll().then(items => ({ data: { data: items } }))
        .catch(() => ({ data: { data: [] } })),
      settingsApi.get('site_timezone').catch(() => null)
    ])

    const tzValue = tzRes?.data?.data?.value
    if (tzValue) siteTimezone.value = tzValue

    types.value = typesRes.data.data || []
    businessUnits.value = buRes.data?.data || []
    applications.value = appsRes.data?.data || []

    // Load notification if editing or viewing
    if (route.params.id) {
      const response = await notificationsApi.get(route.params.id)
      const n = response.data.data

      form.value = {
        notification: n.notification || '',
        notificationtypeid: n.notificationtypeid || '',
        businessunitid: n.businessunitid || '',
        appid: n.appid || '',
        ticketnumber: n.ticketnumber || '',
        link: n.link || '',
        starttime: formatDateForInput(n.starttime),
        endtime: formatDateForInput(n.endtime),
        isactive: n.isactive !== false,
        isshopfloor: n.isshopfloor || false,
        employeesso: n.employeesso || ''
      }

      // Parse existing employee data: SSOs are comma-joined and names are
      // ", "-joined, so pair them up by index (one chip per person). Falling
      // back to the SSO when a name is missing.
      if (n.employeesso) {
        const ssos = n.employeesso.split(',')
        const names = (n.employeename || '').split(',')
        ssos.forEach((rawSso, i) => {
          const sso = rawSso.trim()
          if (!sso) return
          const name = (names[i] || '').trim() || sso
          selectedEmployees.value.push({ sso, name })
        })
      }
    } else {
      // Set default start date to now
      form.value.starttime = formatDateForInput(new Date().toISOString())
      // Default to Recognition type
      const recognitionType = types.value.find(t => t.typename?.toLowerCase() === 'recognition')
      if (recognitionType) {
        form.value.notificationtypeid = recognitionType.notificationtypeid
        onTypeChange()
      }
    }
  } catch (err) {
    console.error('Error loading data:', err)
    error.value = 'Failed to load data'
  } finally {
    loading.value = false
  }
})

// UTC value from the API -> a datetime-local string in the SITE timezone.
function formatDateForInput(dateStr) {
  return zonedInputFromUtc(dateStr, siteTimezone.value)
}

function setNow(field) {
  form.value[field] = zonedInputFromUtc(new Date(), siteTimezone.value)
}

function onTypeChange() {
  // Recognition and recertification get a server-computed display window
  // (recognition clears at 8 AM Eastern; recertification runs two weeks). Set
  // start to now and leave end blank so the backend applies the per-type rule.
  if (isEmployeeType.value) {
    form.value.starttime = zonedInputFromUtc(new Date(), siteTimezone.value)
    form.value.endtime = ''
  }
}

// Employee search
let searchTimeout = null
async function searchEmployees() {
  if (searchTimeout) clearTimeout(searchTimeout)

  const query = employeeSearch.value.trim()
  if (query.length < 2) {
    employeeResults.value = []
    return
  }

  searchTimeout = setTimeout(async () => {
    try {
      const response = await employeesApi.search(query)
      employeeResults.value = response.data.data || []
    } catch (err) {
      console.error('Employee search error:', err)
      employeeResults.value = []
    }
  }, 300)
}

function selectEmployee(emp) {
  // Check if already selected
  if (selectedEmployees.value.some(e => e.sso === String(emp.SSO))) {
    return
  }

  selectedEmployees.value.push({
    sso: String(emp.SSO),
    name: `${emp.First_Name} ${emp.Last_Name}`.trim()
  })

  employeeSearch.value = ''
  employeeResults.value = []
  updateEmployeeSso()
}

// Add one or many at once. The input may hold a single value or a
// comma-separated list of SSOs and/or names. Numeric tokens are treated as
// SSOs and resolved to a real name; everything else is a custom name.
async function addCustomEmployee() {
  const raw = employeeSearch.value.trim()
  if (!raw) return

  const tokens = raw.split(',').map(t => t.trim()).filter(Boolean)
  for (const token of tokens) {
    if (/^\d{4,}$/.test(token)) {
      if (selectedEmployees.value.some(e => e.sso === token)) continue
      let name = token
      try {
        const emp = (await employeesApi.lookup(token)).data.data
        if (emp) name = `${emp.First_Name} ${emp.Last_Name}`.trim() || token
      } catch (err) {
        // SSO not found - keep the number as the label
      }
      selectedEmployees.value.push({ sso: token, name })
    } else {
      const key = `NAME:${token}`
      if (selectedEmployees.value.some(e => e.sso === key)) continue
      selectedEmployees.value.push({ sso: key, name: token })
    }
  }

  employeeSearch.value = ''
  employeeResults.value = []
  updateEmployeeSso()
}

function removeEmployee(idx) {
  selectedEmployees.value.splice(idx, 1)
  updateEmployeeSso()
}

function updateEmployeeSso() {
  form.value.employeesso = selectedEmployees.value.map(e => e.sso).join(',')
}

async function saveNotification() {
  error.value = ''

  // Employee-photo types require at least one employee
  if (isEmployeeType.value && selectedEmployees.value.length === 0) {
    error.value = `Please select at least one employee for ${isRecertification.value ? 'recertification' : 'recognition'}`
    return
  }

  saving.value = true

  try {
    const data = {
      notification: form.value.notification,
      notificationtypeid: parseInt(form.value.notificationtypeid) || null,
      businessunitid: parseInt(form.value.businessunitid) || null,
      appid: parseInt(form.value.appid) || null,
      ticketnumber: form.value.ticketnumber || null,
      link: form.value.link || null,
      starttime: utcFromZonedInput(form.value.starttime, siteTimezone.value),
      endtime: utcFromZonedInput(form.value.endtime, siteTimezone.value),
      isactive: form.value.isactive,
      isshopfloor: form.value.isshopfloor,
      employeesso: form.value.employeesso || null
    }

    // For employee-photo types, also send employeename
    if (isEmployeeType.value && selectedEmployees.value.length > 0) {
      data.employeename = selectedEmployees.value.map(e => e.name).join(', ')
    }

    if (isEdit.value) {
      await notificationsApi.update(route.params.id, data)
    } else {
      await notificationsApi.create(data)
    }

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

<style scoped>
.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

.input-group {
  display: flex;
  gap: 0.25rem;
}

.input-group .form-control {
  flex: 1;
}

.input-group .btn {
  flex-shrink: 0;
}

.checkbox-row {
  display: flex;
  gap: 2rem;
  margin-top: 1rem;
}

.checkbox-row .form-group {
  flex: none;
}

.checkbox-row 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);
}

.form-actions {
  display: flex;
  gap: 0.5rem;
  margin-top: 1.5rem;
}

/* Employee search styles */
.employee-search-container {
  position: relative;
}

.employee-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--bg-card-solid, #1a1a1a);
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  max-height: 200px;
  overflow-y: auto;
  z-index: 100;
}

.employee-option {
  padding: 0.5rem 0.75rem;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.employee-option:hover {
  background: rgba(255, 255, 255, 0.1);
}

.emp-name {
  font-weight: 500;
}

.emp-sso {
  font-size: 0.85rem;
  color: var(--text-light);
}

.selected-employees {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.selected-employee {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: var(--primary);
  color: white;
  padding: 0.25rem 0.5rem;
  border-radius: 0.25rem;
  font-size: 0.9rem;
}

.btn-remove {
  background: none;
  border: none;
  color: white;
  cursor: pointer;
  padding: 0;
  font-size: 1.2rem;
  line-height: 1;
  opacity: 0.7;
}

.btn-remove:hover {
  opacity: 1;
}

@media (max-width: 600px) {
  .form-row {
    grid-template-columns: 1fr;
  }

  .checkbox-row {
    flex-direction: column;
    gap: 0.5rem;
  }
}
</style>
