import { useViewport } from '@nova-hf/ui';
import { IconType } from '@nova-hf/ui/umd/ts/src/icon-library/iconMap';
import { SecondaryColorType } from '@nova-hf/ui/umd/ts/src/styles/vars.css';
import { getFeatureFlags } from 'beta/components/feature-flags/FeatureFlags';
import { addMonths, format, subMonths } from 'date-fns';
import is from 'date-fns/locale/is';
import { get } from 'lodash';
import { NextRouter } from 'next/router';
import {
  ContractStatus,
  FiberService,
  Maybe,
  MobileInternetService,
  MobileService,
  Service,
  ServiceStatus,
  ServiceType,
  SubscriptionPeriodStatus,
  TvService,
} from 'typings/graphql';

export const isDev = process.env.NODE_ENV === 'development';

const locales = {
  'is-IS': is,
};

const featureFlags = getFeatureFlags();
const isBetaFlagActive = featureFlags['beta'];

export function serviceColorMap(type?: Maybe<ServiceType>) {
  switch (type) {
    case ServiceType.Fiber:
      return 'purple';
    case ServiceType.MobileInternet:
      return 'purple';
    case ServiceType.Mobile:
      return 'pink';
    case ServiceType.External:
      return 'viola';
    case ServiceType.CallForward:
      return 'viola';
    case ServiceType.Tv:
      return 'pink';
    default:
      return 'orange';
  }
}

export function deviceMap(type?: string) {
  switch (type) {
    case 'router':
      return 'router';
    default:
      return 'kastari';
  }
}

/**
 * Date-fns format localized to is-IS
 * @param date
 * @param formatString
 */
export function formatDate(date: Date | string, formatString: string) {
  if (typeof date === 'string' || true) {
    const dateItem = date instanceof Date ? date : new Date(date);
    if (isNaN(dateItem.getMonth()) || dateItem.toString() === 'Invalid Date') {
      return 'Dagsetning óákveðin';
    } else {
      return format(dateItem, formatString, {
        locale: locales['is-IS'],
      });
    }
  }
  return 'Engin dagsetning';
}

export function makeDate(date: string) {
  return new Date(date);
}

export function getPages(totalCount: number, perPage: number) {
  return Math.ceil(totalCount / perPage);
}

export function emailValidate(email: string) {
  return /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
    email,
  );
}

export const formatNationalId = (nationalId: string): string =>
  `${nationalId.slice(0, 6)}-${nationalId.slice(6)}`;

export function serviceIconMap(type?: Maybe<ServiceType>) {
  switch (type) {
    case ServiceType.Fiber:
      return 'internet';
    case ServiceType.MobileInternet:
      return 'mobileGlobe';
    case ServiceType.Mobile:
      return 'mobile';
    case ServiceType.External:
      return 'mobile';
    case ServiceType.CallForward:
      return 'mobileReturn';
    case ServiceType.Tv:
      return 'tv';
    default:
      return 'alltSaman';
  }
}

export function serviceSimpleNameMap(type?: Maybe<ServiceType>) {
  switch (type) {
    case ServiceType.Fiber:
      return 'Ljósleiðari';
    case ServiceType.MobileInternet:
      return 'Netið';
    case ServiceType.Mobile:
      return 'Farsími';
    case ServiceType.External:
      return 'Farsími';
    case ServiceType.CallForward:
      return 'Farsími';
    case ServiceType.Tv:
      return 'Sjónvarp';
    default:
      return 'AlltSaman';
  }
}

export function fiberServiceProviderNameMap(providerName: string) {
  switch (providerName) {
    case 'Ljosleidarinn':
      return 'Ljósleiðarinn';
    case 'Tengir':
      return 'Tengir';
    case 'Mila':
      return 'Míla';
    default:
      return '';
  }
}

type ColorIconMap = {
  color: SecondaryColorType;
  icon: IconType;
};

export function serviceStatusColorIconMap(status?: Maybe<ServiceStatus>): ColorIconMap {
  switch (status) {
    case ServiceStatus.Pending:
      return { color: 'attention', icon: 'questionMark' };
    case ServiceStatus.Active:
      return { color: 'success', icon: 'checkMark' };
    case ServiceStatus.Restricted:
      return { color: 'attention', icon: 'questionMark' };
    case ServiceStatus.Terminated:
      return { color: 'warning', icon: 'close' };
    default:
      return { color: 'warning', icon: 'questionMark' };
  }
}

export function contractStatusColorIconMap(status?: Maybe<ContractStatus>): ColorIconMap {
  switch (status) {
    case ContractStatus.Pending:
      return { color: 'attention', icon: 'questionMark' };
    case ContractStatus.Active:
      return { color: 'success', icon: 'checkMark' };
    case ContractStatus.Restricted:
      return { color: 'attention', icon: 'questionMark' };
    case ContractStatus.Canceled || ContractStatus.Abandoned || ContractStatus.Cancelled:
      return { color: 'warning', icon: 'close' };
    default:
      return { color: 'attention', icon: 'questionMark' };
  }
}

