import type { ImageSourcePropType } from 'react-native';

export type CareTaskIconType =
  | 'water'
  | 'inspect'
  | 'prune'
  | 'rotate'
  | 'mist'
  | 'repot'
  | 'fertilize'
  | 'treat'
  | 'harvest'
  | 'propagate'
  | 'check_growth'
  | 'reassess';

export const CARE_TASK_ICONS: Record<CareTaskIconType, ImageSourcePropType> = {
  water: require('../assets/care-icons/water.png'),
  inspect: require('../assets/care-icons/inspect.png'),
  prune: require('../assets/care-icons/prune.png'),
  rotate: require('../assets/care-icons/rotate.png'),
  mist: require('../assets/care-icons/mist.png'),
  repot: require('../assets/care-icons/repot.png'),
  fertilize: require('../assets/care-icons/fertilize.png'),
  treat: require('../assets/care-icons/treat.png'),
  harvest: require('../assets/care-icons/harvest.png'),
  propagate: require('../assets/care-icons/propagate.png'),
  check_growth: require('../assets/care-icons/check_growth.png'),
  reassess: require('../assets/care-icons/reassess.png'),
};

type CareTaskIconKeywordGroup = {
  readonly iconType: CareTaskIconType;
  readonly keywords: readonly string[];
};

type CareTaskIconMatcher = {
  readonly iconType: CareTaskIconType;
  readonly needle: string;
  readonly keywordLength: number;
  readonly precedence: number;
};

const CARE_TASK_ICON_KEYWORDS = [
  { iconType: 'water', keywords: ['water', 'watering'] },
  {
    iconType: 'inspect',
    keywords: [
      'inspect',
      'inspection',
      'pest',
      'pests',
      'check leaf',
      'check leaves',
      'check rose',
      'check roses',
      'check golden',
      'care check',
    ],
  },
  {
    iconType: 'prune',
    keywords: [
      'prune',
      'pruning',
      'trim',
      'trimming',
      'deadhead',
      'deadheading',
      'dead head',
      'dead heading',
    ],
  },
  { iconType: 'rotate', keywords: ['rotate', 'rotating', 'rotation', 'turn', 'turning'] },
  { iconType: 'mist', keywords: ['mist', 'misting', 'spray', 'spraying'] },
  {
    iconType: 'repot',
    keywords: ['repot', 'repotting', 're pot', 're potting', 'pot up', 'potting'],
  },
  {
    iconType: 'fertilize',
    keywords: ['fertilize', 'fertilizing', 'fertilizer', 'fertiliser', 'feed', 'feeding'],
  },
  {
    iconType: 'treat',
    keywords: [
      'treat',
      'treating',
      'treatment',
      'treatments',
      'pest treatment',
      'pest treatments',
      'neem oil',
      'neem',
      'oil',
    ],
  },
  { iconType: 'harvest', keywords: ['harvest', 'harvesting', 'pick', 'picking'] },
  {
    iconType: 'propagate',
    keywords: ['propagate', 'propagating', 'propagation', 'cutting', 'cuttings'],
  },
  { iconType: 'check_growth', keywords: ['check growth', 'growth check', 'growth'] },
  {
    iconType: 'reassess',
    keywords: ['reassess', 'reassessment', 're assess', 're assessment', 'review', 'recheck'],
  },
] as const satisfies readonly CareTaskIconKeywordGroup[];

const CARE_TASK_ICON_MATCHERS: readonly CareTaskIconMatcher[] = CARE_TASK_ICON_KEYWORDS.flatMap(
  ({ iconType, keywords }, precedence) =>
    keywords.map(keyword => ({
      iconType,
      needle: ` ${keyword} `,
      keywordLength: keyword.length,
      precedence,
    })),
);

function normalizeTaskType(taskType: string): string {
  return taskType
    .trim()
    .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, ' ')
    .replace(/\s+/g, ' ')
    .trim();
}

function findCareTaskIconType(searchableTaskType: string): CareTaskIconType | undefined {
  let bestMatch: CareTaskIconMatcher | undefined;
  let bestIndex = Number.POSITIVE_INFINITY;

  for (const matcher of CARE_TASK_ICON_MATCHERS) {
    const matchIndex = searchableTaskType.indexOf(matcher.needle);
    if (matchIndex < 0) {
      continue;
    }

    const isEarlier = matchIndex < bestIndex;
    const isMoreSpecificAtSamePosition =
      matchIndex === bestIndex &&
      (bestMatch === undefined ||
        matcher.keywordLength > bestMatch.keywordLength ||
        (matcher.keywordLength === bestMatch.keywordLength &&
          matcher.precedence < bestMatch.precedence));

    if (isEarlier || isMoreSpecificAtSamePosition) {
      bestMatch = matcher;
      bestIndex = matchIndex;
    }
  }

  return bestMatch?.iconType;
}

export function getCareTaskIconSource(
  taskType: string,
  fallback: ImageSourcePropType,
): ImageSourcePropType {
  if (typeof taskType !== 'string') {
    return fallback;
  }

  const normalizedTaskType = normalizeTaskType(taskType);
  if (!normalizedTaskType) {
    return fallback;
  }

  const iconType = findCareTaskIconType(` ${normalizedTaskType} `);
  return iconType ? CARE_TASK_ICONS[iconType] : fallback;
}
