---
import type { Post } from '../lib/types';
import CodeBlock from './CodeBlock.astro';
import ResponsiveImage from './ui/ResponsiveImage.astro';
import { formatReadTime, getI18n } from '../lib/i18n';
import {
  buildCategoryUrl,
  buildTagUrl,
  getAccentVars,
  getCategoryTheme,
  getPostTypeColor,
  getPostTypeTheme,
  getTagTheme,
  resolveFileRef,
} from '../lib/utils';

interface Props {
  post: Post;
  selectedTag?: string;
  highlightTerm?: string;
  tagHrefPrefix?: string | null;
}

const { post, selectedTag = '', highlightTerm = '', tagHrefPrefix = null } = Astro.props;
const { locale, t } = getI18n(Astro);

const typeColor = getPostTypeColor(post.type);
const typeTheme = getPostTypeTheme(post.type);
const categoryTheme = getCategoryTheme(post.category);

const escapeHtml = (value: string) =>
  value
    .replaceAll('&', '&amp;')
    .replaceAll('<', '&lt;')
    .replaceAll('>', '&gt;')
    .replaceAll('"', '&quot;')
    .replaceAll("'", '&#39;');

const highlightText = (value: string, query: string) => {
  const escapedValue = escapeHtml(value || '');
  const normalizedQuery = query.trim();
  if (!normalizedQuery) {
    return escapedValue;
  }

  const escapedQuery = normalizedQuery.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  return escapedValue.replace(
    new RegExp(`(${escapedQuery})`, 'ig'),
    '<mark class="rounded px-1 bg-[var(--primary-light)] text-[var(--title-color)]">$1</mark>'
  );
};

const normalizedSelectedTag = selectedTag.trim().toLowerCase();
const resolveTagHref = (tag: string) =>
  tagHrefPrefix ? `${tagHrefPrefix}${encodeURIComponent(tag)}` : buildTagUrl(tag);
---

<article
  class="post-card terminal-panel group relative my-2.5 cursor-pointer p-4 transition-all duration-300 hover:-translate-y-1 hover:border-[var(--primary)] focus-within:border-[var(--primary)]"
  style={`--post-border-color: ${typeColor}`}
  data-post-card-link
  data-post-url={`/articles/${post.slug}`}
>
  <div class="absolute left-0 top-4 bottom-4 w-1 rounded-full opacity-80" style={`background-color: ${typeColor}`}></div>

  <div class="relative z-10 mb-2 flex flex-col gap-2.5 pl-3 lg:flex-row lg:items-start lg:justify-between">
    <div class="flex-1 min-w-0">
      <div class="mb-2 flex items-center gap-2">
        <span class="w-3 h-3 rounded-full shrink-0" style={`background-color: ${typeColor}`}></span>
        <span class="terminal-chip terminal-chip--accent shrink-0 text-[10px] py-1 px-2" style={getAccentVars(typeTheme)}>
          {post.type === 'article' ? t('common.article') : t('common.tweet')}
        </span>
        <a
          href={`/articles/${post.slug}`}
          class={`inline-flex min-w-0 items-center text-[var(--title-color)] transition hover:text-[var(--primary)] ${post.type === 'article' ? 'text-lg font-bold' : 'text-base font-bold'}`}
        >
          <h2 class="truncate" set:html={highlightText(post.title, highlightTerm)} />
        </a>
      </div>
      <p class="text-sm text-[var(--text-secondary)]">
        {post.date} | {t('common.readTime')}: {formatReadTime(locale, post.readTime, t)}
      </p>
    </div>
    <a
      href={buildCategoryUrl(post.category)}
      class="terminal-chip terminal-chip--accent shrink-0 text-xs py-1 px-2.5"
      style={getAccentVars(categoryTheme)}
    >
      #{post.category}
    </a>
  </div>

  <p class="relative z-10 mb-3 pl-3 text-sm leading-7 text-[var(--text-secondary)]" set:html={highlightText(post.description, highlightTerm)} />

  {post.code && (
    <div class="relative z-10 mb-3">
      <CodeBlock code={post.code} language={post.language || 'bash'} />
    </div>
  )}

  {post.images && post.images.length > 0 && (
    <div class="relative z-10 mb-3 grid gap-2" class:list={[
      post.images.length === 1 ? 'grid-cols-1' :
      post.images.length === 2 ? 'grid-cols-2' :
      post.images.length >= 3 ? 'grid-cols-2 md:grid-cols-3' :
      'grid-cols-1'
    ]}>
      {post.images.map((img, index) => (
        <div class:list={[
          "relative overflow-hidden rounded-lg border border-[var(--border-color)]",
          post.images && post.images.length === 1 ? 'aspect-video' :
          'aspect-square'
        ]}>
          <ResponsiveImage
            src={resolveFileRef(img)}
            alt={`${post.title} - ${index + 1}`}
            pictureClass="block h-full w-full"
            imgClass="w-full h-full object-cover hover:scale-105 transition-transform"
            widths={post.images && post.images.length === 1 ? [640, 960, 1280, 1600] : [320, 480, 720, 960]}
            sizes={post.images && post.images.length === 1
              ? '(min-width: 1024px) 40rem, 100vw'
              : '(min-width: 1024px) 18rem, (min-width: 640px) 45vw, 100vw'}
          />
        </div>
      ))}
    </div>
  )}

  <!-- Tags -->
  <div class="relative z-10 pl-3 flex flex-wrap gap-2">
    {post.tags?.map(tag => (
      <a
        href={resolveTagHref(tag)}
        class:list={[
          'terminal-chip text-xs py-1 px-2.5',
          'terminal-chip--accent',
          normalizedSelectedTag === tag.trim().toLowerCase() && 'is-active'
        ]}
        style={getAccentVars(getTagTheme(tag))}
      >
        <i class="fas fa-hashtag text-xs"></i>
        <span set:html={highlightText(tag, highlightTerm)} />
      </a>
    ))}
  </div>

  <div class="relative z-10 mt-3 pl-3">
    <a
      href={`/articles/${post.slug}`}
      class="terminal-action-button inline-flex"
    >
      <i class="fas fa-angle-right"></i>
      <span>{t('common.readMore')}</span>
    </a>
  </div>
</article>

<script>
  const interactiveSelector = 'a, button, input, textarea, select, summary, [role="button"]';

  const hasTextSelection = () => {
    const selection = window.getSelection?.();
    return Boolean(selection && selection.toString().trim());
  };

  document.querySelectorAll('[data-post-card-link]').forEach((card) => {
    if (!(card instanceof HTMLElement)) return;
    if (card.dataset.postCardBound === 'true') return;
    card.dataset.postCardBound = 'true';

    card.addEventListener('click', (event) => {
      if (event.defaultPrevented) return;
      if (hasTextSelection()) return;
      if (event.target instanceof Element && event.target.closest(interactiveSelector)) return;
      const href = card.dataset.postUrl;
      if (!href) return;
      window.location.href = href;
    });


  });
</script>