export function serviceDetailStatusMap(service?: Maybe<Service>) {
  switch (service?.type) {
    case ServiceType.Mobile:
      const mobileService: MobileService = service;
      return mobileService;
    case ServiceType.Fiber:
      const fiberService: FiberService = service;
      return fiberService;
    case ServiceType.MobileInternet:
      const mobileInternetService: MobileInternetService = service;
      return mobileInternetService;
    case ServiceType.Tv:
      const tvService: TvService = service;
      return tvService;
    default:
      return 'unknown';
  }
}

export function contractStatusColorTextMap(status?: Maybe<SubscriptionPeriodStatus>) {
  switch (status) {
    case SubscriptionPeriodStatus.Paid:
      return { color: 'success', text: 'Greitt' };
    case SubscriptionPeriodStatus.New:
      return { color: 'blue', text: 'Ógreitt' };
    case SubscriptionPeriodStatus.PaymentFailed:
      return { color: 'warning', text: 'Tókst ekki' };
    case SubscriptionPeriodStatus.Postponed:
      F;
      return { color: 'yellow', text: 'Greiðslu frestað' };
    case SubscriptionPeriodStatus.Abandoned:
      return { color: 'black100', text: 'Yfirgefið' };
    default:
      return { color: 'blue', text: 'Ógreitt' };
  }
}

export function getMonths(date: number | Date, count: number) {
  const dateInPast = subMonths(date, count);

  return Array(count + 1)
    .fill(0)
    .map((_, i) => {
      const newdate = addMonths(dateInPast, i);

      return {
        month: format(newdate, 'MMMM', {
          locale: locales['is-IS'],
        }),
        date: newdate,
      };
    });
}

export const getMonth = (date: number | Date) => {
  return format(date, 'MMMM', {
    locale: locales['is-IS'],
  });
};

type IOpts = {
  showZero?: boolean;
  showDecimals?: boolean;
  monthly?: boolean;
  unit?: string;
};

export function formatPrice(
  price: number,
  opts: IOpts = { showZero: true, showDecimals: false, monthly: false },
) {
  if (!price || price === 0) {
    return get(opts, 'showZero')
      ? `0 kr.${
          get(opts, 'monthly') ? ` ${get(opts, 'unit') ? `/ ${get(opts, 'unit')}` : '/ mán'}` : ''
        }`
      : '—';
  }

  const isMinus = price < 0;
  const decimal = opts.showDecimals ? 2 : 0;

  return `${isMinus ? '-' : ''}${price
    .toFixed(decimal)
    .replace('.', ',')
    .replace('-', '')
    .replace(/./g, (c, i, a) => (i && c !== ',' && (a.length - i) % 3 === 0 ? `.${c}` : c))} kr.${
    get(opts, 'monthly') ? ` ${get(opts, 'unit') ? `/ ${get(opts, 'unit')}` : '/ mán'}` : ''
  }`;
}

export function objectToQuery(obj: { [key: string]: string }) {
  return Object.keys(obj)
    .map((key) => {
      return `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`;
    })
    .join('&');
}

type RouteBackupLink = {
  link: string;
  backupLink: string;
};

const routeBackupLinks: RouteBackupLink[] = [
  { link: '/beta/:customerId/thjonustur', backupLink: '/:ssn/thjonustur' },
];

export function betaRoutingMaster(
  route: string,
  router: NextRouter,
  newParamValue?: string,
  checkLink?: string,
) {
  if (route && !isBetaFlagActive) {
    const routeBackup = routeBackupLinks.find((item) => item.link === checkLink);
    if (routeBackup) {
      const backupLink = replaceParamInLink(
        routeBackup.backupLink,
        /:[\w-]+/g,
        newParamValue || '',
      );
      window.location.href = backupLink ?? 'portal.nova.is';
    } else {
      router.push(route);
    }
  } else {
    router.push(route);
  }
}

function replaceParamInLink(link: string, paramPlaceholder: RegExp, paramValue: string) {
  return link.replace(new RegExp(paramPlaceholder, 'g'), paramValue);
}

export function getFirstName(fullName: string) {
  const words = fullName.split(' ');
  return words[0];
}

export const calculateNextBusinessDay = (startDate: Date, numberOfDays: number): Date => {
  let weekdaysToAdd = numberOfDays;
  const endDate = new Date(startDate);

  while (weekdaysToAdd > 0) {
    endDate.setDate(endDate.getDate() + 1);
    // (0 = Sunday, 6 = Saturday)
    const isWeekday = endDate.getDay() !== 0 && endDate.getDay() !== 6;
    if (isWeekday) {
      weekdaysToAdd--;
    }
  }

  return endDate;
};

export const getMaxLengthOfName = () => {
  const { isLarge, isXLarge } = useViewport();
  if (isXLarge) {
    return 10;
  }
  if (isLarge) {
    return 7;
  }
  return 50;
};
