<script setup lang="ts">
import { formatPrice } from '~/composables/useOrderDetailPresentation';

type OrderItemView = {
  id: string;
  productName: string;
  quantity: number;
  sku?: string | null;
  unitPrice?: number | null;
  lineTotal?: number | null;
  parameters?: Record<string, unknown> | null;
};

type CalculationPayload = Record<string, unknown> | null | undefined;
type ItemParameter = { label: string; value: string };

const props = defineProps<{
  items: OrderItemView[];
  calculationPayload?: CalculationPayload;
  mode?: 'readonly' | 'manager-pricing' | 'cart';
  editable?: boolean;
  unitPriceDrafts?: Record<string, string>;
  editablePriceItemIds?: string[];
  disabled?: boolean;
  framed?: boolean;
  pricePlaceholder?: string;
}>();

const emit = defineEmits<{
  'update:unit-price': [payload: { itemId: string; value: string }];
  'activate:unit-price': [itemId: string];
  'finish:unit-price': [itemId: string];
  increment: [itemId: string];
  decrement: [itemId: string];
  remove: [itemId: string];
}>();

const coverPresets = ['#edf3ef', '#f1f4ee', '#edf2f4'];

function createProductCover(name: string, seedKey: string) {
  const seed = `${name}${seedKey}`.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0);
  const background = coverPresets[seed % coverPresets.length];
  const firstLetter = name.trim().charAt(0).toUpperCase() || 'P';

  const svg = `
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120">
      <rect width="120" height="120" fill="${background}" rx="28" />
      <text x="50%" y="57%" text-anchor="middle" fill="#11412c" font-family="Manrope, sans-serif" font-size="44" font-weight="700">${firstLetter}</text>
    </svg>
  `.trim();

  return `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`;
}

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

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

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

function currentUnitPrice(item: OrderItemView) {
  if (!isPricingMode.value) {
    return item.unitPrice ?? null;
  }

  return parseMoneyDraft(props.unitPriceDrafts?.[item.id]);
}

