import type { PlantEvent, PlantEventType } from '../../types/garden';
import type { PlantMemoryEventType } from '../../types/appTypes';
import type { SavedPlantProfile } from '../../types/plantScan';
import { formatGardenValue } from '../formatters/coreFormatters';
import { timestampFromDateCandidates } from './dateParsing';

export type MemoryCategory = 'action' | 'observation' | 'milestone' | 'progress_photo' | 'custom';

type MemoryCategoryGroup = {
  category: Exclude<MemoryCategory, 'custom'>;
  label: string;
  description: string;
  options: { value: PlantMemoryEventType; label: string }[];
};

export const memoryCategoryGroups: MemoryCategoryGroup[] = [
  {
    category: 'action',
    label: 'I did something',
    description: 'Repotted, pruned, fertilized, treated pests, watered, moved plant',
    options: [
      { value: 'repotting', label: 'Repotted' },
      { value: 'pruning', label: 'Pruned' },
      { value: 'fertilized', label: 'Fertilized' },
      { value: 'treatment', label: 'Treated pests' },
      { value: 'watered', label: 'Watered' },
      { value: 'moved_location', label: 'Moved plant' },
      { value: 'custom', label: 'Something else' },
    ],
  },
  {
    category: 'observation',
    label: 'I noticed something',
    description: 'Yellow leaves, brown tips, drooping, pest signs, slow growth',
    options: [
      { value: 'yellow_leaves', label: 'Yellow leaves' },
      { value: 'brown_tips', label: 'Brown tips' },
      { value: 'drooping', label: 'Drooping' },
      { value: 'pest_signs', label: 'Pest signs' },
      { value: 'slow_growth', label: 'Slow growth' },
      { value: 'custom', label: 'Something else' },
    ],
  },
  {
    category: 'milestone',
    label: 'Something changed',
    description: 'New leaf, flowering, fruiting, recovery, improved growth',
    options: [
      { value: 'new_leaf', label: 'New leaf' },
      { value: 'flowering', label: 'Flowering' },
      { value: 'fruiting', label: 'Fruiting' },
      { value: 'recovery', label: 'Recovery' },
      { value: 'improved_growth', label: 'Improved growth' },
      { value: 'custom', label: 'Something else' },
    ],
  },
  {
    category: 'progress_photo',
    label: 'Progress photo',
    description: 'Capture how your plant looks right now',
    options: [{ value: 'progress_photo', label: 'Progress photo' }],
  },
];

export const plantMemoryEventOptions: { value: PlantMemoryEventType; label: string }[] = (() => {
  const seen = new Set<PlantMemoryEventType>();
  return memoryCategoryGroups.flatMap(group => group.options).filter(option => {
    if (seen.has(option.value)) return false;
    seen.add(option.value);
    return true;
  });
})();

export const plantMemoryDefaultTitles: Record<PlantMemoryEventType, string> = {
  progress_photo: 'Progress photo',
  new_leaf: 'New leaf',
  flowering: 'Flowering',
  fruiting: 'Fruiting',
  repotting: 'Repotted',
  pruning: 'Pruned',
  custom: 'Plant note',
  yellow_leaves: 'Yellow leaves',
  brown_tips: 'Brown tips',
  drooping: 'Drooping',
  pest_signs: 'Pest signs',
  slow_growth: 'Slow growth',
  recovery: 'Recovery',
  improved_growth: 'Improved growth',
  fertilized: 'Fertilized',
  watered: 'Watered',
  moved_location: 'Moved location',
  treatment: 'Treated',
};

const eventCategoryByType = new Map<PlantMemoryEventType, MemoryCategory>();
for (const group of memoryCategoryGroups) {
  for (const option of group.options) {
    if (option.value !== 'custom') eventCategoryByType.set(option.value, group.category);
  }
}
eventCategoryByType.set('custom', 'custom');

export function getPlantMemoryCategory(type: PlantMemoryEventType): MemoryCategory {
  return eventCategoryByType.get(type) || 'custom';
}

export function getPlantEventTypeLabel(type: PlantEventType): string {
  for (const group of memoryCategoryGroups) {
    const option = group.options.find(candidate => candidate.value === type);
    if (option) return option.label;
  }
  return formatGardenValue(type);
}

type ExtendedSavedPlant = SavedPlantProfile & {
  events?: PlantEvent[];
  plantEvents?: PlantEvent[];
};

function isNonBlankString(value: unknown): value is string {
  return typeof value === 'string' && Boolean(value.trim());
}

function isStructurallyValidEvent(event: unknown): event is PlantEvent {
  if (!event || typeof event !== 'object') return false;
  const candidate = event as Partial<PlantEvent>;
  return isNonBlankString(candidate.id) && isNonBlankString(candidate.title) && isNonBlankString(candidate.type);
}

function mergedPlantEvents(plant?: SavedPlantProfile): PlantEvent[] {
  if (!plant) return [];
  const extended = plant as ExtendedSavedPlant;
  const current = Array.isArray(extended.events) ? extended.events : [];
  const legacy = Array.isArray(extended.plantEvents) ? extended.plantEvents : [];
  const merged: PlantEvent[] = [];
  const seenIds = new Set<string>();

  for (const event of [...current, ...legacy]) {
    if (!isStructurallyValidEvent(event)) continue;
    const id = event.id.trim();
    if (seenIds.has(id)) continue;
    seenIds.add(id);
    merged.push(event);
  }
  return merged;
}

function isDeletedEvent(event: PlantEvent): boolean {
  return event.isDeleted === true || isNonBlankString(event.deletedAt);
}

function eventTimestamp(event: PlantEvent): number {
  return timestampFromDateCandidates(event.eventDate, event.createdAt);
}

export function getSavedPlantEvents(plant?: SavedPlantProfile): PlantEvent[] {
  return mergedPlantEvents(plant)
    .filter(event => !isDeletedEvent(event))
    .sort((left, right) => eventTimestamp(right) - eventTimestamp(left));
}

export function getAllSavedPlantEvents(plant?: SavedPlantProfile): PlantEvent[] {
  return mergedPlantEvents(plant);
}
