<script setup lang="ts">
import { useMutation, useQuery } from '@vue/apollo-composable';
import OrderStatusBadge from '~/components/orders/OrderStatusBadge.vue';
import {
  BlockOrderDocument,
  CompleteOrderDocument,
  ManagerFinalizeOrderDocument,
  ManagerOrdersDocument,
  ManagerSetOrderOfferDocument,
  StartOrderWorkDocument,
  type ManagerOrdersQuery,
} from '~/composables/graphql/generated';

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

type ManagerOrderItem = ManagerOrdersQuery['managerOrders'][number];

const ACTIVE_STATUSES = new Set(['NEW', 'MANAGER_PROCESSING', 'WAITING_DOUBLE_CONFIRM', 'CONFIRMED', 'IN_PROGRESS']);
const CLOSED_STATUSES = new Set(['COMPLETED', 'CLIENT_REJECTED', 'MANAGER_REJECTED', 'MANAGER_BLOCKED']);

const ordersQuery = useQuery(ManagerOrdersDocument, { status: null });

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

const search = ref('');
const statusFilter = ref<'ALL' | 'WAITING' | 'ACTIVE' | 'CLOSED'>('ALL');

const offerForm = reactive<Record<string, { deliveryTerms: string; deliveryFee: number; totalPrice: number }>>({});

watchEffect(() => {
  for (const order of ordersQuery.result.value?.managerOrders ?? []) {
    if (!offerForm[order.id]) {
      offerForm[order.id] = {
        deliveryTerms: order.deliveryTerms || 'Доставка 3-5 дней',
        deliveryFee: Number(order.deliveryFee ?? 1000),
        totalPrice: Number(order.totalPrice ?? 12500),
      };
    }
  }
});

function matchesFilter(order: ManagerOrderItem) {
  if (statusFilter.value === 'ALL') {
    return true;
  }
  if (statusFilter.value === 'WAITING') {
    return order.status === 'WAITING_DOUBLE_CONFIRM';
  }
  if (statusFilter.value === 'ACTIVE') {
    return ACTIVE_STATUSES.has(order.status);
  }
  return CLOSED_STATUSES.has(order.status);
}

function getOffer(orderId: string) {
  if (!offerForm[orderId]) {
    offerForm[orderId] = {
      deliveryTerms: 'Доставка 3-5 дней',
      deliveryFee: 1000,
      totalPrice: 12500,
    };
  }

  return offerForm[orderId];
}

function updateOfferField(orderId: string, field: 'deliveryTerms' | 'deliveryFee' | 'totalPrice', value: string) {
  const offer = getOffer(orderId);
  if (field === 'deliveryTerms') {
    offer.deliveryTerms = value;
    return;
  }

  const numericValue = Number(value);
  offer[field] = Number.isFinite(numericValue) ? numericValue : 0;
}

const filteredOrders = computed(() => {
  const orders = ordersQuery.result.value?.managerOrders ?? [];
  const query = search.value.trim().toLowerCase();

  return orders.filter((order) => {
    const haystack = [
      order.code,
      order.customerId || '',
      order.deliveryAddress || '',
      ...order.items.map((item) => item.productName),
    ]
      .join(' ')
      .toLowerCase();

    const matchSearch = !query || haystack.includes(query);
    return matchSearch && matchesFilter(order);
  });
});

async function refetchOrders() {
  await ordersQuery.refetch({
    status: null,
  });
}

async function publishOffer(orderId: string) {
  const form = getOffer(orderId);

  await setOfferMutation.mutate({
    input: {
      orderId,
      deliveryTerms: form.deliveryTerms,
      deliveryFee: Number(form.deliveryFee),
      totalPrice: Number(form.totalPrice),
    },
  });

  await refetchOrders();
}

async function approve(orderId: string) {
  await finalizeMutation.mutate({
    orderId,
    decision: 'APPROVE',
  });
  await refetchOrders();
}

async function reject(orderId: string) {
  await finalizeMutation.mutate({
    orderId,
    decision: 'REJECT',
  });
  await refetchOrders();
}

async function blockOrder(orderId: string) {
  await blockMutation.mutate({
    input: {
      orderId,
      reason: 'Нужно уточнение параметров заказа.',
    },
  });
  await refetchOrders();
}

async function start(orderId: string) {
  await startWorkMutation.mutate({
    orderId,
  });
  await refetchOrders();
}

async function complete(orderId: string) {
  await completeWorkMutation.mutate({
    orderId,
  });
  await refetchOrders();
}
</script>

