<template>
  <section class="manual-conversion">
    <header>
      <div>
        <h2>{{ t('task.manualConversion.title') }}</h2>
        <p>{{ t('task.manualConversion.description') }}</p>
      </div>
    </header>

    <div class="manual-conversion-form">
      <label>
        <span>{{ t('task.manualConversion.targetTaskType') }}</span>
        <select
          v-model="manualConversionForm.target_task_type"
          name="manual_target_task_type"
          :disabled="busy"
          @change="handleManualTargetTypeChange"
        >
          <option
            v-for="targetTaskType in manualReviewTargetTaskTypes"
            :key="targetTaskType"
            :value="targetTaskType"
          >
            {{ formatReservationTaskCard(t, targetTaskType) }}
          </option>
        </select>
      </label>

      <label
        v-if="manualConversionNeedsTargetOrder"
        class="manual-conversion-search"
      >
        <span>{{ t('task.manualConversion.targetOrderKeyword') }}</span>
        <div class="manual-conversion-search-row">
          <input
            v-model="manualConversionForm.target_order_keyword"
            name="manual_target_order_keyword"
            type="search"
            :disabled="busy"
            :placeholder="t('task.manualConversion.targetOrderKeywordPlaceholder')"
          >
          <button
            type="button"
            class="secondary-button"
            :disabled="busy || targetOrderLoading"
            @click="searchTargetOrders"
          >
            {{ t('task.manualConversion.searchTargetOrders') }}
          </button>
        </div>
      </label>

      <label class="manual-conversion-reason">
        <span>{{ t('task.manualConversion.reason') }}</span>
        <textarea
          v-model="manualConversionForm.reason"
          name="manual_conversion_reason"
          rows="3"
          :disabled="busy"
          :placeholder="t('task.manualConversion.reasonPlaceholder')"
        />
      </label>
    </div>

    <div
      v-if="manualConversionNeedsTargetOrder"
      class="target-order-panel"
    >
      <div class="target-order-heading">
        <strong>{{ t('task.manualConversion.targetOrder') }}</strong>
        <span>{{ t('task.manualConversion.targetOrderHelp') }}</span>
      </div>

      <div
        v-if="targetOrderLoading"
        class="target-order-state"
      >
        {{ t('common.loading') }}
      </div>
      <div
        v-else-if="targetOrderErrorMessage"
        class="target-order-state target-order-state--error"
      >
        {{ targetOrderErrorMessage }}
      </div>
      <div
        v-else-if="!targetOrders.length"
        class="target-order-state"
      >
        {{ t('task.manualConversion.noTargetOrderCandidates') }}
      </div>
      <div
        v-else
        class="target-order-list"
      >
        <label
          v-for="order in targetOrders"
          :key="order.order_id"
          class="target-order-option"
          :class="{ 'target-order-option--disabled': isDeletedTargetOrder(order) }"
        >
          <input
            v-model="manualConversionForm.target_order_id"
            type="radio"
            name="manual_target_order_id"
            :value="order.order_id"
            :disabled="busy || isDeletedTargetOrder(order)"
          >
          <span>
            <strong>{{ formatOrderCandidateKey(order) }}</strong>
            <small>{{ formatOrderCandidateMeta(order) }}</small>
            <small
              v-if="isDeletedTargetOrder(order)"
              class="target-order-warning"
            >
              {{ t('task.manualConversion.orderDeletedDisabled') }}
            </small>
          </span>
          <ReservationStatusBadge :status="order.order_status" />
        </label>
      </div>
    </div>
    <p
      v-else
      class="manual-conversion-hint"
    >
      {{ t('task.manualConversion.newBookingHint') }}
    </p>

    <div
      v-if="conversionErrorMessage"
      class="manual-conversion-error"
    >
      {{ conversionErrorMessage }}
    </div>

    <footer class="manual-conversion-actions">
      <button
        type="button"
        class="primary-button"
        :disabled="busy"
        @click="submitManualReviewConversion"
      >
        <i
          class="pi pi-arrow-right-arrow-left"
          aria-hidden="true"
        />
        {{ t('task.manualConversion.submit') }}
      </button>
    </footer>
  </section>
