import type { OutdoorSunTiming, RoomProfile, SpaceType } from '../../types/garden';
import type { SpaceSummary } from '../../types/appTypes';
import { outdoorSpaceTypes } from '../../types/appTypes';
import { formatAmbientArtificialLight } from './climateFormatters';
import { formatGardenValue, formatHumidityProfile, formatLightProfile } from './coreFormatters';

function uniqueValues<T>(values?: T[]): T[] {
  return Array.isArray(values) ? [...new Set(values)] : [];
}

export function isOutdoorSpaceType(spaceType?: SpaceType | null): boolean {
  return Boolean(spaceType && outdoorSpaceTypes.has(spaceType));
}

export function isIndoorSpaceType(spaceType?: SpaceType | null): boolean {
  return Boolean(spaceType && !outdoorSpaceTypes.has(spaceType));
}

export function formatOutdoorSunTimings(values?: OutdoorSunTiming[]): string {
  const unique = uniqueValues(values).filter(Boolean);
  if (!unique.length) return 'Not set';

  const meaningful = unique.filter(value => value !== ('unsure' as typeof value));
  if (meaningful.length) return meaningful.map(formatGardenValue).join(' + ');
  return 'Unsure';
}

/**
 * Format multiple window directions as "East + South window". Conflicting
 * legacy values are resolved in favor of real directions, then `none`, then
 * `unsure`.
 */
export function formatWindowDirections(directions?: RoomProfile['windowDirections']): string {
  const unique = uniqueValues(directions).filter(Boolean);
  if (!unique.length) return 'Not set';

  const realDirections = unique.filter(direction => direction !== 'none' && direction !== 'unsure');
  if (realDirections.length) return `${realDirections.map(formatGardenValue).join(' + ')} window`;
  if (unique.includes('none')) return 'No window';
  if (unique.includes('unsure')) return 'Unsure';
  return 'Not set';
}

export function formatSpaceLight(room: RoomProfile): string {
  if (isOutdoorSpaceType(room.spaceType)) {
    const timing = formatOutdoorSunTimings(room.outdoorSunTimings);
    const hasTiming = timing !== 'Not set' && timing !== 'Unsure';
    const qualityValue = typeof room.outdoorLightQuality === 'string' ? room.outdoorLightQuality.trim() : '';
    const quality = qualityValue && qualityValue !== 'unsure' ? formatGardenValue(qualityValue) : '';
    if (hasTiming && quality) return `${timing} · ${quality}`;
    return (hasTiming ? timing : '') || quality || 'Outdoor light not set';
  }

  if (!isIndoorSpaceType(room.spaceType)) return 'Light not set';
  if (!room.lightProfile || (room.lightProfile as string) === 'unsure') return 'Indoor light not set';
  const light = formatLightProfile(room.lightProfile);
  return light === 'Not set' ? 'Indoor light not set' : light;
}

export function formatSpaceStatusSummary(summary: SpaceSummary): string {
  const rawCount = summary.needsCareCount;
  const count = Number.isFinite(rawCount) ? Math.max(0, Math.trunc(rawCount)) : 0;
  if (count === 1) return '1 plant needs attention';
  if (count > 1) return `${count} plants need attention`;
  return 'All good';
}

export function formatSetupSpaceEnvironment(room: RoomProfile): string {
  const outdoor = isOutdoorSpaceType(room.spaceType);
  const placeType = outdoor ? 'Outdoor' : 'Indoor';
  const light = outdoor ? formatSpaceLight(room) : formatWindowDirections(room.windowDirections);
  const humidity = formatHumidityProfile(room.humidityProfile).toLowerCase();
  const ambientLight = room.usesAmbientArtificialLight === true
    ? ` - Ambient artificial light: ${formatAmbientArtificialLight(room)}`
    : '';
  return `${placeType} - ${light} - Humidity ${humidity}${ambientLight}`;
}

export function cleanSpaceNotesForDisplay(notes?: string): string | undefined {
  if (typeof notes !== 'string') return undefined;
  return notes
    .replace(/\s*Former space type:\s*(Garden Bed|Raised Bed|Plant Shelf)\.?/gi, '')
    .replace(/[ \t]{2,}/g, ' ')
    .trim();
}
