import { ParamsIds, ParamsSlug, Slug } from '@ts/types/app';
import {
  Article,
  ArticlePreview,
  RawArticle,
  RawArticlePreview,
} from '@ts/types/articles';
import { Comment, RawComment } from '@ts/types/comments';
import {
  RawTopic,
  RawTopicPreview,
  RawThematic,
  Topic,
  TopicPreview,
  Thematic,
} from '@ts/types/taxonomies';

/**
 * Format a post preview from RawArticlePreview to ArticlePreview type.
 * @param rawPost - A post preview coming from WP GraphQL.
 * @returns A formatted post preview.
 */
export const getFormattedPostPreview = (rawPost: RawArticlePreview) => {
  const {
    acfPosts,
    commentCount,
    contentParts,
    date,
    featuredImage,
    id,
    info,
    modified,
    slug,
    title,
  } = rawPost;

  const dates = {
    publication: date,
    update: modified,
  };

  const topics = acfPosts.postsInTopic ? acfPosts.postsInTopic : [];
  const thematics = acfPosts.postsInThematic ? acfPosts.postsInThematic : [];

  const formattedPost: ArticlePreview = {
    commentCount,
    dates,
    featuredImage: featuredImage ? featuredImage.node : null,
    id,
    info,
    intro: contentParts.beforeMore,
    slug,
    topics,
    thematics,
    title,
  };

  return formattedPost;
};

/**
 * Format an array of posts list from RawArticlePreview to ArticlePreview type.
 * @param rawPosts - A posts list coming from WP GraphQL.
 * @returns A formatted posts list.
 */
export const getFormattedPostsList = (
  rawPosts: RawArticlePreview[]
): ArticlePreview[] => {
  return rawPosts
    .filter((post) => Object.getOwnPropertyNames(post).length > 0)
    .map((post) => {
      return getFormattedPostPreview(post);
    });
};

/**
 * Format a topic from RawTopic to Topic type.
 * @param rawTopic - A topic coming from WP GraphQL.
 * @returns A formatted topic.
 */
export const getFormattedTopic = (rawTopic: RawTopic): Topic => {
  const {
    acfTopics,
    contentParts,
    databaseId,
    date,
    featuredImage,
    id,
    info,
    modified,
    seo,
    title,
  } = rawTopic;

  const dates = {
    publication: date,
    update: modified,
  };

  const posts = getFormattedPostsList(acfTopics.postsInTopic);

  const formattedTopic: Topic = {
    content: contentParts.afterMore,
    databaseId,
    dates,
    featuredImage: featuredImage ? featuredImage.node : null,
    id,
    info,
    intro: contentParts.beforeMore,
    officialWebsite: acfTopics.officialWebsite,
    posts,
    seo,
    title,
  };

  return formattedTopic;
};

/**
 * Format a thematic from RawThematic to Thematic type.
 * @param rawThematic - A thematic coming from wP GraphQL.
 * @returns A formatted thematic.
 */
export const getFormattedThematic = (rawThematic: RawThematic): Thematic => {
  const {
    acfThematics,
    contentParts,
    databaseId,
    date,
    id,
    info,
    modified,
    seo,
    title,
  } = rawThematic;

  const dates = {
    publication: date,
    update: modified,
  };

  const posts = getFormattedPostsList(acfThematics.postsInThematic);

  const formattedThematic: Thematic = {
    content: contentParts.afterMore,
    databaseId,
    dates,
    id,
    info,
    intro: contentParts.beforeMore,
    posts,
    seo,
    title,
  };

  return formattedThematic;
};

/**
 * Format a comments list from RawComment to Comment type.
 * @param rawComments - A comments list coming from WP GraphQL.
 * @returns A formatted comments list.
 */
export const getFormattedComments = (rawComments: RawComment[]): Comment[] => {
  const formattedComments: Comment[] = rawComments.map((comment) => {
    const formattedComment: Comment = {
      ...comment,
      author: comment.author.node,
      replies: [],
    };

    return formattedComment;
  });

  return formattedComments;
};

/**
 * Create a comments tree with replies.
 * @param comments - A flatten comments list.
 * @returns An array of comments with replies.
 */
