import React, { createContext, useContext, useState, ReactNode, useCallback, useEffect } from 'react';
import { defaultShippingMethods } from '@/lib/shippingConfig';

export interface ShippingOption {
  id: string;
  name: string;
  price: number;
  days: number;
  type?: 'home_delivery' | 'pickup_point' | 'zbox';
  carrier?: string;
  requiresLocation?: boolean;
}

export interface PickupPoint {
  id: string | number;
  name: string;
  city: string;
  street: string;
  zip: string;
  country: string;
  latitude?: number;
  longitude?: number;
  pickupPointType?: string;
  place?: string;
  directions?: string;
  code?: string;
  rawDetail?: any;
}

export interface ContactInfo {
  firstName?: string;
  lastName?: string;
  email?: string;
  phonePrefix?: string;
  phone?: string;
  street?: string;
  city?: string;
  zip?: string;
  orderNote?: string;
}

export interface PacketaWidgetConfig {
  language: string;
  valueFormat: string;
  view: 'modal' | 'inline';
  vendors: Array<{ country: string; group?: string }>;
}

export interface PacketaErrorMessages {
  pickupPoint: string;
  zbox: string;
}

export interface PacketaUILabels {
  selectPickupPointTitle: string;
  selectZBoxTitle: string;
  selectedPickupPointLabel: string;
  selectedZBoxLabel: string;
  changeLocationButton: string;
  widgetOpeningMessage: string;
  widgetOpenButton: string;
}

interface CheckoutContextType {
  selectedShipping: string | null;
  setSelectedShipping: (shippingId: string | null) => void;
  contactInfo: ContactInfo;
  setContactInfo: (info: ContactInfo) => void;
  shippingOptions: ShippingOption[];
  pickupPoints: PickupPoint[];
  selectedPickupPoint: PickupPoint | null;
  setSelectedPickupPoint: (point: PickupPoint | null) => void;
  loadingLocations: boolean;
  fetchPickupPoints: (zip: string) => Promise<void>;
  packetaConfig: PacketaWidgetConfig;
  packetaErrorMessages: PacketaErrorMessages;
  packetaUILabels: PacketaUILabels;
  getPacketaConfig: (shippingType?: string) => PacketaWidgetConfig;
}

export const SHIPPING_OPTIONS: ShippingOption[] = defaultShippingMethods
  .filter((method) => method.enabled)
  .map(({ id, name, price, days, type, carrier, requiresLocation }) => ({ id, name, price, days, type, carrier, requiresLocation }));

export const PACKETA_SHIPPING_OPTIONS = SHIPPING_OPTIONS.filter((option) => option.carrier === 'packeta');
export const CZECH_POST_SHIPPING_OPTIONS = SHIPPING_OPTIONS.filter((option) => option.carrier === 'czech_post');
export const PPL_SHIPPING_OPTIONS = SHIPPING_OPTIONS.filter((option) => option.carrier === 'ppl');
export const GLS_SHIPPING_OPTIONS = SHIPPING_OPTIONS.filter((option) => option.carrier === 'gls');
export const DPD_SHIPPING_OPTIONS = SHIPPING_OPTIONS.filter((option) => option.carrier === 'dpd');

// Legacy support
export const ALL_SHIPPING_OPTIONS = SHIPPING_OPTIONS;

// Packeta Widget Configuration - for regular pickup points
export const PACKETA_WIDGET_PICKUP_POINT_CONFIG: PacketaWidgetConfig = {
  language: 'cs',
  valueFormat: '"Packeta",id,carrierId,carrierPickupPointId,name,city,street',
  view: 'modal',
  vendors: [
    { country: 'cz' },
    { country: 'sk' },
  ],
};

// Packeta Widget Configuration - for Z-BOX
export const PACKETA_WIDGET_ZBOX_CONFIG: PacketaWidgetConfig = {
  language: 'cs',
  valueFormat: '"Packeta",id,carrierId,carrierPickupPointId,name,city,street',
  view: 'modal',
  vendors: [
    { country: 'cz', group: 'zbox' },
    { country: 'sk', group: 'zbox' },
  ],
};

