<script setup lang="ts">
import {
  GetTeamOrdersDocument,
  type GetTeamOrdersQueryResult,
  type GetTeamOrdersQueryVariables,
} from '~/composables/graphql/team/orders-generated'

definePageMeta({
  layout: 'manager',
  middleware: ['auth-oidc'],
})

type TeamOrder = NonNullable<NonNullable<GetTeamOrdersQueryResult['getTeamOrders']>[number]>
type TeamStage = NonNullable<NonNullable<TeamOrder['stages']>[number]>
type OrdersViewMode = 'list' | 'calendar'

const { execute } = useGraphQL()
const localePath = useLocalePath()
const route = useRoute()
const { locale } = useI18n()
const search = ref('')
const visibleLimit = ref(12)

const {
  data,
  pending,
  error,
  refresh,
} = await useAsyncData('manager-orders-optovia', async () => {
  const response = await execute(GetTeamOrdersDocument, {} as GetTeamOrdersQueryVariables, 'team', 'orders')
  return response.getTeamOrders || []
})

const orders = computed(() => (Array.isArray(data.value) ? data.value.filter((item): item is TeamOrder => item !== null) : []))
const viewMode = computed<OrdersViewMode>(() => route.query.view === 'calendar' ? 'calendar' : 'list')
const filteredOrders = computed(() => {
  const query = search.value.trim().toLowerCase()
  if (!query) return orders.value

  return orders.value.filter((item) => {
    const haystack = [
      item.uuid,
      item.name,
      item.status,
      item.sourceLocationName,
      item.destinationLocationName,
      ...(item.orderLines || []).map(line => line?.productName || ''),
      ...(item.stages || []).map(stage => stage?.name || ''),
    ]
      .filter(Boolean)
      .join(' ')
      .toLowerCase()

    return haystack.includes(query)
  })
})
const visibleOrders = computed(() => filteredOrders.value.slice(0, visibleLimit.value))
const canLoadMoreOrders = computed(() => visibleOrders.value.length < filteredOrders.value.length)
const totalTurnover = computed(() => orders.value.reduce((sum, item) => sum + Number(item.totalAmount || 0), 0))
const inTransitCount = computed(() => orders.value.filter(item => ['processing', 'in_transit'].includes(String(item.status || '').toLowerCase())).length)
const deliveredCount = computed(() => orders.value.filter(item => ['delivered', 'completed'].includes(String(item.status || '').toLowerCase())).length)

const orderViewTabs = computed<Array<{ key: OrdersViewMode, label: string, active: boolean }>>(() => ([
  { key: 'list', label: 'Списком', active: viewMode.value === 'list' },
  { key: 'calendar', label: 'Календарь', active: viewMode.value === 'calendar' },
]))

function formatMoney(value?: number | null, currency?: string | null) {
  return new Intl.NumberFormat(locale.value === 'ru' ? 'ru-RU' : 'en-US', {
    style: 'currency',
    currency: currency || 'USD',
    maximumFractionDigits: 0,
  }).format(Number(value || 0))
}

function formatDate(value?: string | null) {
  if (!value) return ''
  return new Intl.DateTimeFormat(locale.value === 'ru' ? 'ru-RU' : 'en-US', {
    day: '2-digit',
    month: 'short',
  }).format(new Date(value))
}

function routeLabel(item: TeamOrder) {
  return `${item.sourceLocationName || 'Откуда'} - ${item.destinationLocationName || 'Куда'}`
}

function cargoLabel(item: TeamOrder) {
  const lines = (item.orderLines || [])
    .filter((line): line is NonNullable<(typeof item.orderLines)[number]> => line !== null)
    .map(line => `${line.productName || 'Cargo'}${line.quantity ? ` · ${line.quantity} ${line.unit || ''}` : ''}`)
  return lines.slice(0, 2).join(' · ') || 'Состав груза уточняется'
}

function statusMeta(status?: string | null) {
  const normalized = String(status || '').toLowerCase()
  if (normalized === 'delivered' || normalized === 'completed') return { label: 'Завершён', className: 'bg-emerald-100 text-emerald-700' }
  if (normalized === 'cancelled' || normalized === 'canceled') return { label: 'Отменён', className: 'bg-rose-100 text-rose-700' }
  if (normalized === 'in_transit' || normalized === 'processing') return { label: 'В пути', className: 'bg-sky-100 text-sky-700' }
  return { label: 'В работе', className: 'bg-amber-100 text-amber-700' }
}

