import moment from 'moment';
import { DefaultRoles } from './constant';
import dayjs from 'dayjs';
import { Role } from '@/app/role/interface';

export function removeEmptyKeys(obj: Record<string, unknown>): object {
  // Filter out key-value pairs where the value is null or undefined
  const filteredObj = Object.fromEntries(
    Object.entries(obj).filter(
      ([_, value]) => value !== null && value !== undefined && value !== ''
    )
  );
  return filteredObj;
}

export const hasPermission = (user: any, requiredPermission: string): boolean => {
  if (!user) {
    return false;
  }
  if (user?.role?.id == DefaultRoles?.super_admin?.id.toString()) {
    return true;
  }
  return user?.permissions?.includes(requiredPermission);
};
export const formatDate = (date: Date, format = 'YYYY-MM-DD') => {
  if (!date) {
    return ''; // Handle cases where the date is not provided
  }

  // Check if the provided date is already a valid moment object
  const momentDate = moment.isMoment(date) ? date : moment(date);

  return momentDate.isValid() ? momentDate.format(format) : '';
};

export const displayDate = (date: any) => {
  if (!date) {
    return ''; // Handle cases where the date is not provided
  }

  // Check if the provided date is already a valid moment object
  const momentDate = moment.isMoment(date) ? date : moment(date);

  return momentDate.isValid() ? momentDate.format('DD MMM, YYYY') : '';
};

export const displayTime = (date: string) => {
  if (!date) {
    return ''; // Handle cases where the date is not provided
  }

  // Check if the provided date is already a valid moment object
  const momentDate = moment.isMoment(date) ? date : moment(date);

  return momentDate.isValid() ? momentDate.format('hh:mm A') : '';
};

export const formatTime = (time: string, format = 'HH:mm') => {
  if (!time) {
    return ''; // Handle cases where the time is not provided
  }

  const momentTime = moment(time, 'HH:mm'); // Assuming time is in 'HH:mm' format
  return momentTime.isValid() ? momentTime.format(format) : '';
};

export const convertToShorthand = (number: number): string => {
  if (isNaN(number)) {
    return '0';
  }
  const absNumber = Math.abs(number);
  const crore = 1e7;
  const lakh = 1e5;
  const thousand = 1e3;
  if (absNumber >= crore) {
    const result = (number / crore).toFixed(2);
    const integerPart = parseInt(result);
    const decimalPart = parseInt((result.split('.')[1] || '0'));
    if (decimalPart === 0) {
      return integerPart + ' CR';
    } else {
      return result + ' CR';
    }
  } else if (absNumber >= lakh) {
    const result = (number / lakh).toFixed(2);
    const integerPart = parseInt(result);
    const decimalPart = parseInt((result.split('.')[1] || '0'));
    if (decimalPart === 0) {
      return integerPart + ' Lakh';
    } else {
      return result + ' Lakh';
    }
  } else if (absNumber >= thousand) {
    const result = (number / thousand).toFixed(2);
    const integerPart = parseInt(result);
    const decimalPart = parseInt((result.split('.')[1] || '0'));
    if (decimalPart === 0) {
      return integerPart + ' K';
    } else {
      return result + ' K';
    }
  } else {
    return Number(number).toFixed(2);
  }
};

export const rangeAfter = (start: number, end: number) => {
  const result = [];
  for (let i = start; i <= end; i++) {
    result.push(i);
  }
  return result;
};

export const minRangeAfter = (start: number, end: number) => {
  return rangeAfter(start, end);
};

export const disabledAfterDateTime = (currentDate: dayjs.Dayjs | null) => {
  const currentDateTime = dayjs();
  return {
    disabledHours: () => {
      if (currentDate && currentDate.isSame(currentDateTime, 'day')) {
        return rangeAfter(currentDateTime.hour() + 1, 23);
      }
      return [];
    },
    disabledMinutes: (selectedHour: number) => {
      if (currentDate && currentDate.isSame(currentDateTime, 'day')) {
        if (selectedHour > currentDateTime.hour()) {
          return rangeAfter(0, 59);
        } else if (selectedHour === currentDateTime.hour()) {
          return minRangeAfter(currentDateTime.minute() + 1, 59);
        }
      }
      return [];
    },
    disabledSeconds: (selectedHour: number, selectedMinute: number) => {
      if (currentDate && currentDate.isSame(currentDateTime, 'day')) {
        if (
          selectedHour > currentDateTime.hour() ||
                    (selectedHour === currentDateTime.hour() &&
                        selectedMinute > currentDateTime.minute())
        ) {
          return rangeAfter(0, 59);
        } else if (
          selectedHour === currentDateTime.hour() &&
                    selectedMinute === currentDateTime.minute()
        ) {
          return minRangeAfter(currentDateTime.second() + 1, 59);
        }
      }
      return [];
    },
  };
};

export const createSlug = (string: string) =>{
  return string.toLowerCase().replace(/[^\w\s-]/g, '').trim().replace(/[\s_-]+/g, '-');
};

export const getManagerAndSubordinates = (roleId: number | string, rolesList: Role[]) => {
  const role = rolesList.find(role => role.id === Number(roleId));

  if (!role) {
    return {
      manager_role_id: null,
      manager_of_role_ids: [],
    };
  }

  return {
    manager_role_id: role.manager_role_id ?? null,
    manager_of_role_ids: role.subordinate_role_id
      ? role.subordinate_role_id.split(',').map(id => Number(id.trim()))
      : [],
  };
};

// return all the labels with ids
export const getRoleIdMap = (rolesList: { name: string; id: number }[]) => {
  return rolesList.reduce((acc: Record<string, number>, role) => {
    acc[role.name] = role.id;
    return acc;
  }, {});
};

export const transformLabel = (text: string, method: string): string =>  {
  if (method === 'convert') {
    return text.trim().toLowerCase().replace(/\s+/g, '_');
  } else if (method === 'revert') {
    return text
      .split('_')
      .map(word => word.charAt(0).toUpperCase() + word.slice(1))
      .join(' ');
  } else {
    throw new Error(`Unsupported method: ${method}`);
  }
}

export const mapSelectedUsersToIds = (
  selectedUsers: { id: number;
    role: string;
    role_id: number; }[]
): Record<string, number> => {
  return selectedUsers.reduce((acc, user) => {
    if (user?.role) {
      acc[`${user.role}_id`] = user.id;
    }
    return acc;
  }, {} as Record<string, number>);
};

export const parseProjectIds = (value?: string | null) => {
  if (!value) return undefined;
  return value.split(',').map((id) => Number(id.trim()));
};
