import {
  OrderRecipientType,
  OrderRouteType,
  OrderServicesDetailType,
  OrderServiceType,
  OrdersType,
} from './types';

export const capitalize = (input: string) => {
  if (!input) {
    return;
  }
  return input.replace(/\b\w/g, function(char) {
    return char.toUpperCase();
  });
};

export const RepackData = [
  {
    packaging_type: 'Recycled Cardboard',
    products: 'DWLK1006 - Altair TV stand for TVs up to 60"(0067564578)',
    created_by: 'TST-002 Training Driver',
    date: '6/11/2024 11:26:05 AM',
    images: '',
  },
  {
    packaging_type: 'Recycled Cardboard',
    products: 'DWLK1006 - Altair TV stand for TVs up to 60"(0067564578)',
    created_by: 'TST-002 Training Driver',
    date: '6/11/2024 11:26:05 AM',
    images: '',
  },
  {
    packaging_type: 'Recycled Cardboard',
    products: 'DWLK1006 - Altair TV stand for TVs up to 60"(0067564578)',
    created_by: 'TST-002 Training Driver',
    date: '6/11/2024 11:26:05 AM',
    images: '',
  },
  {
    packaging_type: 'Recycled Cardboard',
    products: 'DWLK1006 - Altair TV stand for TVs up to 60"(0067564578)',
    created_by: 'TST-002 Training Driver',
    date: '6/11/2024 11:26:05 AM',
    images: '',
  },
];
export const DefectsData = [
  {
    action: 'Route',
    type: 'Product',
    primary_position: 'Right Side',
    secondary_position: 'Bottom Left',
    tertiary_position: 'Other',
    primary_details: 'Smashed Glass',
    secondary_details: 'Remote/Mechanism Does not Function',
    created_by: 'TST-002 Training Driver',
    date: '6/11/2024 11:26:05 AM',
    images: '',
  },
  {
    action: 'Route',
    type: 'Product',
    primary_position: 'Right Side',
    secondary_position: 'Bottom Left',
    tertiary_position: 'Other',
    primary_details: 'Smashed Glass',
    secondary_details: 'Remote/Mechanism Does not Function',
    created_by: 'TST-002 Training Driver',
    date: '6/11/2024 11:26:05 AM',
    images: '',
  },
  {
    action: 'Route',
    type: 'Product',
    primary_position: 'Right Side',
    secondary_position: 'Bottom Left',
    tertiary_position: 'Other',
    primary_details: 'Smashed Glass',
    secondary_details: 'Remote/Mechanism Does not Function',
    created_by: 'TST-002 Training Driver',
    date: '6/11/2024 11:26:05 AM',
    images: '',
  },
  {
    action: 'Route',
    type: 'Product',
    primary_position: 'Right Side',
    secondary_position: 'Bottom Left',
    tertiary_position: 'Other',
    primary_details: 'Smashed Glass',
    secondary_details: 'Remote/Mechanism Does not Function',
    created_by: 'TST-002 Training Driver',
    date: '6/11/2024 11:26:05 AM',
    images: '',
  },
];

export const getCookie = (name: string): string | null => {
  const value = `; ${document.cookie}`;
  const parts = value.split(`; ${name}=`);
  if (parts.length === 2) {
    const lastPart = parts.pop();
    if (lastPart !== undefined) {
      return lastPart.split(';').shift() || null;
    }
  }
  return null;
};

export const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
  // Allowed keys: numbers (0-9), '.', '-', '+'
  const allowedKeys = [
    '0',
    '1',
    '2',
    '3',
    '4',
    '5',
    '6',
    '7',
    '8',
    '9',
    '.',
    '-',
    '+',
    'ArrowLeft',
    'ArrowRight',
  ];

  // Allow backspace, delete, and Tab keys
  if (e.key === 'Backspace' || e.key === 'Delete' || e.key === 'Tab') {
    return;
  }

  const input = e.currentTarget;

  // Check if '+' is allowed only at the start and not duplicated
  if (e.key === '+') {
    // Prevent if '+' is not at the start or there is already a '+' in the input
    if (input.selectionStart !== 0 || input.value.includes('+')) {
      e.preventDefault();
      return;
    }
  }

  // Prevent input if key is not in allowedKeys
  if (!allowedKeys.includes(e.key)) {
    e.preventDefault();
  }
};

export const generateObj = (keys: string[], sourceObj: any) => {
  const newObj: any = {};
  keys.forEach(key => {
    if (key in sourceObj) {
      newObj[key] = sourceObj[key];
    }
  });
  return newObj;
};

