import { Component, Input, Output, EventEmitter, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { I18nService } from '../../../services/i18n';
import { IonIcon, IonButton, IonBadge, IonTextarea, IonItem, IonSelect, IonSelectOption, IonSpinner, IonInfiniteScroll, IonInfiniteScrollContent, } from '@ionic/angular/standalone';
import { addIcons } from 'ionicons';
import { chatbubblesOutline, filterOutline, sendOutline, chatbubbleEllipsesOutline, swapVerticalOutline, } from 'ionicons/icons';
import { CommentComponent } from '../../molecules/comment/comment.component';
import { AvatarComponent } from '../../atoms/avatar/avatar.component';
import { SkeletonComponent } from '../../atoms/skeleton/skeleton.component';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
addIcons({
    chatbubblesOutline,
    filterOutline,
    sendOutline,
    chatbubbleEllipsesOutline,
    swapVerticalOutline,
});
/**
 * val-comment-section
 *
 * An organism component that provides a complete comment section with:
 * - Header with title and count
 * - Sort/filter options
 * - New comment input
 * - Comments list with val-comment
 * - Load more pagination
 * - Empty state
 *
 * @example Basic usage
 * <val-comment-section [props]="{
 *   title: 'Comments',
 *   count: 42,
 *   comments: commentsArray,
 *   showInput: true
 * }"></val-comment-section>
 *
 * @example With sorting
 * <val-comment-section [props]="{
 *   title: 'Reviews',
 *   count: 128,
 *   comments: reviews,
 *   sortOptions: [
 *     { token: 'newest', label: 'Newest first' },
 *     { token: 'oldest', label: 'Oldest first' },
 *     { token: 'popular', label: 'Most popular' }
 *   ],
 *   selectedSort: 'newest'
 * }" (sortChange)="onSort($event)"></val-comment-section>
 *
 * @input props: CommentSectionMetadata - Configuration for the section
 * @output sortChange - Sort option changed
 * @output commentSubmit - New comment submitted
 * @output loadMore - Load more clicked
 * @output authorClick - Comment author clicked (bubbled from val-comment)
 * @output reactionClick - Reaction clicked (bubbled)
 * @output actionClick - Action clicked (bubbled)
 * @output menuItemClick - Menu item clicked (bubbled)
 * @output commentLoadMore - Load more replies clicked (bubbled)
 * @output collapseToggle - Comment collapse toggled (bubbled)
 */
export class CommentSectionComponent {
    constructor() {
        this.i18n = inject(I18nService);
        // Section events
        this.sortChange = new EventEmitter();
        this.commentSubmit = new EventEmitter();
        this.loadMore = new EventEmitter();
        // Bubbled events from val-comment
        this.authorClick = new EventEmitter();
        this.reactionClick = new EventEmitter();
        this.actionClick = new EventEmitter();
        this.menuItemClick = new EventEmitter();
        this.commentLoadMore = new EventEmitter();
        this.collapseToggle = new EventEmitter();
        // Reply state
        this.replyStart = new EventEmitter();
        this.newCommentText = '';
        this.replyingTo = null;
        this.displayTitle = '';
        this.displayLoadMoreLabel = '';
        this.infiniteScrollEvent = null;
    }
    ngOnInit() {
        this.updateDisplayTexts();
    }
    updateDisplayTexts() {
        this.displayTitle = this.props.title || this.i18n.t('comments');
        this.displayLoadMoreLabel = this.props.loadMoreLabel || this.i18n.t('loadMoreComments');
    }
    getSortByLabel() {
        return this.i18n.t('sortBy');
    }
    formatCount(count) {
        if (count >= 1000000) {
            return (count / 1000000).toFixed(1).replace(/\.0$/, '') + 'M';
        }
        if (count >= 1000) {
            return (count / 1000).toFixed(1).replace(/\.0$/, '') + 'K';
        }
        return count.toString();
    }
    getSortOptionLabel(option) {
        return option.label;
    }
    getInputPlaceholder() {
        return this.props.inputConfig?.placeholder || this.i18n.t('writeComment');
    }
    getSubmitLabel() {
        return this.props.inputConfig?.submitLabel || this.i18n.t('publish');
    }
    getEmptyTitle() {
        return this.props.emptyState?.title || this.i18n.t('noCommentsYet');
    }
    getEmptyMessage() {
        return this.props.emptyState?.message || this.i18n.t('beFirstToComment');
    }
    getSkeletonArray() {
        const count = this.props.skeletonCount || 3;
        return Array(count)
            .fill(0)
            .map((_, i) => i);
    }
    canSubmit() {
        const minLength = this.props.inputConfig?.minLength || 1;
        return this.newCommentText.trim().length >= minLength && !this.props.loading && !this.props.inputConfig?.disabled;
    }
    isNearLimit() {
        const maxLength = this.props.inputConfig?.maxLength || 2000;
        return this.newCommentText.length > maxLength * 0.9;
    }
    onSortChange(event) {
        const selectedToken = event.detail.value;
        const option = this.props.sortOptions?.find(o => o.token === selectedToken);
        if (option) {
            this.sortChange.emit({
                option,
                previousSort: this.props.selectedSort,
            });
        }
    }
    onSubmitComment() {
        if (!this.canSubmit())
            return;
        this.commentSubmit.emit({
            content: this.newCommentText.trim(),
            parentToken: this.replyingTo || undefined,
            sectionToken: this.props.token,
        });
        this.newCommentText = '';
        this.replyingTo = null;
    }
    onCommentAction(event) {
        // Check if it's a reply action
        if (event.action.token === 'reply') {
            this.replyingTo = event.commentToken;
            this.replyStart.emit({ commentToken: event.commentToken });
        }
        this.actionClick.emit(event);
    }
    onLoadMore() {
        this.loadMore.emit({
            sectionToken: this.props.token,
            currentCount: this.props.comments?.length || 0,
        });
    }
    onInfiniteScroll(event) {
        this.loadMore.emit({
            sectionToken: this.props.token,
            currentCount: this.props.comments?.length || 0,
        });
        // The parent component should call completeInfiniteScroll() when done loading
        // Store reference to complete the infinite scroll
        this.infiniteScrollEvent = event;
    }
    // Call this method from parent after loading more comments
    completeInfiniteScroll() {
        if (this.infiniteScrollEvent) {
            this.infiniteScrollEvent.target.complete();
            this.infiniteScrollEvent = null;
        }
    }
    // Method to programmatically start a reply
    startReply(commentToken) {
        this.replyingTo = commentToken;
    }
    // Method to cancel reply
    cancelReply() {
        this.replyingTo = null;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommentSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: CommentSectionComponent, isStandalone: true, selector: "val-comment-section", inputs: { props: "props" }, outputs: { sortChange: "sortChange", commentSubmit: "commentSubmit", loadMore: "loadMore", authorClick: "authorClick", reactionClick: "reactionClick", actionClick: "actionClick", menuItemClick: "menuItemClick", commentLoadMore: "commentLoadMore", collapseToggle: "collapseToggle", replyStart: "replyStart" }, ngImport: i0, template: `
    <div class="comment-section" [class.loading]="props.loading">
      <!-- Header -->
      <div class="section-header">
        <div class="header-title">
          <ion-icon name="chatbubbles-outline" class="title-icon"></ion-icon>
          <h3 class="title">{{ displayTitle }}</h3>
          @if (props.showCount !== false && props.count !== undefined) {
            <ion-badge color="medium" class="count-badge">
              {{ formatCount(props.count) }}
            </ion-badge>
          }
        </div>

        @if (props.sortOptions && props.sortOptions.length > 0) {
          <div class="header-actions">
            <ion-item lines="none" class="sort-select-item">
              <ion-icon name="swap-vertical-outline" slot="start" class="sort-icon"></ion-icon>
              <ion-select
                [value]="props.selectedSort"
                [placeholder]="props.sortLabel || getSortByLabel()"
                interface="popover"
                (ionChange)="onSortChange($event)"
              >
                @for (option of props.sortOptions; track option.token) {
                  <ion-select-option [value]="option.token">
                    {{ getSortOptionLabel(option) }}
                  </ion-select-option>
                }
              </ion-select>
            </ion-item>
          </div>
        }
      </div>

      <!-- New Comment Input -->
      @if (props.showInput !== false) {
        <div class="new-comment-section">
          <div class="input-wrapper">
            @if (props.inputConfig?.currentUser?.avatar) {
              <div class="input-avatar">
                <val-avatar [props]="props.inputConfig.currentUser.avatar"></val-avatar>
              </div>
            }

            <div class="input-container">
              <ion-textarea
                [(ngModel)]="newCommentText"
                [placeholder]="getInputPlaceholder()"
                [maxlength]="props.inputConfig?.maxLength || 2000"
                [disabled]="props.inputConfig?.disabled || props.loading"
                [autoGrow]="true"
                rows="2"
                class="comment-textarea"
              ></ion-textarea>

              <div class="input-actions">
                @if (props.inputConfig?.showCounter && props.inputConfig?.maxLength) {
                  <span class="char-counter" [class.warning]="isNearLimit()">
                    {{ newCommentText.length }} / {{ props.inputConfig.maxLength }}
                  </span>
                }

                <ion-button
                  [color]="props.inputConfig?.submitColor || props.color || 'primary'"
                  [disabled]="!canSubmit()"
                  size="small"
                  (click)="onSubmitComment()"
                >
                  <ion-icon name="send-outline" slot="start"></ion-icon>
                  {{ getSubmitLabel() }}
                </ion-button>
              </div>
            </div>
          </div>
        </div>
      }

      @if (props.loading) {
        <div class="loading-state">
          @for (i of getSkeletonArray(); track i) {
            <div class="skeleton-comment">
              <val-skeleton [props]="{ type: 'avatar', width: '36px', height: '36px' }"></val-skeleton>
              <div class="skeleton-content">
                <val-skeleton [props]="{ type: 'text', width: '120px', height: '14px' }"></val-skeleton>
                <val-skeleton [props]="{ type: 'paragraph', lines: 2 }"></val-skeleton>
              </div>
            </div>
          }
        </div>
      } @else if (props.comments && props.comments.length > 0) {
        <div class="comments-list" [class.with-dividers]="props.showDividers">
          @for (comment of props.comments; track comment.token) {
            <val-comment
              [props]="comment"
              (authorClick)="authorClick.emit($event)"
              (reactionClick)="reactionClick.emit($event)"
              (actionClick)="onCommentAction($event)"
              (menuItemClick)="menuItemClick.emit($event)"
              (loadMoreClick)="commentLoadMore.emit($event)"
              (collapseToggle)="collapseToggle.emit($event)"
            ></val-comment>

            @if (props.showDividers && !$last) {
              <div class="comment-divider"></div>
            }
          }

          @if (props.hasMore && props.paginationMode !== 'infinite') {
            <div class="load-more-section">
              @if (props.loadingMore) {
                <ion-spinner name="circular" [color]="props.color || 'primary'"></ion-spinner>
              } @else {
                <ion-button fill="outline" [color]="props.color || 'primary'" expand="block" (click)="onLoadMore()">
                  {{ displayLoadMoreLabel }}
                </ion-button>
              }
            </div>
          }
        </div>

        @if (props.paginationMode === 'infinite') {
          <ion-infinite-scroll
            [threshold]="props.infiniteScrollThreshold || '100px'"
            [position]="props.infiniteScrollPosition || 'bottom'"
            [disabled]="!props.hasMore"
            (ionInfinite)="onInfiniteScroll($event)"
          >
            <ion-infinite-scroll-content
              [loadingSpinner]="'crescent'"
              [loadingText]="displayLoadMoreLabel"
            ></ion-infinite-scroll-content>
          </ion-infinite-scroll>
        }
      } @else {
        <div class="empty-state">
          <ion-icon [name]="props.emptyState?.icon || 'chatbubble-ellipses-outline'" class="empty-icon"></ion-icon>
          <h4 class="empty-title">{{ getEmptyTitle() }}</h4>
          <p class="empty-message">{{ getEmptyMessage() }}</p>
        </div>
      }
    </div>
  `, isInline: true, styles: ["@charset \"UTF-8\";:root{--val-container-sm: 540px;--val-container-md: 720px;--val-container-lg: 880px;--val-container-xl: 1100px;--val-container-padding: 16px;--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}body.dark,html.ion-palette-dark,body[data-theme=dark]{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}:host{display:block}.comment-section.loading{pointer-events:none}.section-header{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:20px;padding-bottom:16px;border-bottom:1px solid var(--ion-color-light-shade)}.header-title{display:flex;align-items:center;gap:8px}.title-icon{font-size:1.5rem;color:var(--ion-color-primary)}.title{margin:0;font-size:1.125rem;font-weight:600;color:var(--ion-text-color)}.count-badge{font-size:.75rem;font-weight:600;--padding-start: 8px;--padding-end: 8px}.header-actions{display:flex;align-items:center;gap:8px}.sort-select-item{--padding-start: 0;--padding-end: 0;--inner-padding-end: 0;--background: transparent;--min-height: 36px}.sort-select-item ion-select{--padding-start: 8px;--padding-end: 8px;min-width:140px;font-size:.875rem}.sort-icon{font-size:1.125rem;color:var(--ion-color-medium);margin-right:4px}.new-comment-section{margin-bottom:24px;padding:16px;background-color:var(--ion-color-light);border-radius:12px}.input-wrapper{display:flex;gap:12px}.input-avatar{flex-shrink:0}.input-avatar val-avatar{--size: 40px}.input-container{flex:1;min-width:0}.comment-textarea{--background: var(--ion-background-color);--padding-start: 12px;--padding-end: 12px;--padding-top: 10px;--padding-bottom: 10px;border-radius:8px;font-size:.875rem;min-height:60px;border:1px solid var(--ion-color-light-shade);transition:border-color .2s}.comment-textarea:focus-within{border-color:var(--ion-color-primary)}.input-actions{display:flex;align-items:center;justify-content:flex-end;gap:12px;margin-top:10px}.char-counter{font-size:.75rem;color:var(--ion-color-medium)}.char-counter.warning{color:var(--ion-color-warning);font-weight:500}.loading-state{display:flex;flex-direction:column;gap:20px}.skeleton-comment{display:flex;gap:12px;padding:12px 0}.skeleton-comment .skeleton-content{flex:1;display:flex;flex-direction:column;gap:8px}.comments-list.with-dividers val-comment{padding:16px 0}.comments-list.with-dividers val-comment:first-child{padding-top:0}.comment-divider{height:1px;background-color:var(--ion-color-light-shade);margin:0}.load-more-section{display:flex;justify-content:center;padding:20px 0}.load-more-section ion-button{min-width:200px}.load-more-section ion-spinner{width:28px;height:28px}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:48px 24px;text-align:center}.empty-icon{font-size:4rem;color:var(--ion-color-medium);opacity:.5;margin-bottom:16px}.empty-title{margin:0 0 8px;font-size:1.125rem;font-weight:600;color:var(--ion-text-color)}.empty-message{margin:0;font-size:.875rem;color:var(--ion-color-medium);max-width:300px}@media (max-width: 576px){.section-header{flex-direction:column;align-items:flex-start}.header-actions,.sort-select-item{width:100%}.sort-select-item ion-select{width:100%}.input-wrapper{flex-direction:column}.input-avatar{display:none}.input-actions{flex-direction:column;align-items:stretch}.input-actions ion-button{width:100%}}:host-context(body.dark) .new-comment-section,:host-context(.dark) .new-comment-section,:host-context(.ion-palette-dark) .new-comment-section,:host-context(html.ion-palette-dark) .new-comment-section,:host-context([data-theme=dark]) .new-comment-section{background-color:var(--ion-color-step-100, #1a1a1a)}:host-context(body.dark) .comment-textarea,:host-context(.dark) .comment-textarea,:host-context(.ion-palette-dark) .comment-textarea,:host-context(html.ion-palette-dark) .comment-textarea,:host-context([data-theme=dark]) .comment-textarea{--background: var(--ion-color-step-50, #121212);border-color:var(--ion-color-step-200, #2a2a2a)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonBadge, selector: "ion-badge", inputs: ["color", "mode"] }, { kind: "component", type: IonTextarea, selector: "ion-textarea", inputs: ["autoGrow", "autocapitalize", "autofocus", "clearOnEdit", "color", "cols", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "maxlength", "minlength", "mode", "name", "placeholder", "readonly", "required", "rows", "shape", "spellcheck", "value", "wrap"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "errorText", "expandedIcon", "fill", "helperText", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: IonInfiniteScroll, selector: "ion-infinite-scroll", inputs: ["disabled", "position", "threshold"] }, { kind: "component", type: IonInfiniteScrollContent, selector: "ion-infinite-scroll-content", inputs: ["loadingSpinner", "loadingText"] }, { kind: "component", type: CommentComponent, selector: "val-comment", inputs: ["props"], outputs: ["authorClick", "reactionClick", "actionClick", "menuItemClick", "loadMoreClick", "collapseToggle"] }, { kind: "component", type: AvatarComponent, selector: "val-avatar", inputs: ["preset", "props"], outputs: ["onClick"] }, { kind: "component", type: SkeletonComponent, selector: "val-skeleton", inputs: ["props"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommentSectionComponent, decorators: [{
            type: Component,
            args: [{ selector: 'val-comment-section', standalone: true, imports: [
                        CommonModule,
                        FormsModule,
                        IonIcon,
                        IonButton,
                        IonBadge,
                        IonTextarea,
                        IonItem,
                        IonSelect,
                        IonSelectOption,
                        IonSpinner,
                        IonInfiniteScroll,
                        IonInfiniteScrollContent,
                        CommentComponent,
                        AvatarComponent,
                        SkeletonComponent,
                    ], template: `
    <div class="comment-section" [class.loading]="props.loading">
      <!-- Header -->
      <div class="section-header">
        <div class="header-title">
          <ion-icon name="chatbubbles-outline" class="title-icon"></ion-icon>
          <h3 class="title">{{ displayTitle }}</h3>
          @if (props.showCount !== false && props.count !== undefined) {
            <ion-badge color="medium" class="count-badge">
              {{ formatCount(props.count) }}
            </ion-badge>
          }
        </div>

        @if (props.sortOptions && props.sortOptions.length > 0) {
          <div class="header-actions">
            <ion-item lines="none" class="sort-select-item">
              <ion-icon name="swap-vertical-outline" slot="start" class="sort-icon"></ion-icon>
              <ion-select
                [value]="props.selectedSort"
                [placeholder]="props.sortLabel || getSortByLabel()"
                interface="popover"
                (ionChange)="onSortChange($event)"
              >
                @for (option of props.sortOptions; track option.token) {
                  <ion-select-option [value]="option.token">
                    {{ getSortOptionLabel(option) }}
                  </ion-select-option>
                }
              </ion-select>
            </ion-item>
          </div>
        }
      </div>

      <!-- New Comment Input -->
      @if (props.showInput !== false) {
        <div class="new-comment-section">
          <div class="input-wrapper">
            @if (props.inputConfig?.currentUser?.avatar) {
              <div class="input-avatar">
                <val-avatar [props]="props.inputConfig.currentUser.avatar"></val-avatar>
              </div>
            }

            <div class="input-container">
              <ion-textarea
                [(ngModel)]="newCommentText"
                [placeholder]="getInputPlaceholder()"
                [maxlength]="props.inputConfig?.maxLength || 2000"
                [disabled]="props.inputConfig?.disabled || props.loading"
                [autoGrow]="true"
                rows="2"
                class="comment-textarea"
              ></ion-textarea>

              <div class="input-actions">
                @if (props.inputConfig?.showCounter && props.inputConfig?.maxLength) {
                  <span class="char-counter" [class.warning]="isNearLimit()">
                    {{ newCommentText.length }} / {{ props.inputConfig.maxLength }}
                  </span>
                }

                <ion-button
                  [color]="props.inputConfig?.submitColor || props.color || 'primary'"
                  [disabled]="!canSubmit()"
                  size="small"
                  (click)="onSubmitComment()"
                >
                  <ion-icon name="send-outline" slot="start"></ion-icon>
                  {{ getSubmitLabel() }}
                </ion-button>
              </div>
            </div>
          </div>
        </div>
      }

      @if (props.loading) {
        <div class="loading-state">
          @for (i of getSkeletonArray(); track i) {
            <div class="skeleton-comment">
              <val-skeleton [props]="{ type: 'avatar', width: '36px', height: '36px' }"></val-skeleton>
              <div class="skeleton-content">
                <val-skeleton [props]="{ type: 'text', width: '120px', height: '14px' }"></val-skeleton>
                <val-skeleton [props]="{ type: 'paragraph', lines: 2 }"></val-skeleton>
              </div>
            </div>
          }
        </div>
      } @else if (props.comments && props.comments.length > 0) {
        <div class="comments-list" [class.with-dividers]="props.showDividers">
          @for (comment of props.comments; track comment.token) {
            <val-comment
              [props]="comment"
              (authorClick)="authorClick.emit($event)"
              (reactionClick)="reactionClick.emit($event)"
              (actionClick)="onCommentAction($event)"
              (menuItemClick)="menuItemClick.emit($event)"
              (loadMoreClick)="commentLoadMore.emit($event)"
              (collapseToggle)="collapseToggle.emit($event)"
            ></val-comment>

            @if (props.showDividers && !$last) {
              <div class="comment-divider"></div>
            }
          }

          @if (props.hasMore && props.paginationMode !== 'infinite') {
            <div class="load-more-section">
              @if (props.loadingMore) {
                <ion-spinner name="circular" [color]="props.color || 'primary'"></ion-spinner>
              } @else {
                <ion-button fill="outline" [color]="props.color || 'primary'" expand="block" (click)="onLoadMore()">
                  {{ displayLoadMoreLabel }}
                </ion-button>
              }
            </div>
          }
        </div>

        @if (props.paginationMode === 'infinite') {
          <ion-infinite-scroll
            [threshold]="props.infiniteScrollThreshold || '100px'"
            [position]="props.infiniteScrollPosition || 'bottom'"
            [disabled]="!props.hasMore"
            (ionInfinite)="onInfiniteScroll($event)"
          >
            <ion-infinite-scroll-content
              [loadingSpinner]="'crescent'"
              [loadingText]="displayLoadMoreLabel"
            ></ion-infinite-scroll-content>
          </ion-infinite-scroll>
        }
      } @else {
        <div class="empty-state">
          <ion-icon [name]="props.emptyState?.icon || 'chatbubble-ellipses-outline'" class="empty-icon"></ion-icon>
          <h4 class="empty-title">{{ getEmptyTitle() }}</h4>
          <p class="empty-message">{{ getEmptyMessage() }}</p>
        </div>
      }
    </div>
  `, styles: ["@charset \"UTF-8\";:root{--val-container-sm: 540px;--val-container-md: 720px;--val-container-lg: 880px;--val-container-xl: 1100px;--val-container-padding: 16px;--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}body.dark,html.ion-palette-dark,body[data-theme=dark]{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}:host{display:block}.comment-section.loading{pointer-events:none}.section-header{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:20px;padding-bottom:16px;border-bottom:1px solid var(--ion-color-light-shade)}.header-title{display:flex;align-items:center;gap:8px}.title-icon{font-size:1.5rem;color:var(--ion-color-primary)}.title{margin:0;font-size:1.125rem;font-weight:600;color:var(--ion-text-color)}.count-badge{font-size:.75rem;font-weight:600;--padding-start: 8px;--padding-end: 8px}.header-actions{display:flex;align-items:center;gap:8px}.sort-select-item{--padding-start: 0;--padding-end: 0;--inner-padding-end: 0;--background: transparent;--min-height: 36px}.sort-select-item ion-select{--padding-start: 8px;--padding-end: 8px;min-width:140px;font-size:.875rem}.sort-icon{font-size:1.125rem;color:var(--ion-color-medium);margin-right:4px}.new-comment-section{margin-bottom:24px;padding:16px;background-color:var(--ion-color-light);border-radius:12px}.input-wrapper{display:flex;gap:12px}.input-avatar{flex-shrink:0}.input-avatar val-avatar{--size: 40px}.input-container{flex:1;min-width:0}.comment-textarea{--background: var(--ion-background-color);--padding-start: 12px;--padding-end: 12px;--padding-top: 10px;--padding-bottom: 10px;border-radius:8px;font-size:.875rem;min-height:60px;border:1px solid var(--ion-color-light-shade);transition:border-color .2s}.comment-textarea:focus-within{border-color:var(--ion-color-primary)}.input-actions{display:flex;align-items:center;justify-content:flex-end;gap:12px;margin-top:10px}.char-counter{font-size:.75rem;color:var(--ion-color-medium)}.char-counter.warning{color:var(--ion-color-warning);font-weight:500}.loading-state{display:flex;flex-direction:column;gap:20px}.skeleton-comment{display:flex;gap:12px;padding:12px 0}.skeleton-comment .skeleton-content{flex:1;display:flex;flex-direction:column;gap:8px}.comments-list.with-dividers val-comment{padding:16px 0}.comments-list.with-dividers val-comment:first-child{padding-top:0}.comment-divider{height:1px;background-color:var(--ion-color-light-shade);margin:0}.load-more-section{display:flex;justify-content:center;padding:20px 0}.load-more-section ion-button{min-width:200px}.load-more-section ion-spinner{width:28px;height:28px}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:48px 24px;text-align:center}.empty-icon{font-size:4rem;color:var(--ion-color-medium);opacity:.5;margin-bottom:16px}.empty-title{margin:0 0 8px;font-size:1.125rem;font-weight:600;color:var(--ion-text-color)}.empty-message{margin:0;font-size:.875rem;color:var(--ion-color-medium);max-width:300px}@media (max-width: 576px){.section-header{flex-direction:column;align-items:flex-start}.header-actions,.sort-select-item{width:100%}.sort-select-item ion-select{width:100%}.input-wrapper{flex-direction:column}.input-avatar{display:none}.input-actions{flex-direction:column;align-items:stretch}.input-actions ion-button{width:100%}}:host-context(body.dark) .new-comment-section,:host-context(.dark) .new-comment-section,:host-context(.ion-palette-dark) .new-comment-section,:host-context(html.ion-palette-dark) .new-comment-section,:host-context([data-theme=dark]) .new-comment-section{background-color:var(--ion-color-step-100, #1a1a1a)}:host-context(body.dark) .comment-textarea,:host-context(.dark) .comment-textarea,:host-context(.ion-palette-dark) .comment-textarea,:host-context(html.ion-palette-dark) .comment-textarea,:host-context([data-theme=dark]) .comment-textarea{--background: var(--ion-color-step-50, #121212);border-color:var(--ion-color-step-200, #2a2a2a)}\n"] }]
        }], propDecorators: { props: [{
                type: Input
            }], sortChange: [{
                type: Output
            }], commentSubmit: [{
                type: Output
            }], loadMore: [{
                type: Output
            }], authorClick: [{
                type: Output
            }], reactionClick: [{
                type: Output
            }], actionClick: [{
                type: Output
            }], menuItemClick: [{
                type: Output
            }], commentLoadMore: [{
                type: Output
            }], collapseToggle: [{
                type: Output
            }], replyStart: [{
                type: Output
            }] } });
//# sourceMappingURL=data:application/json;base64, 