'use client';

import { Skeleton } from '@chakra-ui/react';
import axios from 'axios';
import Image from 'next/image';
import React, { useEffect, useState } from 'react';
import { useQuery } from 'react-query';
import toast from 'react-hot-toast';
import { useAddress } from '../stores/useAdress';
import { useQuotation } from '../stores/stateQuotation';

import currencyFormat from '@/core/utils/currencyFormat';
import { formatShipmentRange } from '../utils/functionCheckouit';
import odooApi from '@/core/api/odooApi';

function mappingItems(products) {
  return products?.map((item) => ({
    name: item?.name,
    description: `${item.code} - ${item.name}`,
    value: item.price.priceDiscount,
    weight: item.weight * 1000,
    quantity: item.quantity,
  }));
}

function reverseMappingCourier(couriersOdoo, couriers, includeInstant = false) {
  const courierMap = couriers.reduce((acc, item) => {
    const { courier_name, courier_code, courier_service_code } = item;
    const key = courier_code.toLowerCase();

    if (
      !includeInstant &&
      (['hours'].includes(item.shipment_duration_unit.toLowerCase()) ||
        item.service_type === 'same_day')
    ) {
      return acc;
    }

    if (!acc[key]) {
      acc[key] = {
        courier_name: item.courier_name,
        courier_code: courier_code,
        service_type: {},
      };
    }

    acc[key].service_type[courier_service_code] = {
      service_name: item.courier_service_name,
      duration: item.duration,
      shipment_range: item.shipment_duration_range,
      shipment_unit: item.shipment_duration_unit,
      price: item.price,
      service_type: courier_service_code,
      description: item.description,
    };

    return acc;
  }, {});

  return couriersOdoo.map((courierOdoo) => {
    const courierNameKey = courierOdoo.label.toLowerCase();
    const carrierId = courierOdoo.carrierId;

    const mappedCourier = courierMap[courierNameKey] || false;

    if (!mappedCourier) {
      return {
        ...courierOdoo,
        courier: false,
      };
    }

    return {
      ...courierOdoo,
      courier: {
        ...mappedCourier,
        courier_id_odoo: carrierId,
      },
    };
  });
}

