// Chat components: ChatMessage, ListingCard, TraceOverlay, TypingIndicator

const { useState, useEffect, useRef } = React;

// Tiny markdown renderer — handles **bold**, lists, and line breaks.
// Good enough for our scripted responses; no external deps.
function renderMarkdown(text) {
  if (!text) return null;
  const lines = text.split("\n");
  const out = [];
  let listBuffer = [];

  const flushList = () => {
    if (listBuffer.length) {
      out.push(
        <ol key={`ol-${out.length}`} className="md-ol">
          {listBuffer.map((item, i) => (
            <li key={i}>{renderInline(item)}</li>
          ))}
        </ol>
      );
      listBuffer = [];
    }
  };

  lines.forEach((line, i) => {
    const ol = line.match(/^\s*(\d+)\.\s+(.*)$/);
    const ul = line.match(/^\s*[-•]\s+(.*)$/);
    if (ol) {
      listBuffer.push(ol[2]);
    } else if (ul) {
      listBuffer.push(ul[1]);
    } else {
      flushList();
      if (line.trim() === "") {
        out.push(<div key={i} className="md-spacer" />);
      } else {
        out.push(
          <p key={i} className="md-p">
            {renderInline(line)}
          </p>
        );
      }
    }
  });
  flushList();
  return out;
}

function renderInline(text) {
  // **bold** segments
  const parts = text.split(/(\*\*[^*]+\*\*)/g);
  return parts.map((p, i) =>
    p.startsWith("**") && p.endsWith("**") ? (
      <strong key={i}>{p.slice(2, -2)}</strong>
    ) : (
      <span key={i}>{p}</span>
    )
  );
}

function formatPriceFull(rub) {
  return rub.toLocaleString("ru-RU") + " ₽";
}

function formatPriceShort(rub) {
  const mln = rub / 1_000_000;
  return mln.toFixed(mln < 10 ? 1 : 0).replace(".", ",") + " млн ₽";
}

function ListingCard({ listing, layout, isActive, isHover, onClick, onHover, onDetails }) {
  const ppm = Math.round(listing.price / listing.area / 1000);
  return (
    <article
      data-comment-anchor={`listing-${listing.id}`}
      className={`listing-card listing-card--${layout} ${isActive ? "is-active" : ""} ${isHover ? "is-hover" : ""}`}
      onMouseEnter={() => onHover && onHover(listing.id)}
      onMouseLeave={() => onHover && onHover(null)}
      onClick={() => onClick && onClick(listing.id)}
    >
      <div
        className="listing-thumb"
        style={{
          background: `linear-gradient(135deg, hsl(${listing.image_hue}, 38%, 78%), hsl(${(listing.image_hue + 18) % 360}, 30%, 62%))`,
        }}
      >
        <div className="listing-thumb-shapes">
          <div className="lt-shape lt-shape-1" />
          <div className="lt-shape lt-shape-2" />
          <div className="lt-shape lt-shape-3" />
        </div>
        <span className="listing-id-pill">{listing.id}</span>
      </div>

      <div className="listing-body">
        <div className="listing-top">
          <div className="listing-name">{listing.name}</div>
          <div className="listing-price">{formatPriceShort(listing.price)}</div>
        </div>

        <div className="listing-meta">
          <span>{listing.rooms}-комн.</span>
          <span className="meta-dot">·</span>
          <span>{listing.area} м²</span>
          <span className="meta-dot">·</span>
          <span>{ppm} тыс/м²</span>
        </div>

        <div className="listing-sub">
          <span className="listing-district">{listing.district}</span>
          <span className="meta-dot">·</span>
          <span>м. {listing.metro_name}, {listing.metro_walk_min} мин</span>
          {listing.distance_km != null && (
            <>
              <span className="meta-dot">·</span>
              <span>{listing.distance_km} км от центра</span>
            </>
          )}
        </div>

        {layout !== "minimal" && (
          <div className="listing-actions">
            <button
              className="btn-detail"
              onClick={(e) => {
                e.stopPropagation();
                onDetails && onDetails(listing);
              }}
            >
              Подробнее
            </button>
          </div>
        )}
      </div>
    </article>
  );
}

function TypingIndicator({ traceItems, showTrace }) {
  return (
    <div className="msg msg--assistant msg--typing">
      <div className="msg-avatar">
        <span className="msg-avatar-dot" />
      </div>
      <div className="msg-bubble">
        <div className="typing-dots">
          <span /><span /><span />
        </div>
        {showTrace && traceItems && traceItems.length > 0 && (
          <div className="typing-trace">
            {traceItems.map((t, i) => (
              <div key={i} className={`trace-line ${t.done ? "trace-done" : "trace-active"}`}>
                <span className="trace-icon">{t.done ? "✓" : "›"}</span>
                <code className="trace-name">{t.name}</code>
                <span className="trace-args">{formatArgs(t.args)}</span>
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

function formatArgs(args) {
  if (!args) return "";
  const entries = Object.entries(args).map(([k, v]) => {
    let val = typeof v === "string" ? `"${v}"` : Array.isArray(v) ? `[${v.join(",")}]` : v;
    return `${k}: ${val}`;
  });
  return entries.join(", ");
}

function TraceBlock({ items }) {
  return (
    <div className="msg-trace">
      <div className="msg-trace-label">tool calls</div>
      {items.map((t, i) => (
        <div key={i} className="trace-line trace-done">
          <span className="trace-icon">✓</span>
          <code className="trace-name">{t.name}</code>
          <span className="trace-args">{formatArgs(t.args)}</span>
          <span className="trace-ms">{t.ms} ms</span>
        </div>
      ))}
    </div>
  );
}

Object.assign(window, {
  renderMarkdown,
  ListingCard,
  TypingIndicator,
  TraceBlock,
  formatPriceFull,
  formatPriceShort,
});