</template>

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

import ReservationStatusBadge from '@/components/reservation/ReservationStatusBadge.vue'
import { fetchReservationOrders } from '@/services/reservationService'
import type {
  ReservationManualReviewConversionRequest,
  ReservationManualReviewTargetTaskType,
  ReservationOrderListItem,
} from '@/types/reservation'
import { formatReservationTaskCard } from '@/utils/reservationDisplay'

withDefaults(
  defineProps<{
    busy?: boolean
  }>(),
  {
    busy: false,
  },
)

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

const { t } = useI18n()
const targetOrders = ref<ReservationOrderListItem[]>([])
const targetOrderLoading = ref(false)
const targetOrderErrorMessage = ref('')
const conversionErrorMessage = ref('')
const manualReviewTargetTaskTypes: ReservationManualReviewTargetTaskType[] = [
  'NEW_BOOKING',
  'UPDATE_BOOKING',
  'CANCEL_BOOKING',
]
const manualConversionForm = ref({
  target_task_type: 'NEW_BOOKING' as ReservationManualReviewTargetTaskType,
  target_order_id: '',
  target_order_keyword: '',
  reason: '',
})
const manualConversionNeedsTargetOrder = computed(() => manualConversionForm.value.target_task_type !== 'NEW_BOOKING')

async function searchTargetOrders(): Promise<void> {
  targetOrderLoading.value = true
  targetOrderErrorMessage.value = ''
  conversionErrorMessage.value = ''
  try {
    const result = await fetchReservationOrders({
      keyword: manualConversionForm.value.target_order_keyword.trim(),
      page_num: 1,
      page_size: 8,
    })
    targetOrders.value = result.items
    const selectedOrder = targetOrders.value.find((order) => order.order_id === manualConversionForm.value.target_order_id)
    if (!selectedOrder || isDeletedTargetOrder(selectedOrder)) {
      manualConversionForm.value.target_order_id = ''
    }
  } catch (error) {
    targetOrders.value = []
    targetOrderErrorMessage.value = error instanceof Error ? error.message : String(error)
  } finally {
    targetOrderLoading.value = false
  }
}

function submitManualReviewConversion(): void {
  conversionErrorMessage.value = ''
  if (manualConversionNeedsTargetOrder.value && !manualConversionForm.value.target_order_id) {
    conversionErrorMessage.value = t('task.manualConversion.targetOrderRequired')
    return
  }
  emit('submit', buildManualReviewConversionRequest())
}

function buildManualReviewConversionRequest(): ReservationManualReviewConversionRequest {
  const request: ReservationManualReviewConversionRequest = {
    target_task_type: manualConversionForm.value.target_task_type,
  }
  if (manualConversionNeedsTargetOrder.value) {
    request.target_order_id = manualConversionForm.value.target_order_id
  }
  const reason = manualConversionForm.value.reason.trim()
  if (reason) {
    request.reason = reason
  }
  return request
}

function handleManualTargetTypeChange(): void {
  conversionErrorMessage.value = ''
  if (!manualConversionNeedsTargetOrder.value) {
    manualConversionForm.value.target_order_id = ''
  }
}

function isDeletedTargetOrder(order: ReservationOrderListItem): boolean {
  return normalizeStableCode(order.order_status) === 'LOGIC_DELETED'
}

function normalizeStableCode(code: string | null | undefined): string {
  return code?.trim().replace(/[\s-]+/g, '_').toUpperCase() ?? ''
}

function formatOrderCandidateKey(order: ReservationOrderListItem): string {
  return order.display_order_key ?? order.group_code ?? order.confirmation_number ?? order.temporary_order_no ?? order.order_id
}

