<script setup lang="ts">
import { computed, ref } from 'vue'
import { useRouter } from 'vue-router'
import { useFormFailures, useFormFailuresKpis } from '@/composables/api/useFormFailures'
import type { FormFailureScope } from '@/composables/api/useFormFailures'
import type { FormFailure, FormFailureState } from '@/types/form-failures'
import { listenerShortName, shortId } from '@/types/form-failures'
import RetryFailureDialog from '@/components/form-failures/RetryFailureDialog.vue'
import ResolveFailureDialog from '@/components/form-failures/ResolveFailureDialog.vue'
import DismissFailureDialog from '@/components/form-failures/DismissFailureDialog.vue'

const props = defineProps<{
  scope: FormFailureScope
  orgId?: string
}>()

const router = useRouter()

// Filter state — URL-synced via router push so views are shareable.
const stateFilter = ref<FormFailureState | 'all'>('open')
const search = ref('')
const searchDebounced = refDebounced(search, 400)
const page = ref(1)
const itemsPerPage = ref(25)

const params = computed(() => ({
  page: page.value,
  per_page: itemsPerPage.value,
}))

const orgIdRef = computed(() => props.orgId)

const { data, isLoading, isError, refetch } = useFormFailures(params, props.scope, orgIdRef)
const { data: kpis } = useFormFailuresKpis(props.scope, orgIdRef)

// The backend currently only ships paginated indexes (no server-side
// filters). Apply state + search + listener filters client-side over
// the current page. Acceptable for the "open failures across orgs"
// volumes Crewli sees in v1; tracked for backend pagination work
// post-launch.
const allItems = computed(() => data.value?.data ?? [])

const filtered = computed(() => {
  let rows = allItems.value
  if (stateFilter.value !== 'all') {
    rows = rows.filter(r => r.state === stateFilter.value)
  }
  const q = searchDebounced.value.trim().toLowerCase()
  if (q !== '') {
    rows = rows.filter(r =>
      r.exception_class.toLowerCase().includes(q)
      || r.exception_message.toLowerCase().includes(q)
      || r.id.toLowerCase().includes(q)
      || r.form_submission_id.toLowerCase().includes(q),
    )
  }

  return rows
})

const stateOptions = [
  { title: 'Open', value: 'open' as FormFailureState },
  { title: 'Opgelost', value: 'resolved' as FormFailureState },
  { title: 'Dismissed', value: 'dismissed' as FormFailureState },
  { title: 'Alle', value: 'all' as const },
]

const stateColor: Record<FormFailureState, string> = {
  open: 'error',
  resolved: 'success',
  dismissed: 'warning',
}

const stateLabel: Record<FormFailureState, string> = {
  open: 'Open',
  resolved: 'Opgelost',
  dismissed: 'Dismissed',
}

const headers = [
  { title: 'Status', key: 'state', sortable: false },
  { title: 'Failed at', key: 'failed_at', sortable: false },
  { title: 'Listener', key: 'listener_class', sortable: false },
  { title: 'Exception', key: 'exception_class', sortable: false },
  { title: 'Submission', key: 'form_submission_id', sortable: false },
  { title: 'Retries', key: 'retry_count', sortable: false, align: 'center' as const },
  { title: '', key: 'actions', sortable: false, align: 'end' as const },
]

function formatDate(iso: string): string {
  return new Date(iso).toLocaleDateString('nl-NL', {
    day: '2-digit',
    month: '2-digit',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
  })
}

function truncate(s: string, n = 80): string {
  return s.length > n ? `${s.slice(0, n)}…` : s
}

// Action dialogs — driven by selected row.
const retryDialogOpen = ref(false)
const resolveDialogOpen = ref(false)
const dismissDialogOpen = ref(false)
const selectedFailure = ref<FormFailure | null>(null)

function openRetry(f: FormFailure) {
  selectedFailure.value = f
  retryDialogOpen.value = true
}
function openResolve(f: FormFailure) {
  selectedFailure.value = f
  resolveDialogOpen.value = true
}
function openDismiss(f: FormFailure) {
  selectedFailure.value = f
  dismissDialogOpen.value = true
}