// Default config (fallback)
export const PACKETA_WIDGET_DEFAULT_CONFIG: PacketaWidgetConfig = PACKETA_WIDGET_PICKUP_POINT_CONFIG;

// Packeta Error Messages
export const PACKETA_ERROR_MESSAGES: PacketaErrorMessages = {
  pickupPoint: 'Vyberte místo vyzvednutí',
  zbox: 'Vyberte Z-BOX',
};

// Packeta UI Labels
export const PACKETA_UI_LABELS: PacketaUILabels = {
  selectPickupPointTitle: 'Vyberte místo vyzvednutí',
  selectZBoxTitle: 'Vyberte Z-BOX',
  selectedPickupPointLabel: 'Vybrané místo vyzvednutí',
  selectedZBoxLabel: 'Vybraný Z-BOX',
  changeLocationButton: 'Změnit místo',
  widgetOpeningMessage: 'Pokud se karta neotevřela, klikni zde:',
  widgetOpenButton: 'Otevřít kartu s výběrem místa.',
};

const CheckoutContext = createContext<CheckoutContextType | undefined>(undefined);

export const CheckoutProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
  const [selectedShipping, setSelectedShipping] = useState<string | null>(null);
  const [shippingOptions, setShippingOptions] = useState<ShippingOption[]>(SHIPPING_OPTIONS);
  const [contactInfo, setContactInfo] = useState<ContactInfo>({});
  const [pickupPoints, setPickupPoints] = useState<PickupPoint[]>([]);
  const [selectedPickupPoint, setSelectedPickupPoint] = useState<PickupPoint | null>(null);
  const [loadingLocations, setLoadingLocations] = useState(false);

  useEffect(() => {
    let active = true;
    fetch('/api/shipping-methods', { cache: 'no-store' })
      .then(async (response) => {
        if (!response.ok) throw new Error('Dopravu se nepodařilo načíst');
        return response.json() as Promise<{ methods?: ShippingOption[] }>;
      })
      .then((data) => {
        if (!active || !Array.isArray(data.methods)) return;
        setShippingOptions(data.methods);
        setSelectedShipping((current) => {
          if (!current || data.methods?.some((method) => method.id === current)) return current;
          setSelectedPickupPoint(null);
          return null;
        });
      })
      .catch(() => undefined);
    return () => { active = false; };
  }, []);

  // Fetch pickup points from Packeta API
  const fetchPickupPoints = useCallback(async (zip: string) => {
    if (!zip) {
      setPickupPoints([]);
      return;
    }

    setLoadingLocations(true);
    try {
      const response = await fetch(
        `/api/packeta/locations?zip=${encodeURIComponent(zip)}&country=CZ`
      );

      if (response.ok) {
        const data = await response.json();
        setPickupPoints(data.locations || []);
      } else {
        setPickupPoints([]);
      }
    } catch (error) {
      setPickupPoints([]);
    } finally {
      setLoadingLocations(false);
    }
  }, []);

  // Helper function to get correct Packeta config based on shipping type
  const getPacketaConfig = useCallback((shippingType?: string) => {
    const type = shippingType || (selectedShipping ?
      PACKETA_SHIPPING_OPTIONS.find(opt => opt.id === selectedShipping)?.type
      : undefined);

    return type === 'zbox' ? PACKETA_WIDGET_ZBOX_CONFIG : PACKETA_WIDGET_PICKUP_POINT_CONFIG;
  }, [selectedShipping]);

  const value: CheckoutContextType = {
    selectedShipping,
    setSelectedShipping,
    contactInfo,
    setContactInfo,
    shippingOptions,
    pickupPoints,
    selectedPickupPoint,
    setSelectedPickupPoint,
    loadingLocations,
    fetchPickupPoints,
    packetaConfig: getPacketaConfig(),
    packetaErrorMessages: PACKETA_ERROR_MESSAGES,
    packetaUILabels: PACKETA_UI_LABELS,
    getPacketaConfig,
  };

  return (
    <CheckoutContext.Provider value={value}>{children}</CheckoutContext.Provider>
  );
};

export const useCheckout = () => {
  const context = useContext(CheckoutContext);
  if (!context) {
    throw new Error('useCheckout must be used within CheckoutProvider');
  }
  return context;
};