function checkpointLabel(item: TeamOrder) {
  const stages = (item.stages || []).filter((stage): stage is TeamStage => stage !== null)
  return stages[0]?.name || 'Этап уточняется'
}

function customerLabel(item: TeamOrder) {
  return `Клиент ${(item.uuid || 'order').slice(-6).toUpperCase()}`
}

function stageCount(item: TeamOrder) {
  return (item.stages || []).filter(Boolean).length
}

function mapCalendarOrders() {
  return filteredOrders.value.map((item) => {
    const stages = (item.stages || []).filter((stage): stage is TeamStage => stage !== null)
    const checkpoints = stages.map((stage, index) => {
      const firstTrip = (stage.trips || []).find(Boolean)
      return {
        code: stage.uuid || `stage-${index}`,
        name: stage.name || 'Этап',
        plannedDate: firstTrip?.plannedLoadingDate || firstTrip?.plannedUnloadingDate || null,
        actualDate: firstTrip?.actualLoadingDate || firstTrip?.actualUnloadingDate || null,
        completed: Boolean(firstTrip?.actualUnloadingDate || firstTrip?.realLoadingDate),
        current: index === 0,
      }
    })

    return {
      id: item.uuid || '',
      status: item.status || '',
      totalAmount: Number(item.totalAmount || 0),
      currency: item.currency || 'USD',
      createdAt: item.createdAt || new Date().toISOString(),
      pickupDate: checkpoints[0]?.plannedDate || null,
      fromAddress: {
        city: item.sourceLocationName || '',
        country: '',
      },
      toAddress: {
        city: item.destinationLocationName || '',
        country: '',
      },
      currentCheckpoint: checkpoints[0] || null,
      checkpoints,
    }
  }).filter(order => order.id)
}

async function openOrder(orderId?: string | null) {
  if (!orderId) return
  await navigateTo(localePath(`/manager/orders/${orderId}`))
}

async function setViewMode(nextMode: OrdersViewMode) {
  const nextQuery = { ...route.query }
  if (nextMode === 'calendar') {
    nextQuery.view = 'calendar'
  } else {
    delete nextQuery.view
  }

  await navigateTo({
    path: route.path,
    query: nextQuery,
  }, { replace: true })
}

async function loadMoreOrders() {
  visibleLimit.value += 12
  await refresh()
}
</script>

