import { Photo, PhotoDb } from '..';
import {
  AI_TEXT_AUTO_GENERATED_FIELDS,
  AI_CONTENT_GENERATION_ENABLED,
  COLOR_SORT_ENABLED,
} from '@/app/config';
import { AiAutoGeneratedField } from '../ai';
import { capitalize } from '@/utility/string';

export interface PhotoUpdateStatus {
  isOutdated: boolean
  isMissingAiTextFields: AiAutoGeneratedField[]
  isMissingColorData: boolean
}

export const UPDATE_QUERY_LIMIT = 1000;

// UTC 2025-09-7 23:55:00
export const OUTDATED_UPDATE_AT_THRESHOLD =
  new Date(Date.UTC(2025, 8, 7, 23, 55, 0));

const isPhotoOutdated = (photo: PhotoDb) =>
  photo.updatedAt < OUTDATED_UPDATE_AT_THRESHOLD;

const getMissingAiTextFields = ({
  title,
  caption,
  tags,
  semanticDescription,
}: PhotoDb | Photo): AiAutoGeneratedField[] =>
  AI_CONTENT_GENERATION_ENABLED
    ? AI_TEXT_AUTO_GENERATED_FIELDS.reduce((fields, field) => {
      switch (field) {
        case 'title':
          return !title ? [...fields, 'title'] : fields;
        case 'caption':
          return !caption ? [...fields, 'caption'] : fields;
        case 'tags':
          return (tags ?? []).length === 0 ? [...fields, 'tags'] : fields;
        case 'semantic':
          return !semanticDescription ? [...fields, 'semantic'] : fields;
      }
    }, [] as AiAutoGeneratedField[])
    : [];

export const isPhotoMissingColorData = (photo: PhotoDb) =>
  // "== null" intentional check for undefined or null
  COLOR_SORT_ENABLED && (
    photo.colorData == null ||
    photo.colorSort == null
  );

export const generatePhotoUpdateStatus = (
  photo: PhotoDb,
): PhotoUpdateStatus => ({
  isOutdated: isPhotoOutdated(photo),
  isMissingAiTextFields: getMissingAiTextFields(photo),
  isMissingColorData: isPhotoMissingColorData(photo),
});

export const photoNeedsToBeUpdated = (photo: Photo) =>
  photo.updateStatus?.isOutdated ||
  (photo.updateStatus?.isMissingAiTextFields ?? []).length > 0 ||
  photo.updateStatus?.isMissingColorData;

export const isPhotoOnlyMissingColorData = (photo?: Photo) =>
  photo?.updateStatus?.isMissingColorData &&
  !photo?.updateStatus.isOutdated &&
  (photo?.updateStatus.isMissingAiTextFields.length ?? 0) === 0;

export const getPhotoUpdateStatusText = (photo: Photo) => {
  const {
    isOutdated,
    isMissingAiTextFields = [],
    isMissingColorData,
  } = photo.updateStatus ?? {};

  const cta = 'sync to update';
  if (isOutdated) {
    return `Outdated data—${cta}`;
  } else {
    const textParts: string[] = [];
    if (isMissingAiTextFields.length > 0) {
      const missingFields = isMissingAiTextFields
        .map(field => field.toLocaleUpperCase())
        .join(', ');
      textParts.push(`AI text (${missingFields})`);
    }
    if (isMissingColorData) {
      textParts.push('color data');
    }
    if (textParts.length > 0) {
      return `Missing ${textParts.join(', ')}—${cta}`;
    } else {
      return capitalize(cta);
    }
  }
};

export const getPhotosUpdateStatusCounts = (photos: Photo[]) => {
  const photosCountOutdated = photos.filter(
    photo => photo.updateStatus?.isOutdated,
  ).length;
  const photosCountMissingAiText = photos.filter(
    photo => (photo.updateStatus?.isMissingAiTextFields ?? []).length > 0,
  ).length;
  const photosCountMissingColorData = photos.filter(
    photo => photo.updateStatus?.isMissingColorData,
  ).length;

  return {
    photosCountOutdated,
    photosCountMissingAiText,
    photosCountMissingColorData,
  };
};

export const getPhotosUpdateStatusText = (photos: Photo[]) => {
  const statusText = [] as string[];

  const {
    photosCountOutdated,
    photosCountMissingAiText,
    photosCountMissingColorData,
  } = getPhotosUpdateStatusCounts(photos);

  if (photosCountOutdated > 0) {
    statusText.push(`${photosCountOutdated} outdated`);
  }
  if (photosCountMissingAiText > 0) {
    statusText.push(`${photosCountMissingAiText} missing AI text`);
  }
  if (photosCountMissingColorData > 0) {
    statusText.push(`${photosCountMissingColorData} missing color data`);
  }

  return statusText.join(', ');
};