function goToDetail(f: FormFailure) {
  if (props.scope === 'platform') {
    router.push({ name: 'platform-form-failures-id', params: { id: f.id } })
  }
  else {
    router.push({ name: 'organisation-form-failures-id', params: { id: f.id } })
  }
}

function clearFilters() {
  stateFilter.value = 'open'
  search.value = ''
}

function setStateFilter(s: FormFailureState | 'all') {
  stateFilter.value = s
  page.value = 1
}
</script>

<template>
  <div>
    <!-- KPI tiles -->
    <VRow class="mb-4">
      <VCol
        cols="12"
        md="3"
      >
        <VCard
          density="compact"
          class="cursor-pointer"
          :variant="stateFilter === 'open' ? 'elevated' : 'outlined'"
          @click="setStateFilter('open')"
        >
          <VCardText>
            <p class="text-caption text-disabled mb-1">
              Open failures
            </p>
            <h5 class="text-h5">
              <VIcon
                icon="tabler-alert-triangle"
                color="error"
                size="20"
                class="me-1"
              />
              {{ kpis?.open ?? 0 }}
            </h5>
          </VCardText>
        </VCard>
      </VCol>
      <VCol
        cols="12"
        md="3"
      >
        <VCard
          density="compact"
          class="cursor-pointer"
          :variant="stateFilter === 'resolved' ? 'elevated' : 'outlined'"
          @click="setStateFilter('resolved')"
        >
          <VCardText>
            <p class="text-caption text-disabled mb-1">
              Opgelost
            </p>
            <h5 class="text-h5">
              <VIcon
                icon="tabler-check"
                color="success"
                size="20"
                class="me-1"
              />
              {{ kpis?.resolved ?? 0 }}
            </h5>
          </VCardText>
        </VCard>
      </VCol>
      <VCol
        cols="12"
        md="3"
      >
        <VCard
          density="compact"
          class="cursor-pointer"
          :variant="stateFilter === 'dismissed' ? 'elevated' : 'outlined'"
          @click="setStateFilter('dismissed')"
        >
          <VCardText>
            <p class="text-caption text-disabled mb-1">
              Dismissed
            </p>
            <h5 class="text-h5">
              <VIcon
                icon="tabler-x"
                color="warning"
                size="20"
                class="me-1"
              />
              {{ kpis?.dismissed ?? 0 }}
            </h5>
          </VCardText>
        </VCard>
      </VCol>
      <VCol
        cols="12"
        md="3"
      >
        <VCard
          density="compact"
          class="cursor-pointer"
          :variant="stateFilter === 'all' ? 'elevated' : 'outlined'"
          @click="setStateFilter('all')"
        >
          <VCardText>
            <p class="text-caption text-disabled mb-1">
              Totaal
            </p>
            <h5 class="text-h5">
              <VIcon
                icon="tabler-chart-bar"
                color="info"
                size="20"
                class="me-1"
              />
              {{ kpis?.total ?? 0 }}
            </h5>
          </VCardText>
        </VCard>
      </VCol>
    </VRow>

    <!-- Error -->
    <VAlert
      v-if="isError"
      type="error"
      class="mb-4"
    >
      Kon failures niet laden.
      <template #append>
        <VBtn
          variant="text"
          @click="refetch()"
        >
          Opnieuw proberen
        </VBtn>
      </template>
    </VAlert>

    <VCard>
      <!-- Filter bar -->
      <VCardText>
        <VRow>
          <VCol
            cols="12"
            md="6"
          >
            <VBtnToggle
              :model-value="stateFilter"
              divided
              density="comfortable"
              mandatory
              @update:model-value="(v: FormFailureState | 'all') => setStateFilter(v)"
            >
              <VBtn
                v-for="opt in stateOptions"
                :key="opt.value"
                :value="opt.value"
              >
                {{ opt.title }}
              </VBtn>
            </VBtnToggle>
          </VCol>
          <VCol
            cols="12"
            md="6"
          >
            <AppTextField
              v-model="search"
              placeholder="Zoek op exception, ID..."
              prepend-inner-icon="tabler-search"
              clearable
            />
          </VCol>
        </VRow>
      </VCardText>

      <VDataTableServer
        :headers="headers"
        :items="filtered"
        :items-length="data?.meta?.total ?? 0"
        :loading="isLoading"
        :items-per-page="itemsPerPage"
        :page="page"
        hover
        @update:page="(p: number) => (page = p)"
        @update:items-per-page="(n: number) => (itemsPerPage = n)"
      >
        <template #item.state="{ item }">
          <VChip
            :color="stateColor[item.state]"
            size="small"
          >
            {{ stateLabel[item.state] }}
          </VChip>
        </template>

        <template #item.failed_at="{ item }">
          {{ formatDate(item.failed_at) }}
        </template>

        <template #item.listener_class="{ item }">
          <span class="text-body-2">{{ listenerShortName(item.listener_class) }}</span>
        </template>

        <template #item.exception_class="{ item }">
          <div>
            <code class="text-caption d-block">{{ item.exception_class }}</code>
            <span class="text-caption text-disabled">{{ truncate(item.exception_message, 60) }}</span>
          </div>
        </template>

        <template #item.form_submission_id="{ item }">
          <code class="text-caption">{{ shortId(item.form_submission_id) }}</code>
        </template>

        <template #item.retry_count="{ item }">
          <VChip
            v-if="item.retry_count > 0"
            variant="outlined"
            size="x-small"
          >
            {{ item.retry_count }}
          </VChip>
          <span
            v-else
            class="text-disabled"
          >—</span>
        </template>

        <template #item.actions="{ item }">
          <div class="d-flex justify-end ga-1">
            <VBtn
              icon
              variant="text"
              size="small"
              @click="goToDetail(item)"
            >
              <VIcon icon="tabler-eye" />
              <VTooltip activator="parent">
                Detail
              </VTooltip>
            </VBtn>
            <VBtn
              v-if="item.state === 'open'"
              icon
              variant="text"
              size="small"
              color="error"
              @click="openRetry(item)"
            >
              <VIcon icon="tabler-refresh" />
              <VTooltip activator="parent">
                Retry
              </VTooltip>
            </VBtn>
            <VMenu v-if="item.state === 'open'">
              <template #activator="{ props: menuProps }">
                <VBtn
                  v-bind="menuProps"
                  icon
                  variant="text"
                  size="small"
                >
                  <VIcon icon="tabler-dots-vertical" />
                </VBtn>
              </template>
              <VList density="compact">
                <VListItem
                  prepend-icon="tabler-check"
                  title="Markeren als opgelost"
                  @click="openResolve(item)"
                />
                <VListItem
                  prepend-icon="tabler-x"
                  title="Dismiss"
                  @click="openDismiss(item)"
                />
              </VList>
            </VMenu>
          </div>
        </template>

        <template #no-data>
          <div class="text-center pa-4 text-disabled">
            <VIcon
              icon="tabler-checks"
              size="48"
              class="mb-2"
            />
            <p>Geen failures gevonden</p>
            <p class="text-caption">
              Met de huidige filters zijn er geen mislukkingen om op te volgen.
            </p>
            <VBtn
              variant="text"
              @click="clearFilters"
            >
              Filters wissen
            </VBtn>
          </div>
        </template>
      </VDataTableServer>
    </VCard>

    <!-- Action dialogs -->
    <RetryFailureDialog
      v-model="retryDialogOpen"
      :failure="selectedFailure"
      :scope="scope"
      :org-id="orgId"
      @success="refetch()"
    />
    <ResolveFailureDialog
      v-model="resolveDialogOpen"
      :failure="selectedFailure"
      :scope="scope"
      :org-id="orgId"
      @success="refetch()"
    />
    <DismissFailureDialog
      v-model="dismissDialogOpen"
      :failure="selectedFailure"
      :scope="scope"
      :org-id="orgId"
      @success="refetch()"
    />
  </div>
</template>