<template>
  <section class="space-y-6">
    <div class="manager-hero">
      <p class="manager-eyebrow">Заказы клиентов</p>
      <h1 class="manager-title">Разбор заявок, офферов и статусов без отдельной менеджерки</h1>
      <p class="manager-copy">
        Фильтруйте заявки, публикуйте условия доставки, подтверждайте работу и доводите заказ до завершения прямо в основном кабинете.
      </p>
    </div>

    <div class="surface-card rounded-3xl p-4 md:p-5">
      <div class="grid gap-3 md:grid-cols-[1fr_auto]">
        <label class="form-control">
          <span class="label-text">Поиск</span>
          <input
            v-model="search"
            type="text"
            class="input manager-field w-full"
            placeholder="Номер, пользователь, адрес или товар"
          >
        </label>

        <label class="form-control md:min-w-60">
          <span class="label-text">Фильтр</span>
          <select v-model="statusFilter" class="select manager-field w-full">
            <option value="ALL">Все заказы</option>
            <option value="WAITING">Ожидают подтверждения</option>
            <option value="ACTIVE">Активные</option>
            <option value="CLOSED">Закрытые</option>
          </select>
        </label>
      </div>
    </div>

    <div v-if="ordersQuery.loading.value" class="manager-empty-state">
      Загружаем очередь заказов...
    </div>
    <div v-else-if="filteredOrders.length === 0" class="manager-empty-state">
      По текущим условиям заказов не найдено.
    </div>

    <div v-else class="space-y-4">
      <article
        v-for="order in filteredOrders"
        :key="order.id"
        class="surface-card rounded-3xl p-5"
      >
        <div class="flex flex-wrap items-start justify-between gap-3">
          <div class="space-y-1">
            <h2 class="text-xl font-bold text-[#123824]">{{ order.code }}</h2>
            <div class="flex flex-wrap gap-3 text-sm text-[#5c7b69]">
              <span>Клиент: {{ order.customerId || 'не указан' }}</span>
              <span>{{ new Date(order.createdAt).toLocaleString() }}</span>
            </div>
          </div>
          <OrderStatusBadge :status="order.status" />
        </div>

        <div class="mt-4 grid gap-3 lg:grid-cols-[1.1fr_0.9fr]">
          <div class="space-y-3">
            <div class="surface-subcard p-4">
              <p class="text-sm font-semibold text-[#123824]">Состав заказа</p>
              <ul class="mt-3 space-y-2 text-sm text-[#214735]">
                <li
                  v-for="item in order.items"
                  :key="item.id"
                  class="manager-mini-card"
                >
                  {{ item.productName }} × {{ item.quantity }}
                </li>
              </ul>
            </div>

            <div class="surface-subcard p-4">
              <p class="text-sm font-semibold text-[#123824]">Доставка</p>
              <div class="mt-3 grid gap-3 text-sm text-[#214735] md:grid-cols-2">
                <div class="manager-mini-card">
                  Адрес: {{ order.deliveryAddress || 'клиент еще не выбрал адрес' }}
                </div>
                <div class="manager-mini-card">
                  Условия: {{ order.deliveryTerms || 'ожидает оффера менеджера' }}
                </div>
              </div>
            </div>
          </div>

          <div class="surface-subcard p-4">
            <p class="text-sm font-semibold text-[#123824]">Оффер и действия</p>
            <div class="mt-3 space-y-3">
              <input
                :value="getOffer(order.id).deliveryTerms"
                class="input manager-field w-full"
                placeholder="Условия доставки"
                @input="updateOfferField(order.id, 'deliveryTerms', ($event.target as HTMLInputElement).value)"
              >
              <input
                :value="getOffer(order.id).deliveryFee"
                type="number"
                class="input manager-field w-full"
                placeholder="Стоимость доставки"
                @input="updateOfferField(order.id, 'deliveryFee', ($event.target as HTMLInputElement).value)"
              >
              <input
                :value="getOffer(order.id).totalPrice"
                type="number"
                class="input manager-field w-full"
                placeholder="Итоговая стоимость"
                @input="updateOfferField(order.id, 'totalPrice', ($event.target as HTMLInputElement).value)"
              >
            </div>

            <div class="mt-4 flex flex-wrap gap-2">
              <button class="btn btn-primary btn-sm border-0" @click="publishOffer(order.id)">Публиковать оффер</button>
              <button class="btn btn-success btn-sm border-0" @click="approve(order.id)">Подтвердить</button>
              <button class="btn btn-error btn-sm border-0" @click="reject(order.id)">Отклонить</button>
              <button class="btn btn-warning btn-sm border-0" @click="blockOrder(order.id)">Заблокировать</button>
              <button class="btn btn-accent btn-sm border-0" :disabled="order.status !== 'CONFIRMED'" @click="start(order.id)">В работу</button>
              <button class="btn btn-neutral btn-sm border-0" :disabled="order.status !== 'IN_PROGRESS'" @click="complete(order.id)">Завершить</button>
            </div>
          </div>
        </div>
      </article>
    </div>
  </section>
</template>