export default function SectionExpeditionQuotation({ products }) {
  const { addressMaps, coordinate, postalCode } = useAddress();
  const [serviceOptions, setServiceOptions] = useState([]);
  const [isOpen, setIsOpen] = useState(false);
  const [onFocusSelectedCourier, setOnFocuseSelectedCourier] = useState(false);
  const [couriers, setCouriers] = useState(null);
  const [slaProducts, setSlaProducts] = useState(null);
  const [savedServiceOptions, setSavedServiceOptions] = useState([]);

  const {
    checkWeigth,
    checkoutValidation,
    setBiayaKirim,
    setUnit,
    setEtd,
    selectedCourier,
    setSelectedCourier,
    selectedService,
    setSelectedService,
    listExpedisi,
    productSla,
    setProductSla,
    setSelectedCourierId,
  } = useQuotation();

  let destination = {};
  let items = mappingItems(products);

  if (addressMaps) {
    destination = {
      origin_latitude: -6.3031123,
      origin_longitude: 106.7794934999,
      ...coordinate,
    };
  } else if (postalCode) {
    destination = {
      origin_postal_code: 14440,
      destination_postal_code: postalCode,
    };
  }

  const fetchSlaProducts = async () => {
    try {
      let productsMapped = products.map((item) => ({
        id: item.id,
        quantity: item.quantity,
      }));

      let data = {
        products: JSON.stringify(productsMapped),
      };
      const res = await odooApi('POST', `/api/v1/product/variants/sla`, data);
      setSlaProducts(res);
    } catch (error) {
      console.error('Failed to fetch SLA:', error);
    }
  };

  useEffect(() => {
    fetchSlaProducts();
  }, []);

  useEffect(() => {
    if (slaProducts) {
      let productSla = slaProducts?.slaTotal;
      if (slaProducts.slaUnit === 'jam') {
        productSla = 1;
      }
      setProductSla(productSla);
    }
  }, [slaProducts]);

  const fetchExpedition = async () => {
    const body = {
      ...destination,
      couriers:
        'gojek,grab,deliveree,lalamove,jne,tiki,ninja,lion,rara,sicepat,jnt,pos,idexpress,rpx,wahana,jdl,pos,anteraja,sap,paxel,borzo',
      items,
    };
    const response = await axios.get(`/api/biteship-service`, {
      params: { body: JSON.stringify(body) },
    });
    return response;
  };

  const { data, isLoading } = useQuery(
    ['expedition', JSON.stringify(destination), JSON.stringify(items)],
    fetchExpedition,
    {
      enabled:
        Boolean(Object.keys(destination).length) &&
        items?.length > 0 &&
        !checkWeigth &&
        onFocusSelectedCourier,
      staleTime: Infinity,
      cacheTime: Infinity,
    }
  );

  useEffect(() => {
    const instant = slaProducts?.includeInstant || false;
    if (data) {
      const couriers = reverseMappingCourier(
        listExpedisi,
        data?.data?.pricing,
        instant
      );
      setCouriers(couriers);
    }
  }, [data, slaProducts]);

  const onCourierChange = (courier) => {
    setIsOpen(false);
    setOnFocuseSelectedCourier(false);
    setSelectedService(null);
    setBiayaKirim(0);
    if (courier !== 0 && courier !== 32) {
      if (courier.courier) {
        setSelectedCourier(courier.courier.courier_code);
        setSelectedCourierId(courier.carrierId);
        setServiceOptions(Object.values(courier.courier.service_type));
      } else {
        if (
          (courier.label === 'GRAB' || courier.label === 'GOJEK') &&
          !addressMaps
        ) {
          toast.error(
            `Maaf, layanan kurir ${courier.label} tidak tersedia karena belum mengatur PinPoint.`
          );
        } else {
          toast.error('Maaf, layanan tidak tersedia. Mohon pilih ekspedisi lain.');
        }
        setServiceOptions([]);
      }
    } else {
      setSelectedCourier(courier === 32 ? 'SELF PICKUP' : null);
      setSelectedCourierId(courier);
      setServiceOptions([]);
    }
  };

  const handleSelect = (service) => {
    setSelectedService(service);
    setBiayaKirim(service?.price);
    setEtd(service?.shipment_range);
    setUnit(service?.shipment_unit);
    setIsOpen(false);
  };

  useEffect(() => {
    if (serviceOptions.length > 0) {
      setSavedServiceOptions(serviceOptions);
    }
  }, [serviceOptions]);

  return (
    <div className='px-4 py-2'>
      <div className='flex justify-between items-center'>
        <div className='font-medium'>Pilih Ekspedisi: </div>
        <div className='w-[350px]'>
          <div
            className='w-full p-2 border rounded-lg bg-white cursor-pointer'
            onClick={() => setOnFocuseSelectedCourier(!onFocusSelectedCourier)}
          >
            {selectedCourier ? (
              <div className='flex justify-between'>
                <span>{selectedCourier}</span>
              </div>
            ) : (
              <span className='text-gray-500'>Pilih Expedisi</span>
            )}
          </div>
          {onFocusSelectedCourier && (
            <div className='absolute bg-white border rounded-lg mt-1 shadow-lg z-10 max-h-[200px] overflow-y-auto w-[350px]'>
              {!isLoading ? (
                <>
                  <div
                    key={32}
                    onClick={() => onCourierChange(32)}
                    className='p-2 hover:bg-gray-100 cursor-pointer'
                  >
                    <p className='font-semibold'>SELF PICKUP</p>
                  </div>
                  {couriers?.map((courier) => (
                    <div
                      key={courier?.courier?.courier_code}
                      onClick={() => onCourierChange(courier)}
                      className='flex justify-between p-2 items-center hover:bg-gray-100 cursor-pointer'
                    >
                      <p className='font-semibold'>{courier?.label}</p>
                      <Image
                        src={courier?.logo}
                        alt={courier?.courier?.courier_name}
                        width={50}
                        height={50}
                      />
                    </div>
                  ))}
                </>
              ) : (
                <>
                  <Skeleton height={40} />
                  <Skeleton height={40} />
                </>
              )}
            </div>
          )}
          {checkoutValidation && (
            <span className='text-sm text-red-500'>
              *Silahkan pilih ekspedisi
            </span>
          )}
        </div>
      </div>

      {checkWeigth && (
        <p className='mt-4 text-gray-600'>
          Mohon maaf, pengiriman hanya tersedia untuk self pickup karena ada barang
          yang belum memiliki berat. Silakan hubungi admin via{' '}
          <a
            className='text-blue-600 underline'
            href='https://api.whatsapp.com/send?phone=6281717181922'
            target='_blank'
            rel='noopener noreferrer'
          >
            tautan ini
          </a>
        </p>
      )}

      {(serviceOptions.length > 0 || selectedService) &&
        selectedCourier &&
        selectedCourier !== 32 &&
        selectedCourier !== 0 && (
          <div className='mt-4 flex justify-between'>
            <div className='font-medium mb-2'>Tipe Layanan Ekspedisi:</div>
            <div className='relative w-[350px]'>
              <div
                className='p-2 border rounded-lg bg-white cursor-pointer'
                onClick={() => setIsOpen(!isOpen)}
              >
                {selectedService ? (
                  <div className='flex justify-between'>
                    <span>{selectedService.service_name}</span>
                    <span>
                      {currencyFormat(
                        Math.round((selectedService?.price * 1.1) / 1000) * 1000
                      )}
                    </span>
                  </div>
                ) : (
                  <span className='text-gray-500'>Pilih layanan pengiriman</span>
                )}
              </div>
              {isOpen && (
                <div className='absolute bg-white border rounded-lg mt-1 shadow-lg z-10 w-full'>
                  {serviceOptions.map((service) => (
                    <div
                      key={service.service_type}
                      onClick={() => handleSelect(service)}
                      className='flex justify-between p-2 items-center hover:bg-gray-100 cursor-pointer'
                    >
                      <div>
                        <p className='font-semibold'>{service.service_name}</p>
                        <p className='text-sm text-gray-600'>
                          {formatShipmentRange(
                            service.shipment_range,
                            service.shipment_unit,
                            productSla
                          )}
                        </p>
                      </div>
                      <span>
                        {currencyFormat(
                          Math.round((service?.price * 1.1) / 1000) * 1000
                        )}
                      </span>
                    </div>
                  ))}
                </div>
              )}
            </div>
          </div>
        )}
    </div>
  );
}
