import type { ReactNode } from "react";
import {
  Activity,
  Bot,
  Boxes,
  ChartNoAxesColumnIncreasing,
  ChevronLeft,
  ChevronRight,
  ExternalLink,
  KeyRound,
  LockKeyhole,
  Network,
  Wrench,
} from "lucide-react";
import { resolveAmbientMedia } from "../../entities/service/media";
import type { LauncherServiceView } from "../../entities/service/types";
import { Button } from "../../shared/ui/Button";
import { ServiceStatusBadge, StatusBadge } from "../../shared/ui/StatusBadge";

const stageActionAccentRgb = [247, 248, 244] as const;

export function ServiceStage({
  service,
  hasServices,
  onLaunch,
  onSelectPrevious,
  onSelectNext,
}: {
  service?: LauncherServiceView;
  hasServices: boolean;
  onLaunch: (service: LauncherServiceView) => void;
  onSelectPrevious: () => void;
  onSelectNext: () => void;
}) {
  if (!hasServices) {
    return (
      <section className="service-stage service-stage--empty">
        <div className="empty-stage-card">
          <Network size={28} />
          <h1>Нет доступных сервисов</h1>
          <p>Для активного клиента не найдено доступных приложений. Проверьте гранты или статус клиента.</p>
        </div>
      </section>
    );
  }

  const style = {
    "--service-accent": service?.accentColor ?? "#C3FF66",
  } as React.CSSProperties;
  const ambientMedia = resolveAmbientMedia(service);
  const disabledReason = service
    ? service.status === "maintenance"
      ? "Сервис временно недоступен"
      : service.userAccess === "denied"
        ? "Нет доступа"
        : service.effectiveAccess.openEnabled
          ? null
          : "Открытие заблокировано"
    : null;

  return (
    <section className="service-stage" style={style}>
      <div className="stage-video-shell">
        <div className="stage-video-stream" aria-hidden="true">
          <StageMedia className="stage-video-gif" src={ambientMedia.src} kind={ambientMedia.kind} priority={!service} />
        </div>

        {service ? (
          <div className="stage-service-overlay">
            <article className="stage-image-card">
              <div className="stage-image-card__visual">
                {service.media.coverImage || service.media.thumbnail ? (
                  <StageMedia
                    className="stage-image-card__image"
                    src={service.media.coverImage ?? service.media.thumbnail ?? ""}
                    kind={service.media.coverKind}
                  />
                ) : (
                  <>
                    <div className="stage-image-card__figure" />
                    <div className="stage-image-card__glow" />
                  </>
                )}
              </div>
            </article>

            <aside className="stage-description-card">
              <div className="stage-card-label">
                <ServiceIcon slug={service.slug} />
                <span>Description</span>
              </div>

              <div className="stage-description-card__copy">
                <h1>{service.title}</h1>
              </div>

              <div className="stage-description-card__description">
                <RichDescription text={service.fullDescription ?? service.description} />
              </div>

              <div className="stage-description-card__footer">
                <div className="stage-description-card__chips">
                  <ServiceStatusBadge status={service.status} />
                  <StatusBadge
                    label={service.userAccess === "allowed" ? `Доступ: ${service.appRole ?? "member"}` : "Нет доступа"}
                    tone={service.userAccess === "allowed" ? "green" : "muted"}
                  />
                </div>
                <Button
                  type="button"
                  variant="accent"
                  accentRgb={stageActionAccentRgb}
                  icon={
                    service.status === "maintenance" ? (
                      <Wrench size={16} />
                    ) : service.userAccess === "denied" ? (
                      <LockKeyhole size={16} />
                    ) : (
                      <ExternalLink size={16} />
                    )
                  }
                  onClick={() => onLaunch(service)}
                  disabled={!service.effectiveAccess.openEnabled || !service.openUrl}
                >
                  {disabledReason ?? "Открыть"}
                </Button>
              </div>
            </aside>
          </div>
        ) : (
          <div className="stage-empty-title" aria-label="NodeDC витрина модулей">
            <span>NODE.DC</span>
            <strong>Витрина модулей</strong>
          </div>
        )}

        <div className="stage-video-controls">
          <button type="button" aria-label="Предыдущий сервис" onClick={onSelectPrevious}>
            <ChevronLeft size={15} />
          </button>
          <button type="button" aria-label="Следующий сервис" onClick={onSelectNext}>
            <ChevronRight size={15} />
          </button>
        </div>
      </div>
    </section>
  );
}

function ServiceIcon({ slug }: { slug: string }) {
  if (slug.includes("task")) return <ChartNoAxesColumnIncreasing size={18} />;
  if (slug.includes("1c")) return <Boxes size={18} />;
  if (slug.includes("tender")) return <KeyRound size={18} />;
  if (slug.includes("twin")) return <Activity size={18} />;
  return <Bot size={18} />;
}

function StageMedia({
  src,
  kind,
  className,
  priority = false,
}: {
  src: string;
  kind?: LauncherServiceView["media"]["coverKind"];
  className: string;
  priority?: boolean;
}) {
  if (kind === "video" || isVideoSource(src)) {
    return <video className={className} src={src} autoPlay loop muted playsInline preload="metadata" />;
  }

  return <img className={className} src={src} alt="" loading={priority ? "eager" : "lazy"} decoding="async" />;
}

function RichDescription({ text }: { text: string }) {
  const blocks = text
    .replace(/\r\n/g, "\n")
    .split(/\n{2,}/)
    .map((block) => block.trim())
    .filter(Boolean);

  if (!blocks.length) return null;

  return (
    <div className="stage-rich-description">
      {blocks.map((block, index) => {
        const lines = block.split("\n").map((line) => line.trim()).filter(Boolean);
        const isList = lines.length > 0 && lines.every((line) => /^[-*]\s+/.test(line));

        if (isList) {
          return (
            <ul key={`list-${index}`}>
              {lines.map((line, lineIndex) => (
                <li key={lineIndex}>{renderInlineRichText(line.replace(/^[-*]\s+/, ""))}</li>
              ))}
            </ul>
          );
        }

        return <p key={`p-${index}`}>{renderInlineRichText(lines.join("\n"))}</p>;
      })}
    </div>
  );
}

function renderInlineRichText(text: string): ReactNode[] {
  const parts: ReactNode[] = [];
  const pattern = /(\*\*[^*]+\*\*|__[^_]+__|`[^`]+`|\*[^*]+\*|_[^_]+_|\n)/g;
  let lastIndex = 0;
  let match: RegExpExecArray | null;

  while ((match = pattern.exec(text))) {
    if (match.index > lastIndex) {
      parts.push(text.slice(lastIndex, match.index));
    }

    const token = match[0];
    const key = `${match.index}-${token}`;

    if (token === "\n") {
      parts.push(<br key={key} />);
    } else if (token.startsWith("**") || token.startsWith("__")) {
      parts.push(<strong key={key}>{token.slice(2, -2)}</strong>);
    } else if (token.startsWith("`")) {
      parts.push(<code key={key}>{token.slice(1, -1)}</code>);
    } else {
      parts.push(<em key={key}>{token.slice(1, -1)}</em>);
    }

    lastIndex = pattern.lastIndex;
  }

  if (lastIndex < text.length) {
    parts.push(text.slice(lastIndex));
  }

  return parts;
}

function isVideoSource(src: string) {
  return /\.(mp4|webm|mov|m4v|avi|mkv)(\?.*)?$/i.test(src);
}