<template>
  <div>
    <section class="grid gap-3 lg:grid-cols-4">
      <article class="rounded-[28px] bg-white p-5 shadow-none">
        <p class="text-xs font-bold uppercase tracking-[0.14em] text-[#8c7b67]">Orders</p>
        <p class="mt-3 text-3xl font-black text-[#2f2418]">{{ orders.length }}</p>
        <p class="mt-1 text-sm text-[#6f6353]">Активный пул заказов в microservice flow</p>
      </article>
      <article class="rounded-[28px] bg-white p-5 shadow-none">
        <p class="text-xs font-bold uppercase tracking-[0.14em] text-[#8c7b67]">In transit</p>
        <p class="mt-3 text-3xl font-black text-[#2f2418]">{{ inTransitCount }}</p>
        <p class="mt-1 text-sm text-[#6f6353]">Маршруты, которые сейчас в движении</p>
      </article>
      <article class="rounded-[28px] bg-white p-5 shadow-none">
        <p class="text-xs font-bold uppercase tracking-[0.14em] text-[#8c7b67]">Delivered</p>
        <p class="mt-3 text-3xl font-black text-[#2f2418]">{{ deliveredCount }}</p>
        <p class="mt-1 text-sm text-[#6f6353]">Завершённые кейсы для менеджерского кабинета</p>
      </article>
      <article class="rounded-[28px] bg-white p-5 shadow-none">
        <p class="text-xs font-bold uppercase tracking-[0.14em] text-[#8c7b67]">Turnover</p>
        <p class="mt-3 text-3xl font-black text-[#2f2418]">{{ formatMoney(totalTurnover, orders[0]?.currency || 'USD') }}</p>
        <p class="mt-1 text-sm text-[#6f6353]">Сумма по заказам без фронтового Odoo-слоя</p>
      </article>
    </section>

    <section class="mt-6 flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
      <div>
        <p class="text-xs font-bold uppercase tracking-[0.16em] text-[#8c7b67]">Manager workspace</p>
        <h2 class="mt-1 text-3xl font-black text-[#2f2418]">Orders</h2>
      </div>

      <div class="flex w-full flex-col gap-3 lg:w-auto lg:min-w-[620px] lg:flex-row">
        <label class="block flex-1">
          <span class="sr-only">Search orders</span>
          <input
            v-model="search"
            class="input h-12 w-full rounded-full border-0 bg-white px-5 shadow-none"
            placeholder="Поиск по маршруту, грузу или этапу"
          >
        </label>

        <div class="inline-flex w-fit items-center rounded-full bg-white p-1 shadow-[0_16px_38px_rgba(38,29,18,0.08)]">
          <button
            v-for="tab in orderViewTabs"
            :key="tab.key"
            type="button"
            class="rounded-full px-4 py-2 text-sm font-bold transition"
            :class="tab.active ? 'bg-[#2f2418] text-white' : 'text-[#6a5947] hover:bg-[#f6f1ea]'"
            @click="setViewMode(tab.key)"
          >
            {{ tab.label }}
          </button>
        </div>
      </div>
    </section>

    <section v-if="pending && !orders.length" class="mt-6 rounded-[28px] bg-white p-8 text-center">
      <p class="text-sm opacity-70">Загружаем заказы…</p>
    </section>

    <section v-else-if="error" class="mt-6 rounded-[28px] bg-rose-50/92 p-6 text-rose-700">
      <p class="text-sm font-medium">Не удалось загрузить manager orders</p>
      <p class="mt-2 text-sm opacity-80">{{ error.message }}</p>
    </section>

    <OrdersCalendarPanel
      v-else-if="viewMode === 'calendar'"
      class="mt-6"
      :orders="mapCalendarOrders()"
      @select="openOrder"
    />

    <section v-else class="mt-6 space-y-3">
      <article
        v-for="item in visibleOrders"
        :key="item.uuid"
        class="cursor-pointer rounded-[28px] bg-white px-6 py-5 shadow-none transition-[transform,box-shadow] hover:-translate-y-0.5 hover:shadow-[0_18px_34px_rgba(62,47,26,0.12)]"
        @click="openOrder(item.uuid)"
      >
        <div class="grid gap-3 md:grid-cols-[minmax(0,2.1fr)_minmax(0,1.15fr)_auto_auto] md:items-center">
          <div class="flex min-w-0 items-start gap-4">
            <UserAvatar
              :seed="item.uuid"
              :label="customerLabel(item)"
              :size="52"
            />
            <div class="min-w-0">
              <p class="truncate text-sm font-bold text-[#8a7761]">{{ customerLabel(item) }}</p>
              <p class="mt-1 truncate text-lg font-black leading-tight text-[#2f2418]">{{ routeLabel(item) }}</p>
              <p class="mt-1 truncate text-sm text-[#6f6353]">{{ cargoLabel(item) }}</p>
            </div>
          </div>

          <div class="min-w-0 text-sm text-[#6f6353]">
            <p class="truncate">{{ checkpointLabel(item) }}</p>
            <p class="mt-1 truncate text-xs text-[#998b78]">
              {{ stageCount(item) }} этапов · {{ formatDate(item.createdAt) }}
            </p>
          </div>

          <div class="md:text-right">
            <span class="inline-flex rounded-full px-3 py-1 text-xs font-semibold" :class="statusMeta(item.status).className">
              {{ statusMeta(item.status).label }}
            </span>
          </div>

          <div class="whitespace-nowrap text-right text-lg font-semibold text-[#2f2418]">
            {{ formatMoney(item.totalAmount, item.currency) }}
          </div>
        </div>
      </article>

      <article
        v-if="visibleOrders.length === 0"
        class="rounded-[28px] bg-white p-8 text-center"
      >
        <p class="text-lg font-semibold text-[#2f2418]">Заказы не найдены</p>
        <p class="mt-2 text-sm text-[#6f6353]">Попробуй изменить строку поиска или фильтр представления.</p>
      </article>
    </section>

    <ManagerListLoadMore
      v-if="!error && visibleOrders.length"
      class="mt-5"
      :shown="visibleOrders.length"
      :total="filteredOrders.length"
      :can-load-more="canLoadMoreOrders"
      :loading="pending"
      :page-size="12"
      item-label="заказов"
      @load-more="loadMoreOrders"
    />
  </div>
</template>
