import { z } from 'zod';
import {
  getPaymentMethod,
  getShippingMethod,
  isPaymentAllowedForShipping,
} from './catalog';

const pickupPointSchema = z
  .object({
    id: z.string().optional(),
    name: z.string().optional(),
    address: z.string().optional(),
    city: z.string().optional(),
    zip: z.string().optional(),
  })
  .passthrough()
  .optional();

export const orderSubmitSchema = z.object({
  firstname: z.string().min(1).max(80),
  lastname: z.string().min(1).max(80),
  phone: z.string().min(6).max(30),
  email: z.string().email().max(160),
  address: z.string().min(3).max(500),
  city: z.string().min(1).max(120),
  zip: z.string().min(4).max(12),
  country: z.string().length(2).default('PL'),
  paymentMethod: z.string().min(1),
  shippingMethodId: z.string().min(1),
  shippingMethodName: z.string().optional(),
  shippingPrice: z.coerce.number().min(0),
  deliveryType: z.enum(['store', 'pickup', 'courier']).optional(),
  pickupPointId: z.string().optional(),
  pickupPointJson: pickupPointSchema,
  invoiceIsCompany: z.boolean().optional(),
  companyName: z.string().max(200).optional(),
  vatin: z.string().max(20).optional(),
  regon: z.string().max(20).optional(),
  notes: z.string().max(2000).optional(),
});

export type OrderSubmitInput = z.infer<typeof orderSubmitSchema>;

export function validateOrderSubmit(
  body: unknown,
  cartTotal: number,
): { ok: true; data: OrderSubmitInput } | { ok: false; error: string } {
  const parsed = orderSubmitSchema.safeParse(body);
  if (!parsed.success) {
    const msg = parsed.error.issues[0]?.message ?? 'Invalid request';
    return { ok: false, error: msg };
  }

  const data = parsed.data;
  const shipping = getShippingMethod(data.shippingMethodId);
  if (!shipping) {
    return { ok: false, error: 'Nieprawidłowa metoda dostawy' };
  }

  if (Math.abs(data.shippingPrice - shipping.price) > 0.02) {
    return { ok: false, error: 'Nieprawidłowa cena dostawy' };
  }

  if (!isPaymentAllowedForShipping(data.shippingMethodId, data.paymentMethod)) {
    return { ok: false, error: 'Wybrana płatność nie jest dostępna dla tej dostawy' };
  }

  const payment = getPaymentMethod(data.paymentMethod);
  if (!payment || payment.disabled) {
    return { ok: false, error: 'Nieprawidłowa metoda płatności' };
  }

  const deliveryType = data.deliveryType ?? shipping.type;
  if (deliveryType === 'pickup' || deliveryType === 'store') {
    if (!data.pickupPointId && !data.pickupPointJson?.id) {
      return { ok: false, error: 'Wybierz punkt odbioru' };
    }
  }

  if (deliveryType === 'courier') {
    const zipOk = /^\d{2}-\d{3}$/.test(data.zip.trim());
    if (!zipOk) {
      return { ok: false, error: 'Nieprawidłowy kod pocztowy (format: 00-000)' };
    }
  }

  const expectedTotal = Math.round((cartTotal + shipping.price) * 100) / 100;
  void expectedTotal;

  return { ok: true, data };
}

export function orderTotalWithShipping(cartTotal: number, shippingPrice: number): number {
  return Math.round((cartTotal + shippingPrice) * 100) / 100;
}
