<script setup lang="ts">
import { useMutation, useQuery } from '@vue/apollo-composable';
import {
  BlockOrderDocument,
  CompleteOrderDocument,
  ManagerFinalizeOrderDocument,
  ManagerSetOrderOfferDocument,
  OrderDetailDocument,
  StartOrderWorkDocument,
  type OrderDetailQuery,
} from '~/composables/graphql/generated';
import {
  formatPrice,
  orderLogisticsStateText,
  orderDeliveryStateText,
  orderLineStateText,
} from '~/composables/useOrderDetailPresentation';

definePageMeta({
  middleware: ['manager-only'],
});

const route = useRoute();
const orderId = computed(() => String(route.params.id || ''));

type ManagerOrderItem = NonNullable<OrderDetailQuery['order']>;

const orderQuery = useQuery(OrderDetailDocument, () => ({
  id: orderId.value,
}));

const finalizeMutation = useMutation(ManagerFinalizeOrderDocument);
const blockMutation = useMutation(BlockOrderDocument);
const startWorkMutation = useMutation(StartOrderWorkDocument);
const completeWorkMutation = useMutation(CompleteOrderDocument);
const setOfferMutation = useMutation(ManagerSetOrderOfferDocument);

const itemPriceDrafts = reactive<Record<string, string>>({});
const deliveryTermsDraft = ref('');
const deliveryFeeDraft = ref('');

const currentOrder = computed<ManagerOrderItem | null>(() =>
  orderQuery.result.value?.order ?? null,
);

watch(
  currentOrder,
  (order) => {
    for (const key of Object.keys(itemPriceDrafts)) {
      delete itemPriceDrafts[key];
    }

    if (!order) {
      deliveryTermsDraft.value = '';
      deliveryFeeDraft.value = '';
      return;
    }

    for (const item of order.items) {
      itemPriceDrafts[item.id] = item.unitPrice == null ? '' : String(item.unitPrice);
    }

    deliveryTermsDraft.value = order.deliveryTerms ?? '';
    deliveryFeeDraft.value = order.deliveryFee == null ? '' : String(order.deliveryFee);
  },
  { immediate: true },
);

function parseMoneyDraft(value: string) {
  const trimmed = String(value).replace(',', '.').trim();
  if (!trimmed) {
    return null;
  }

  const normalized = Number(trimmed);
  if (!Number.isFinite(normalized) || normalized < 0) {
    return null;
  }

  return Math.round((normalized + Number.EPSILON) * 100) / 100;
}

function draftUnitPrice(itemId: string, fallback?: number | null) {
  return parseMoneyDraft(itemPriceDrafts[itemId] ?? '') ?? fallback ?? null;
}

function draftLineTotal(item: ManagerOrderItem['items'][number]) {
  const unitPrice = draftUnitPrice(item.id, item.unitPrice);
  if (unitPrice == null) {
    return null;
  }

  return Math.round((unitPrice * item.quantity + Number.EPSILON) * 100) / 100;
}

const draftDeliveryTerms = computed(() => deliveryTermsDraft.value.trim() || currentOrder.value?.deliveryTerms || null);
const draftDeliveryFee = computed(() => parseMoneyDraft(deliveryFeeDraft.value) ?? currentOrder.value?.deliveryFee ?? null);

const offerReady = computed(() => {
  if (!currentOrder.value) {
    return false;
  }

  const deliveryFee = parseMoneyDraft(deliveryFeeDraft.value);
  if (deliveryFee == null) {
    return false;
  }

  return currentOrder.value.items.every((item) => parseMoneyDraft(itemPriceDrafts[item.id] ?? '') != null);
});

const offerTotal = computed(() => {
  if (!currentOrder.value || !offerReady.value) {
    return null;
  }

  const productsTotal = currentOrder.value.items.reduce((sum, item) => (
    sum + item.quantity * (parseMoneyDraft(itemPriceDrafts[item.id] ?? '') ?? 0)
  ), 0);

  return Math.round((productsTotal + (parseMoneyDraft(deliveryFeeDraft.value) ?? 0) + Number.EPSILON) * 100) / 100;
});

async function refetchOrder() {
  await orderQuery.refetch({ id: orderId.value });
}

async function saveOffer() {
  if (!currentOrder.value || !offerReady.value) {
    return;
  }

  await setOfferMutation.mutate({
    input: {
      orderId: currentOrder.value.id,
      itemPrices: currentOrder.value.items.map((item) => ({
        itemId: item.id,
        unitPrice: parseMoneyDraft(itemPriceDrafts[item.id] ?? '') ?? 0,
      })),
      deliveryTerms: deliveryTermsDraft.value.trim(),
      deliveryFee: parseMoneyDraft(deliveryFeeDraft.value) ?? 0,
    },
  });
  await refetchOrder();
}

async function approveOrder() {
  if (!currentOrder.value) {
    return;
  }

  await finalizeMutation.mutate({ orderId: currentOrder.value.id, decision: 'APPROVE' });
  await refetchOrder();
}

async function rejectOrder() {
  if (!currentOrder.value) {
    return;
  }

  await finalizeMutation.mutate({ orderId: currentOrder.value.id, decision: 'REJECT' });
  await refetchOrder();
}

async function blockOrder() {
  if (!currentOrder.value) {
    return;
  }

  await blockMutation.mutate({
    input: {
      orderId: currentOrder.value.id,
      reason: 'Нужно уточнение параметров заказа.',
    },
  });
  await refetchOrder();
}

