<template>
  <section class="manual-resolution">
    <header>
      <div>
        <h2>{{ t('task.manualResolution.title') }}</h2>
        <p>{{ t('task.manualResolution.description') }}</p>
      </div>
      <span class="manual-resolution__status">
        {{ t('task.reviewStatus') }}: {{ reviewStatusLabel }}
      </span>
    </header>

    <div
      v-if="isResolved"
      class="manual-resolution__resolved"
    >
      <strong>{{ t('task.manualResolution.resolvedTitle') }}</strong>
      <pre>{{ formatJson(reviewResolution) }}</pre>
    </div>

    <template v-else>
      <div
        v-if="manualReview"
        class="manual-resolution__meta"
      >
        <dl>
          <div v-if="typeof manualReview.reason_code === 'string'">
            <dt>{{ t('task.manualResolution.reasonCode') }}</dt>
            <dd class="th-code">
              {{ manualReview.reason_code }}
            </dd>
          </div>
          <div v-if="typeof manualReview.review_instruction === 'string'">
            <dt>{{ t('task.manualResolution.reviewInstruction') }}</dt>
            <dd>{{ manualReview.review_instruction }}</dd>
          </div>
        </dl>
      </div>

      <div class="manual-resolution__form">
        <label>
          <span>{{ t('task.manualResolution.confirmedOrderId') }}</span>
          <input
            v-model="confirmedOrderId"
            name="manual_resolution_confirmed_order_id"
            type="text"
            :disabled="busy"
            :placeholder="taskOrderId"
          >
        </label>

        <div
          v-if="supportedMissingFields.length"
          class="manual-resolution__fields"
        >
          <label
            v-for="(item, index) in supportedMissingFields"
            :key="item.key"
          >
            <span>
              {{ item.label }}
              <small class="th-code">{{ item.pointer ?? item.fieldPath }}</small>
            </span>
            <input
              v-model="fieldOverrideInputs[item.key]"
              :name="`manual_resolution_field_override_${index}`"
              type="text"
              :disabled="busy"
              :placeholder="t('task.manualResolution.fieldValuePlaceholder')"
            >
          </label>
        </div>
        <p
          v-else
          class="manual-resolution__empty"
        >
          {{ t('task.manualResolution.noSupportedMissingFields') }}
        </p>

        <label>
          <span>{{ t('task.manualResolution.reason') }}</span>
          <textarea
            v-model="reason"
            name="manual_resolution_reason"
            rows="3"
            :disabled="busy"
            :placeholder="t('task.manualResolution.reasonPlaceholder')"
          />
        </label>
      </div>

      <div
        v-if="formErrorMessage"
        class="manual-resolution__error"
      >
        {{ formErrorMessage }}
      </div>

      <footer>
        <button
          type="button"
          class="primary-button"
          :disabled="busy || !canSubmit"
          @click="submitResolution"
        >
          <i
            class="pi pi-check-circle"
            aria-hidden="true"
          />
          {{ t('task.manualResolution.submit') }}
        </button>
      </footer>
    </template>
  </section>
</template>

<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'

import type {
  ReservationManualReviewResolutionRequest,
  ReservationRecord,
  ReservationTaskFieldResult,
} from '@/types/reservation'
import { normalizeStableCode } from '@/utils/reservationDisplay'
import { readReservationFieldValue } from '@/utils/reservationFieldRules'

interface ManualResolutionFieldItem {
  key: string
  pointer?: string
  fieldPath: string
  label: string
  field?: ReservationTaskFieldResult
}

const props = withDefaults(
  defineProps<{
    taskOrderId: string
    reviewStatus?: string | null
    reviewResolution?: ReservationRecord | null
    manualReview?: ReservationRecord | null
    fields?: ReservationTaskFieldResult[]
    fieldValues?: ReservationRecord
    busy?: boolean
  }>(),
  {
    reviewStatus: null,
    reviewResolution: null,
    manualReview: null,
    fields: () => [],
    fieldValues: () => ({}),
    busy: false,
  },
)

const emit = defineEmits<{
  submit: [request: ReservationManualReviewResolutionRequest]
}>()

const { t } = useI18n()
const confirmedOrderId = ref(props.taskOrderId)
const reason = ref('')
const formErrorMessage = ref('')
const fieldOverrideInputs = ref<Record<string, string>>({})
const isResolved = computed(() => normalizeStableCode(props.reviewStatus) === 'RESOLVED')
const reviewStatusLabel = computed(() => props.reviewStatus || t('task.manualResolution.pendingStatus'))
const supportedMissingFields = computed(() =>
  extractMissingFields(props.manualReview)
    .map((reference) => resolveMissingField(reference))
    .filter((item): item is ManualResolutionFieldItem => item !== null),
)
const canSubmit = computed(() => {
  if (!supportedMissingFields.value.length || !confirmedOrderId.value.trim()) {
    return false
  }
  return supportedMissingFields.value.every((item) => String(fieldOverrideInputs.value[item.key] ?? '').trim())
})