function currentLineTotal(item: OrderItemView) {
  const unitPrice = currentUnitPrice(item);
  if (unitPrice == null) {
    return null;
  }

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

function updateUnitPrice(itemId: string, event: Event) {
  emit('update:unit-price', {
    itemId,
    value: (event.target as HTMLInputElement).value,
  });
}

function activateUnitPrice(itemId: string) {
  if (!isPricingMode.value || props.disabled) {
    return;
  }

  emit('activate:unit-price', itemId);
}

function finishUnitPrice(itemId: string) {
  emit('finish:unit-price', itemId);
}

function incrementItem(itemId: string) {
  emit('increment', itemId);
}

function decrementItem(itemId: string) {
  emit('decrement', itemId);
}

function removeItem(itemId: string) {
  emit('remove', itemId);
}

function formatParameterValue(value: unknown) {
  if (typeof value === 'number') {
    return String(value);
  }

  return String(value ?? '').trim();
}

const mode = computed(() => props.mode ?? (props.editable ? 'manager-pricing' : 'readonly'));
const isPricingMode = computed(() => mode.value === 'manager-pricing');
const isCartMode = computed(() => mode.value === 'cart');
const isFramed = computed(() => props.framed ?? true);
const editablePriceItemIds = computed(() => new Set(props.editablePriceItemIds ?? []));
const displayPricePlaceholder = computed(() => props.pricePlaceholder ?? '—');

function mapParameterEntries(source: Record<string, unknown> | null | undefined): ItemParameter[] {
  if (!source || typeof source !== 'object') {
    return [];
  }

  const variants = [
    { key: 'width', label: 'Ширина', suffix: ' мм' },
    { key: 'thickness', label: 'Толщина', suffix: ' мкм' },
    { key: 'color', label: 'Цвет', suffix: '' },
  ];

  return variants
    .map((variant) => {
      const rawValue = source[variant.key];
      const value = formatParameterValue(rawValue);
      if (!value) {
        return null;
      }

      return {
        label: variant.label,
        value: `${value}${variant.suffix}`,
      };
    })
    .filter(Boolean) as ItemParameter[];
}

function itemParameters(item: OrderItemView) {
  if (item.parameters && typeof item.parameters === 'object') {
    return mapParameterEntries(item.parameters);
  }

  if (props.items.length !== 1 || !props.calculationPayload || typeof props.calculationPayload !== 'object') {
    return [];
  }

  return mapParameterEntries(props.calculationPayload);
}
</script>

<template>
  <div :class="isFramed ? 'surface-card rounded-3xl p-5' : ''">
    <ul class="space-y-3">
      <li
        v-for="item in items"
        :key="item.id"
        class="surface-card rounded-[28px] p-4 md:grid md:grid-cols-[minmax(0,1.8fr)_140px_160px_140px] md:gap-4 md:p-5"
      >
        <div class="flex min-w-0 gap-4">
          <img
            :src="createProductCover(item.productName, item.id)"
            :alt="item.productName"
            class="h-20 w-20 shrink-0 rounded-[24px] bg-[#edf3ef] object-cover"
          >

          <div class="min-w-0 space-y-2">
            <p class="text-base font-bold text-[#123824]">{{ item.productName }}</p>
            <p v-if="item.sku" class="text-xs font-semibold uppercase tracking-[0.14em] text-[#6a8a76]">
              SKU: {{ item.sku }}
            </p>

            <div v-if="itemParameters(item).length > 0" class="flex flex-wrap gap-2">
              <span
                v-for="parameter in itemParameters(item)"
                :key="parameter.label"
                class="rounded-full bg-[#f3f5f4] px-3 py-1 text-xs font-semibold text-[#355947]"
              >
                {{ parameter.label }}: {{ parameter.value }}
              </span>
            </div>
          </div>
        </div>

        <div class="mt-4 md:mt-0">
          <p class="mb-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-[#6a8a76] md:hidden">Цена</p>
          <input
            v-if="isPricingMode && editablePriceItemIds.has(item.id)"
            :value="unitPriceDrafts?.[item.id] ?? ''"
            type="number"
            min="0"
            step="0.01"
            placeholder="Например, 125.50"
            :data-unit-price-input="item.id"
            class="w-full rounded-2xl bg-[#f3f5f4] px-4 py-3 text-sm text-[#123824] outline-none transition focus:shadow-[0_0_0_3px_rgba(19,153,87,0.12)] disabled:cursor-not-allowed disabled:bg-[#f4f8f5]"
            :disabled="disabled"
            @input="updateUnitPrice(item.id, $event)"
            @blur="finishUnitPrice(item.id)"
            @keydown.enter="finishUnitPrice(item.id)"
          >
          <p
            v-else
            class="text-sm font-semibold text-[#123824]"
            :class="isPricingMode && !disabled ? 'cursor-pointer transition hover:text-[#0d854a]' : ''"
            @dblclick="activateUnitPrice(item.id)"
          >
            {{ formatPrice(currentUnitPrice(item)) || displayPricePlaceholder }}
          </p>
        </div>

        <div class="mt-4 md:mt-0">
          <p class="mb-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-[#6a8a76] md:hidden">Количество</p>
          <div v-if="isCartMode" class="flex flex-wrap items-center gap-2">
            <button
              type="button"
              class="flex h-9 w-9 items-center justify-center rounded-full bg-[#f3f5f4] text-lg font-semibold text-[#123824] transition hover:bg-[#e8efea] hover:text-[#139957]"
              @click="decrementItem(item.id)"
            >
              -
            </button>
            <span class="min-w-8 text-center text-sm font-semibold text-[#123824]">{{ item.quantity }}</span>
            <button
              type="button"
              class="flex h-9 w-9 items-center justify-center rounded-full bg-[#f3f5f4] text-lg font-semibold text-[#123824] transition hover:bg-[#e8efea] hover:text-[#139957]"
              @click="incrementItem(item.id)"
            >
              +
            </button>
            <button
              type="button"
              class="ml-1 text-sm font-semibold text-[#d94b55] transition hover:text-[#b73742]"
              @click="removeItem(item.id)"
            >
              Удалить
            </button>
          </div>
          <p v-else class="text-sm font-semibold text-[#123824]">{{ item.quantity }}</p>
        </div>

        <div class="mt-4 md:mt-0">
          <p class="mb-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-[#6a8a76] md:hidden">Итог</p>
          <p class="text-sm font-bold text-[#123824]">
            {{ formatPrice(currentLineTotal(item)) || '—' }}
          </p>
        </div>
      </li>
    </ul>
  </div>
</template>