async function startOrder() {
  if (!currentOrder.value) {
    return;
  }

  await startWorkMutation.mutate({ orderId: currentOrder.value.id });
  await refetchOrder();
}

async function completeOrder() {
  if (!currentOrder.value) {
    return;
  }

  await completeWorkMutation.mutate({ orderId: currentOrder.value.id });
  await refetchOrder();
}
</script>

<template>
  <section class="space-y-6">
    <NuxtLink to="/client-orders" class="text-sm font-semibold text-[#0d854a]">← Назад к заказам клиентов</NuxtLink>

    <div v-if="orderQuery.loading.value" class="manager-empty-state">
      Загружаем заказ...
    </div>

    <div v-else-if="!currentOrder" class="manager-empty-state">
      Заказ не найден.
    </div>

    <template v-else>
      <div class="manager-hero">
        <p class="manager-eyebrow">Заказ</p>
        <h1 class="manager-title">{{ currentOrder.code }}</h1>
      </div>

      <div class="space-y-4">
        <OrdersOrderStatusTimelineCard
          :status="currentOrder.status"
          :created-at="currentOrder.createdAt"
        />

        <div class="surface-card rounded-3xl p-5">
          <h2 class="text-xl font-bold text-[#123824]">Состав заказа</h2>
          <ul class="mt-4 space-y-3">
            <li v-for="item in currentOrder.items" :key="item.id" class="manager-mini-card space-y-3">
              <div class="space-y-1">
                <p class="text-sm font-semibold text-[#123824]">{{ item.productName }} × {{ item.quantity }}</p>
                <p class="text-sm text-[#5c7b69]">{{ orderLineStateText(draftUnitPrice(item.id, item.unitPrice), draftLineTotal(item)) }}</p>
              </div>

              <label class="form-control">
                <span class="mb-2 text-xs font-semibold uppercase tracking-[0.22em] text-[#6a8a76]">Цена за единицу</span>
                <input
                  v-model="itemPriceDrafts[item.id]"
                  type="number"
                  min="0"
                  step="0.01"
                  placeholder="Например, 125.50"
                  class="input input-bordered w-full rounded-2xl bg-white"
                >
              </label>
            </li>
          </ul>
        </div>

        <div class="surface-card rounded-3xl p-5">
          <h2 class="text-xl font-bold text-[#123824]">Доставка</h2>
          <div class="mt-4 space-y-3">
            <div class="manager-mini-card text-sm text-[#123824]">
              Адрес: {{ currentOrder.deliveryAddress || 'Адрес пока не указан' }}
            </div>
            <div class="manager-mini-card space-y-3 text-sm text-[#123824]">
              <p>{{ orderDeliveryStateText(draftDeliveryTerms) }}</p>
              <label class="form-control">
                <span class="mb-2 text-xs font-semibold uppercase tracking-[0.22em] text-[#6a8a76]">Комментарий по доставке</span>
                <input
                  v-model="deliveryTermsDraft"
                  type="text"
                  placeholder="Например, доставка до склада 2-3 дня"
                  class="input input-bordered w-full rounded-2xl bg-white"
                >
              </label>
            </div>
            <div class="manager-mini-card space-y-3 text-sm text-[#123824]">
              <p>{{ orderLogisticsStateText(draftDeliveryFee) }}</p>
              <label class="form-control">
                <span class="mb-2 text-xs font-semibold uppercase tracking-[0.22em] text-[#6a8a76]">Стоимость логистики</span>
                <input
                  v-model="deliveryFeeDraft"
                  type="number"
                  min="0"
                  step="0.01"
                  placeholder="Например, 3000"
                  class="input input-bordered w-full rounded-2xl bg-white"
                >
              </label>
            </div>
          </div>

          <div class="mt-4 flex flex-wrap items-center justify-between gap-3 border-t border-[#d6ebde] pt-4">
            <p class="text-sm text-[#5c7b69]">
              {{
                offerTotal == null
                  ? 'Итог по заказу посчитается автоматически после заполнения всех цен.'
                  : `Предварительный итог: ${formatPrice(offerTotal)}`
              }}
            </p>
            <button
              class="btn btn-primary rounded-full border-0 px-5"
              :disabled="!offerReady || setOfferMutation.loading.value"
              @click="saveOffer"
            >
              Сохранить условия
            </button>
          </div>
        </div>

        <div class="surface-card rounded-3xl p-5">
          <div class="flex flex-wrap items-center justify-between gap-3">
            <h2 class="text-xl font-bold text-[#123824]">Действия менеджера</h2>
            <div class="flex flex-wrap gap-2">
              <button class="btn btn-success btn-sm border-0" @click="approveOrder">Подтвердить</button>
              <button class="btn btn-error btn-sm border-0" @click="rejectOrder">Отклонить</button>
              <button class="btn btn-warning btn-sm border-0" @click="blockOrder">Заблокировать</button>
              <button class="btn btn-accent btn-sm border-0" :disabled="currentOrder.status !== 'CONFIRMED'" @click="startOrder">В работу</button>
              <button class="btn btn-neutral btn-sm border-0" :disabled="currentOrder.status !== 'IN_PROGRESS'" @click="completeOrder">Завершить</button>
            </div>
          </div>
        </div>
      </div>
    </template>
  </section>
</template>