export const findDifference = (obj1: any, obj2: any) => {
  // Check if obj1 or obj2 is null or undefined and return an empty object if so
  if (!obj1 || !obj2) {
    return {};
  }

  const diffKeys = Object.keys(obj1).reduce((acc: any, key) => {
    if (!(key in obj2) || obj1[key] !== obj2[key]) {
      acc.push(key);
    }
    return acc;
  }, []);

  Object.keys(obj2).forEach(key => {
    if (!(key in obj1) || obj1[key] !== obj2[key]) {
      if (!diffKeys.includes(key)) {
        diffKeys.push(key);
      }
    }
  });

  const newObj = generateObj(diffKeys, obj2);
  return newObj;
};

export const filterObject = (obj: any, keysToRemove: any[]) => {
  const filteredObj = Object.keys(obj).reduce((acc: any, key: any) => {
    if (!keysToRemove.includes(key)) {
      acc[key] = obj[key];
    }
    return acc;
  }, {});

  return filteredObj;
};

export const isObjectEmpty = (objectName: object) => {
  return Object.keys(objectName).length === 0;
};

export const compareArrays = (arr: any, newArr: any) => {
  const required_output: any = [];
  newArr.forEach((newObj: any) => {
    arr.forEach((oldObj: any) => {
      if (!newObj.hasOwnProperty('id')) {
        required_output.push(newObj);
      } else {
        const newObjFiltered = {};
        if (newObj.id === oldObj.id) {
          Object.keys(newObj).forEach((key: any) => {
            if (
              key !== 'id' &&
              oldObj.hasOwnProperty(key) &&
              newObj[key] !== oldObj[key]
            ) {
              //@ts-ignore
              newObjFiltered[key] = newObj[key];
            }
          });
          const isEmpty = isObjectEmpty(newObjFiltered);
          if (!isEmpty) {
            const clone = { ...newObjFiltered, id: newObj.id };
            required_output.push(clone);
          }
          // const newObjFiltered = { id: newObj.id };
        }
      }
    });
  });
  return required_output;
};

export const compareOrderDetailsStates = (
  oldData: OrdersType,
  newData: OrdersType
) => {
  const {
    order_recipient: oldOrderRecipient,
    order_routes: oldOrderRoutes,
    order_services_detail: oldOrderServicesDetail,
    order_services: oldOrderServices,
    ...oldRequiredData
  } = oldData;
  const {
    order_recipient: newOrderRecipient,
    order_routes: newOrderRoutes,
    order_services_detail: newOrderServicesDetail,
    order_services: newOrderServices,
    ...newRequiredData
  } = newData;

  const payload: OrdersType = findDifference(oldRequiredData, newRequiredData);

  const payloadWithId = { ...payload, id: oldData.id };

  const payloadOrderRecipient: OrderRecipientType = findDifference(
    oldOrderRecipient,
    newOrderRecipient
  );

  const payloadOrderRoutes: OrderRouteType = findDifference(
    oldOrderRoutes,
    newOrderRoutes
  );

  const payloadOrderServicesDetail: OrderServicesDetailType = findDifference(
    oldOrderServicesDetail,
    newOrderServicesDetail
  );

  // need to remove id and new_id from new order_services
  const filteredNewOrderServices = newOrderServices?.map((item: any) => {
    if (item.new_id) {
      const { id, new_id, ...newItem } = item;
      return newItem;
    } else {
      return item;
    }
  });

  const newOrderServicesWithoutId = filteredNewOrderServices.filter(
    (service: OrderServiceType) => !service.id
  );
  const newOrderServicesWithId = filteredNewOrderServices.filter(
    (service: OrderServiceType) => service.id
  );

  const payloadOrderServices: OrderServiceType[] = compareArrays(
    oldOrderServices,
    newOrderServicesWithId
  );

  const finalPayloadOrderServices = [
    ...payloadOrderServices,
    ...newOrderServicesWithoutId,
  ];

  const finalPayload = {
    ...payloadWithId,
    ...(!isObjectEmpty(payloadOrderRecipient) && {
      order_recipient: payloadOrderRecipient,
    }),
    ...(!isObjectEmpty(payloadOrderRoutes) && {
      order_routes: payloadOrderRoutes,
    }),
    ...(!isObjectEmpty(payloadOrderServicesDetail) && {
      order_services_detail: payloadOrderServicesDetail,
    }),
    ...(finalPayloadOrderServices.length > 0 && {
      order_services: finalPayloadOrderServices,
    }),
  };

  return finalPayload;
};

export const sanitizeInput = (value: string): string => {
  return value.trim() === '' ? '' : value;
};
