import { isValid, parseISO } from 'date-fns';

import type { PillsProps } from '@material-hu/components/design-system/Pills';
import { formatToTime } from 'src/utils/date';

import type { BreakdownReason } from 'src/types/prode';
import { ReactNativeWebViewType } from 'src/types/login';

import { SPORTS_POOL_PATHS } from './routes';

export const postWebViewRouteChange = (route: string) => {
  (window as ReactNativeWebViewType).ReactNativeWebView?.postMessage(
    JSON.stringify({ type: 'ROUTE_CHANGE', route }),
  );
};

export const postWebViewReady = () => {
  (window as ReactNativeWebViewType).ReactNativeWebView?.postMessage('READY');
};

export const SPORTS_POOL_MOBILE_PREFIX = `/${SPORTS_POOL_PATHS.MOBILE_ROOT}/`;

export const isSportsPoolMobilePath = (pathname: string) =>
  pathname.startsWith(SPORTS_POOL_MOBILE_PREFIX);

export const getSportsPoolMobileBase = (pathname: string) => {
  if (!isSportsPoolMobilePath(pathname)) return null;
  const parts = pathname.split('/');
  return parts[2] ? `/${parts[1]}/${parts[2]}` : null;
};

export type TabValue = 'predictions' | 'ranking' | 'rules';

const PATH_TAB_MAP: [string, TabValue][] = [
  ['/ranking', 'ranking'],
  ['/rules', 'rules'],
];

export const getTabFromPath = (pathname: string): TabValue =>
  PATH_TAB_MAP.find(([suffix]) => pathname.endsWith(suffix))?.[1] ??
  'predictions';

export const getScorePointsPillType = (
  score: number,
): NonNullable<PillsProps['type']> => {
  if (score > 0) return 'success';
  return 'neutral';
};

export const formatScorePoints = (score: number): string => {
  if (score > 0) return `+${score}`;
  return `${score}`;
};

export const formatBreakdownPoints = (
  points: number,
  reason: BreakdownReason,
): string => {
  const sign = reason === 'CORRECT_QUALIFIER' ? '+' : '';
  return `${sign}${points}`;
};

function parseMatchUtcDate(matchDate: string, matchTime: string): Date | null {
  const utcDate = parseISO(`${matchDate}T${matchTime}:00Z`);
  return isValid(utcDate) ? utcDate : null;
}

export function getMatchLocalTime(
  matchDate: string,
  matchTime: string | null,
): string {
  if (!matchTime) return '--:--';
  const utcDate = parseMatchUtcDate(matchDate, matchTime);
  return utcDate ? formatToTime(utcDate) : matchTime;
}

export function getMatchLocalDate(
  matchDate: string,
  matchTime: string | null,
): string {
  if (!matchTime) return matchDate;
  const utcDate = parseMatchUtcDate(matchDate, matchTime);
  if (!utcDate) return matchDate;
  const year = utcDate.getFullYear();
  const month = String(utcDate.getMonth() + 1).padStart(2, '0');
  const day = String(utcDate.getDate()).padStart(2, '0');
  return `${year}-${month}-${day}`;
}

/**
 * Converts an ISO 3166-1 alpha-2 country code to a flag emoji.
 * Works by converting each letter to its Regional Indicator Symbol.
 * e.g., "AR" → 🇦🇷, "BR" → 🇧🇷, "FR" → 🇫🇷
 *
 * @param countryCode ISO 3166-1 alpha-2 country code (e.g. "AR", "US")
 * @returns Flag emoji string, or null if the input is invalid
 */
export function countryCodeToFlagEmoji(
  countryCode: string | null | undefined,
): string | null {
  if (!countryCode || countryCode.length !== 2) return null;

  const code = countryCode.toUpperCase();
  const OFFSET = 0x1f1e6 - 'A'.charCodeAt(0);

  const first = code.charCodeAt(0);
  const second = code.charCodeAt(1);

  // Validate that both characters are A-Z
  if (first < 65 || first > 90 || second < 65 || second > 90) return null;

  return (
    String.fromCodePoint(first + OFFSET) + String.fromCodePoint(second + OFFSET)
  );
}