export const buildCommentsTree = (comments: Comment[]) => {
  type CommentsHashTable = {
    [key: string]: Comment;
  };

  const hashTable: CommentsHashTable = Object.create(null);
  const commentsTree: Comment[] = [];

  comments.forEach(
    (comment) => (hashTable[comment.databaseId] = { ...comment, replies: [] })
  );

  comments.forEach((comment) => {
    if (!comment.parentDatabaseId) {
      commentsTree.push(hashTable[comment.databaseId]);
    } else {
      hashTable[comment.parentDatabaseId].replies.push(
        hashTable[comment.databaseId]
      );
    }
  });

  return commentsTree;
};

export const getFormattedTopicsPreview = (
  topics: RawTopicPreview[]
): TopicPreview[] => {
  const formattedTopics: TopicPreview[] = topics.map((topic) => {
    return {
      ...topic,
      featuredImage: topic.featuredImage ? topic.featuredImage.node : null,
    };
  });

  return formattedTopics;
};

/**
 * Format an article from RawArticle to Article type.
 * @param rawPost - An article coming from WP GraphQL.
 * @returns A formatted article.
 */
export const getFormattedPost = (rawPost: RawArticle): Article => {
  const {
    acfPosts,
    author,
    commentCount,
    contentParts,
    databaseId,
    date,
    featuredImage,
    id,
    info,
    modified,
    seo,
    title,
  } = rawPost;

  const dates = {
    publication: date,
    update: modified,
  };

  const topics = acfPosts.postsInTopic
    ? getFormattedTopicsPreview(acfPosts.postsInTopic)
    : [];

  const formattedPost: Article = {
    author: author.node,
    commentCount,
    content: contentParts.afterMore,
    databaseId,
    dates,
    featuredImage: featuredImage ? featuredImage.node : null,
    id,
    info,
    intro: contentParts.beforeMore,
    seo,
    topics,
    thematics: acfPosts.postsInThematic ? acfPosts.postsInThematic : [],
    title,
  };

  return formattedPost;
};

/**
 * Converts a date to a string by using the specified locale.
 * @param {string} date The date.
 * @param {string} locale A locale.
 * @returns {string} The formatted date to locale date string.
 */
export const <style>pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */</style><div class="highlight"><pre><span></span>import {
  forwardRef,
  type FieldsetHTMLAttributes,
  ForwardRefRenderFunction,
  ReactElement,
} from &#39;react&#39;;
import styles from &#39;./fieldset.module.scss&#39;;
import { LegendProps } from &#39;../legend&#39;;

export type FieldsetProps = Omit&lt;
  FieldsetHTMLAttributes&lt;HTMLFieldSetElement&gt;,
  &#39;disabled&#39; | &#39;hidden&#39;
&gt; &amp; {
  /**
   * Should the fieldset be disabled?
   *
   * @default false
   */
  isDisabled?: boolean;
  /**
   * Should the fieldset contents be inlined?
   *
   * @default false
   */
  isInline?: boolean;
  /**
   * The fieldset legend.
   */
  legend?: ReactElement&lt;LegendProps&gt;;
};

/**
 * Fieldset component.
 */
const FieldsetWithRef: ForwardRefRenderFunction&lt;
  HTMLFieldSetElement,
  FieldsetProps
&gt; = (
  {
    children,
    className = &#39;&#39;,
    isDisabled = false,
    isInline = false,
    legend,
    ...props
  },
  ref
) =&gt; {
  const layoutModifier = isInline
    ? styles[&#39;fieldset--inline&#39;]
    : styles[&#39;fieldset--stack&#39;];
  const legendModifier = legend ? styles[&#39;fieldset--has-legend&#39;] : &#39;&#39;;
  const fieldsetClass = `${styles.fieldset} ${legendModifier} ${layoutModifier} ${className}`;

  return (
    &lt;fieldset
      {...props}
      className={fieldsetClass}
      disabled={isDisabled}
      ref={ref}
    &gt;
      {legend}
      {children}
    &lt;/fieldset&gt;
  );
};

export const Fieldset = forwardRef(FieldsetWithRef);
</pre></div>
</code></pre></td></tr></table>
</div> <!-- class=content -->
<div class='footer'>generated by <a href='https://git.zx2c4.com/cgit/about/'>cgit v1.2.3</a> (<a href='https://git-scm.com/'>git 2.39.1</a>) at 2025-10-30 01:34:43 +0000</div>
</div> <!-- id=cgit -->
</body>
</html>