function formatOrderCandidateMeta(order: ReservationOrderListItem): string {
  return [
    order.group_code ? `${t('orderList.groupCode')}: ${order.group_code}` : '',
    order.confirmation_number ? `${t('orderList.confirmationNumber')}: ${order.confirmation_number}` : '',
    `${t('task.manualConversion.orderId')}: ${order.order_id}`,
  ]
    .filter(Boolean)
    .join(' · ')
}
</script>

<style scoped>
.manual-conversion {
  display: grid;
  gap: 16px;
  border: 1px solid var(--th-color-blue-100);
  border-radius: var(--th-radius-md);
  background: var(--th-color-blue-100);
  padding: 16px;
}

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

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

.manual-conversion h2 {
  color: var(--th-color-slate-900);
  font-size: 15px;
}

.manual-conversion p,
.manual-conversion-hint,
.target-order-heading span,
.target-order-state {
  color: var(--th-color-slate-500);
  font-size: 12px;
  line-height: 1.55;
}

.manual-conversion-form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

.manual-conversion-form label {
  display: grid;
  gap: 7px;
}

.manual-conversion-form span {
  color: var(--th-color-slate-500);
  font-size: 12px;
  font-weight: 800;
}

.manual-conversion-form input,
.manual-conversion-form select,
.manual-conversion-form textarea {
  min-height: 38px;
  min-width: 0;
  border: 1px solid var(--th-color-slate-200);
  border-radius: var(--th-radius-sm);
  background: var(--th-color-white);
  color: var(--th-color-slate-900);
  padding: 8px 10px;
}

.manual-conversion-form textarea {
  resize: vertical;
}

.manual-conversion-reason {
  grid-column: 1 / -1;
}

.manual-conversion-search-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 8px;
}

.target-order-panel {
  display: grid;
  gap: 10px;
}

.target-order-heading {
  display: grid;
  gap: 4px;
}

.target-order-heading strong {
  color: var(--th-color-slate-900);
  font-size: 13px;
}

.target-order-state,
.manual-conversion-error {
  border: 1px dashed var(--th-color-slate-200);
  border-radius: var(--th-radius-sm);
  background: var(--th-color-white);
  padding: 12px;
}

.target-order-state--error,
.target-order-warning,
.manual-conversion-error {
  color: var(--th-color-danger);
}

.target-order-list {
  display: grid;
  gap: 8px;
}

.target-order-option {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  border: 1px solid var(--th-color-slate-200);
  border-radius: var(--th-radius-sm);
  background: var(--th-color-white);
  padding: 10px 12px;
}

.target-order-option strong,
.target-order-option small {
  display: block;
}

.target-order-option strong {
  color: var(--th-color-slate-900);
  font-size: 13px;
}

.target-order-option small {
  margin-top: 4px;
  color: var(--th-color-slate-500);
  font-size: 12px;
  overflow-wrap: anywhere;
}

.target-order-option--disabled {
  opacity: 0.66;
}

.manual-conversion-actions {
  display: flex;
  justify-content: flex-end;
}

.primary-button,
.secondary-button {
  display: inline-flex;
  min-height: 36px;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border-radius: var(--th-radius-sm);
  padding: 8px 14px;
  font-size: 13px;
  font-weight: 800;
  cursor: pointer;
}

.primary-button {
  border: 1px solid var(--th-color-blue-600);
  background: var(--th-color-blue-600);
  color: var(--th-color-white);
}

.secondary-button {
  border: 1px solid var(--th-color-slate-200);
  background: var(--th-color-white);
  color: var(--th-color-slate-900);
}

.primary-button:disabled,
.secondary-button:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

@media (max-width: 640px) {
  .manual-conversion-form,
  .manual-conversion-search-row {
    grid-template-columns: 1fr;
  }

  .target-order-option {
    grid-template-columns: auto minmax(0, 1fr);
  }
}
</style>
