export const LONG_TEXT_KEYS = {
  containerType: "container_type",
  tag: "tag",
  title: "title",
  content: "content",
  contentSummary: "content_summary",
  guideConclusion: "guide_conclusion",
  keyFacts: "key_facts",
  sceneImage: "scene_image",
  checklistOrSteps: "checklist_or_steps",
  bestTimeOrPeople: "best_time_or_people",
  avoidPitfalls: "avoid_pitfalls",
  nextSuggestion: "next_suggestion",
  poiDefinition: "poi_definition",
  keyHighlights: "key_highlights",
  heroImage: "hero_image",
  backgroundStory: "background_story",
  bestTime: "best_time",
  visitSuggestion: "visit_suggestion",
  routeSummary: "route_summary",
  routeMeta: "route_meta",
  routeSteps: "route_steps",
  onsiteClues: "onsite_clues",
  realtimeNotice: "realtime_notice",
  routeWarning: "route_warning",
  arrivalNextStep: "arrival_next_step",
  photoConclusion: "photo_conclusion",
  photoSpots: "photo_spots",
  compositionTips: "composition_tips",
  phoneSettings: "phone_settings",
  lightReminder: "light_reminder",
  sampleImage: "sample_image",
  components: "components",
  checklist: "checklist",
  suggest: "suggest",
  commodity: "commodity",
  actionZone: "action_zone",
};

export const LONG_TEXT_FIELD_CONFIG = [
  { key: LONG_TEXT_KEYS.containerType },
  { key: LONG_TEXT_KEYS.tag },
  { key: LONG_TEXT_KEYS.title },
  { key: LONG_TEXT_KEYS.content },
  { key: LONG_TEXT_KEYS.contentSummary },
  { key: LONG_TEXT_KEYS.guideConclusion },
  { key: LONG_TEXT_KEYS.keyFacts },
  { key: LONG_TEXT_KEYS.sceneImage },
  { key: LONG_TEXT_KEYS.checklistOrSteps },
  { key: LONG_TEXT_KEYS.bestTimeOrPeople },
  { key: LONG_TEXT_KEYS.avoidPitfalls },
  { key: LONG_TEXT_KEYS.nextSuggestion },
  { key: LONG_TEXT_KEYS.poiDefinition },
  { key: LONG_TEXT_KEYS.keyHighlights },
  { key: LONG_TEXT_KEYS.heroImage },
  { key: LONG_TEXT_KEYS.backgroundStory },
  { key: LONG_TEXT_KEYS.bestTime },
  { key: LONG_TEXT_KEYS.visitSuggestion },
  { key: LONG_TEXT_KEYS.routeSummary },
  { key: LONG_TEXT_KEYS.routeMeta },
  { key: LONG_TEXT_KEYS.routeSteps },
  { key: LONG_TEXT_KEYS.onsiteClues },
  { key: LONG_TEXT_KEYS.realtimeNotice },
  { key: LONG_TEXT_KEYS.routeWarning },
  { key: LONG_TEXT_KEYS.arrivalNextStep },
  { key: LONG_TEXT_KEYS.photoConclusion },
  { key: LONG_TEXT_KEYS.photoSpots },
  { key: LONG_TEXT_KEYS.compositionTips },
  { key: LONG_TEXT_KEYS.phoneSettings },
  { key: LONG_TEXT_KEYS.lightReminder },
  { key: LONG_TEXT_KEYS.sampleImage },
  { key: LONG_TEXT_KEYS.components },
  { key: LONG_TEXT_KEYS.checklist },
  { key: LONG_TEXT_KEYS.suggest },
  { key: LONG_TEXT_KEYS.commodity },
  { key: LONG_TEXT_KEYS.actionZone },
];

export const LONG_TEXT_PREVIEW_KEYS = [
  LONG_TEXT_KEYS.contentSummary,
  LONG_TEXT_KEYS.title,
  LONG_TEXT_KEYS.tag,
];

const CONFIGURED_KEYS = LONG_TEXT_FIELD_CONFIG.map((item) => item.key);

type LongTextKey = string;

export interface LongTextData {
  values: Record<LongTextKey, string>;
  parsedValues: Record<LongTextKey, unknown>;
}

export interface LongTextChunk {
  contentKey?: string | number | null;
  contentValue?: unknown;
}

interface ParseResult {
  ok: boolean;
  value: unknown;
}

export interface LongTextSection {
  contentKey: string;
  contentValue: string;
  parsedValue: unknown;
}

export const createLongTextData = (): LongTextData => ({
  values: {},
  parsedValues: {},
});

const toText = (value: unknown): string => {
  if (value === undefined || value === null) return "";
  return typeof value === "string" ? value : String(value);
};

const shouldParseJSON = (raw: unknown): raw is string => {
  if (!raw || typeof raw !== "string") return false;
  return /^[\s]*[\[{]/.test(raw);
};

const tryParseJSON = (raw: string): ParseResult => {
  if (!shouldParseJSON(raw)) {
    return { ok: false, value: null };
  }
  try {
    return { ok: true, value: JSON.parse(raw) };
  } catch (e) {
    return { ok: false, value: null };
  }
};

export const appendLongTextChunk = (
  target: LongTextData | null | undefined,
  chunk: LongTextChunk = {},
): LongTextData | null | undefined => {
  if (!target || !chunk.contentKey) return target;

  const key = String(chunk.contentKey);
  const value = toText(chunk.contentValue);

  if (!target.values) target.values = {};
  if (!target.parsedValues) target.parsedValues = {};

  target.values[key] = (target.values[key] || "") + value;

  const parsed = tryParseJSON(target.values[key]);
  if (parsed.ok) {
    target.parsedValues[key] = parsed.value;
  } else {
    delete target.parsedValues[key];
  }

  return target;
};

export const getLongTextValue = (
  data: LongTextData | null | undefined,
  key: string,
): string => {
  if (!data || !data.values || !key) return "";
  return data.values[key] || "";
};

export const getLongTextParsedValue = <T = unknown>(
  data: LongTextData | null | undefined,
  key: string,
  fallback?: T,
): T | unknown => {
  if (!data || !data.parsedValues || !key) return fallback;
  return Object.prototype.hasOwnProperty.call(data.parsedValues, key)
    ? data.parsedValues[key]
    : fallback;
};

export const getLongTextPreviewText = (
  data: LongTextData | null | undefined,
  keys: string[] = LONG_TEXT_PREVIEW_KEYS,
): string => {
  for (const key of keys) {
    const value = getLongTextValue(data, key);
    if (value) return value;
  }
  return "";
};

export const hasLongTextExtraSections = (
  data: LongTextData | null | undefined,
  previewKeys: string[] = LONG_TEXT_PREVIEW_KEYS,
): boolean => {
  if (!data || !data.values) return false;
  return Object.keys(data.values).some((key) => !previewKeys.includes(key));
};

export const getLongTextSections = (
  data: LongTextData | null | undefined,
): LongTextSection[] => {
  if (!data || !data.values) return [];

  const extraKeys = Object.keys(data.values).filter(
    (key) => !CONFIGURED_KEYS.includes(key),
  );

  return [...CONFIGURED_KEYS, ...extraKeys]
    .filter((key) => Object.prototype.hasOwnProperty.call(data.values, key))
    .map((key) => ({
      contentKey: key,
      contentValue: getLongTextValue(data, key),
      parsedValue: getLongTextParsedValue(data, key, null),
    }));
};