watch(
  () => props.taskOrderId,
  (nextOrderId) => {
    confirmedOrderId.value = nextOrderId
  },
)

watch(
  supportedMissingFields,
  (items) => {
    const nextInputs: Record<string, string> = {}
    items.forEach((item) => {
      nextInputs[item.key] = fieldOverrideInputs.value[item.key] || readCurrentFieldValue(item)
    })
    fieldOverrideInputs.value = nextInputs
  },
  { immediate: true },
)

function submitResolution(): void {
  formErrorMessage.value = ''
  if (!canSubmit.value) {
    formErrorMessage.value = t('task.manualResolution.fieldRequired')
    return
  }

  emit('submit', {
    confirmed_order_id: confirmedOrderId.value.trim(),
    reason: reason.value.trim() || undefined,
    field_overrides: supportedMissingFields.value.map((item) => ({
      ...(item.pointer ? { field_pointer: item.pointer } : {}),
      field_path: item.fieldPath,
      value: String(fieldOverrideInputs.value[item.key] ?? '').trim(),
    })),
  })
}

function extractMissingFields(manualReview: ReservationRecord | null | undefined): string[] {
  const missingFields = manualReview?.missing_fields
  if (!Array.isArray(missingFields)) {
    return []
  }
  return missingFields.filter((item): item is string => typeof item === 'string' && item.trim() !== '')
}

function resolveMissingField(reference: string): ManualResolutionFieldItem | null {
  const pointer = reference.startsWith('/') ? reference : undefined
  const referenceFieldPath = pointer ? fieldPointerToFieldPath(pointer) : reference
  const field = props.fields.find((item) =>
    item.field_pointer === reference ||
    item.field_path === referenceFieldPath ||
    item.legacy_field_path === referenceFieldPath,
  )
  if (field) {
    return {
      key: field.field_pointer ?? field.field_path,
      pointer: field.field_pointer ?? pointer,
      fieldPath: field.field_path,
      label: field.display_name,
      field,
    }
  }
  return null
}

function readCurrentFieldValue(item: ManualResolutionFieldItem): string {
  const value = item.field
    ? readReservationFieldValue(item.field, props.fieldValues)
    : props.fieldValues[item.fieldPath]
  return value === undefined || value === null ? '' : String(value)
}

function fieldPointerToFieldPath(pointer: string): string {
  return pointer.replace(/^\//, '').replace(/\//g, '.')
}

function formatJson(value: unknown): string {
  return JSON.stringify(value ?? {}, null, 2)
}
</script>

<style scoped>
.manual-resolution {
  display: grid;
  gap: 14px;
  border: 1px solid var(--th-color-warning);
  border-radius: var(--th-radius-lg);
  background: color-mix(in srgb, var(--th-color-warning) 8%, var(--th-color-white));
  padding: 16px;
}

.manual-resolution header {
  display: flex;
  justify-content: space-between;
  gap: 14px;
}

.manual-resolution h2,
.manual-resolution p {
  margin: 0;
}

.manual-resolution p {
  margin-top: 4px;
  color: var(--th-color-slate-500);
  font-size: 13px;
}

.manual-resolution__status {
  align-self: flex-start;
  border-radius: 999px;
  background: var(--th-color-white);
  color: var(--th-color-warning);
  font-size: 12px;
  font-weight: 800;
  padding: 5px 10px;
  white-space: nowrap;
}

.manual-resolution__meta dl,
.manual-resolution__form,
.manual-resolution__fields {
  display: grid;
  gap: 12px;
}

.manual-resolution__meta dl {
  margin: 0;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}

.manual-resolution__meta dt {
  color: var(--th-color-slate-500);
  font-size: 12px;
}

.manual-resolution__meta dd {
  margin: 3px 0 0;
  font-weight: 800;
}

.manual-resolution label {
  display: grid;
  gap: 6px;
  color: var(--th-color-slate-600);
  font-size: 12px;
  font-weight: 800;
}

.manual-resolution label small {
  display: block;
  margin-top: 3px;
  color: var(--th-color-slate-400);
  font-weight: 700;
}

.manual-resolution input,
.manual-resolution textarea {
  border: 1px solid var(--th-color-slate-200);
  border-radius: var(--th-radius-md);
  background: var(--th-color-white);
  color: var(--th-color-slate-900);
  font: inherit;
  padding: 10px 12px;
}

.manual-resolution__error,
.manual-resolution__empty {
  color: var(--th-color-danger);
  font-size: 13px;
  font-weight: 800;
}

.manual-resolution footer {
  display: flex;
  justify-content: flex-end;
}

.manual-resolution__resolved pre {
  margin: 8px 0 0;
  max-height: 180px;
  overflow: auto;
  border-radius: var(--th-radius-md);
  background: var(--th-color-slate-900);
  color: var(--th-color-white);
  padding: 12px;
}
</style>
