<template>
  <div class="reviews-page">
    <!-- Герой-секция -->
    <section class="hero-section">
      <div class="container">
        <div class="hero-content">
          <h1 class="hero-title">⭐ Отзывы участников</h1>
          <p class="hero-subtitle">Реальные истории и достижения наших бегунов</p>
          <div class="hero-stats">
            <div class="stat">
              <div class="stat-number">{{ stats.average_rating || 0 }}</div>
              <div class="stat-label">Средний рейтинг</div>
            </div>
            <div class="stat">
              <div class="stat-number">{{ stats.total_reviews || 0 }}</div>
              <div class="stat-label">Отзывов</div>
            </div>
            <div class="stat">
              <div class="stat-number">{{ stats.success_stories || 0 }}</div>
              <div class="stat-label">Историй успеха</div>
            </div>
          </div>
        </div>
      </div>
    </section>

    <!-- Основной контент -->
    <section class="reviews-section">
      <div class="container">
        <div class="reviews-header">
          <h2 class="section-title">Что говорят наши участники</h2>
          <div class="reviews-controls">
            <div class="sort-controls">
              <label for="sort">Сортировка:</label>
              <select id="sort" v-model="sortBy" @change="loadReviews">
                <option value="newest">Сначала новые</option>
                <option value="oldest">Сначала старые</option>
                <option value="highest">Высокий рейтинг</option>
                <option value="lowest">Низкий рейтинг</option>
              </select>
            </div>
            <div class="filter-controls">
              <button v-for="filter in ratingFilters" :key="filter.value"
                :class="['filter-btn', { 'active': activeRatingFilter === filter.value }]"
                @click="filterByRating(filter.value)">
                {{ filter.label }}
              </button>
            </div>
          </div>
        </div>

        <!-- Загрузка -->
        <div v-if="loading" class="loading">
          <div class="spinner"></div>
          <p>Загрузка отзывов...</p>
        </div>

        <!-- Сообщение об отсутствии отзывов -->
        <div v-else-if="reviews.length === 0" class="no-reviews">
          <h3>😔 Отзывов пока нет</h3>
          <p>Будьте первым, кто поделится своим опытом!</p>
        </div>

        <!-- Сетка отзывов -->
        <div v-else class="reviews-grid">
          <div v-for="review in reviews" :key="review.id" class="review-card"
            :class="getReviewCardClass(review.rating)">
            <div class="review-header">
              <div class="reviewer-info">
                <div class="reviewer-avatar">
                  {{ getInitials(review.author) }}
                </div>
                <div class="reviewer-details">
                  <h4 class="review-author">{{ review.author.first_name }} {{ review.author.last_name }}</h4>
                  <p class="reviewer-achievement" v-if="review.achievement">
                    🏆 {{ review.achievement }}
                  </p>
                  <p class="review-membership">
                    Участник клуба
                  </p>
                </div>
              </div>
              <div class="review-rating">
                <div class="stars">
                  <span v-for="star in 5" :key="star" :class="['star', { 'filled': star <= review.rating }]">
                    ★
                  </span>
                </div>
                <span class="rating-value">{{ review.rating }}/5</span>
              </div>
            </div>

            <div class="review-content">
              <p class="review-text">{{ review.text }}</p>

              <div class="review-meta">
                <div class="meta-items">
                  <span class="meta-item" v-if="review.distance">
                    🏃 {{ review.distance }}
                  </span>
                  <span class="meta-item" v-if="review.improvement">
                    📈 {{ review.improvement }}
                  </span>
                  <span class="meta-item" v-if="review.trainings">
                    💪 {{ review.trainings }} тренировок
                  </span>
                </div>
                <span class="review-date">{{ formatDate(review.created_at) }}</span>
              </div>

              <div class="review-actions" v-if="review.verified">
                <span class="verified-badge">✅ Проверенный отзыв</span>
              </div>

              <!-- Действия для своих отзывов -->
              <div class="review-actions" v-if="isMyReview(review)">
                <button @click="editReview(review)" class="btn-edit">✏️ Редактировать</button>
                <button @click="deleteReview(review.id)" class="btn-delete">🗑️ Удалить</button>
              </div>
            </div>
          </div>
        </div>

        <!-- Пагинация -->
        <div class="pagination" v-if="totalPages > 1">
          <button class="pagination-btn" :disabled="currentPage === 1" @click="changePage(currentPage - 1)">
            ‹
          </button>

          <button v-for="page in visiblePages" :key="page"
            :class="['pagination-btn', { 'active': currentPage === page }]" @click="changePage(page)">
            {{ page }}
          </button>

          <button class="pagination-btn" :disabled="currentPage === totalPages" @click="changePage(currentPage + 1)">
            ›
          </button>
        </div>

        <!-- Статистика отзывов -->
        <div class="reviews-stats">
          <h3>📊 Распределение оценок</h3>
          <div class="rating-bars">
            <div v-for="rating in 5" :key="rating" class="rating-bar">
              <div class="rating-label">
                <span class="stars-small">
                  <span v-for="star in 5" :key="star" :class="['star-small', { 'filled': star <= (6 - rating) }]">
                    ★
                  </span>
                </span>
              </div>
              <div class="bar-container">
                <div class="bar-fill" :style="{ width: getRatingPercentage(6 - rating) + '%' }"></div>
              </div>
              <div class="rating-count">
                {{ getRatingCount(6 - rating) }}
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>

    <!-- Форма отзыва -->
    <section class="add-review-section" id="add-review">
      <div class="container">
        <div class="add-review-content">
          <div class="form-header">
            <h2 class="section-title">✍️ Поделитесь своим опытом</h2>
            <p>Расскажите о своих достижениях и впечатлениях от тренировок</p>
          </div>

          <form class="review-form" @submit.prevent="submitReview" v-if="!isAuthenticated">
            <div class="auth-required">
              <div class="auth-message">
                <h3>🔐 Войдите, чтобы оставить отзыв</h3>
                <p>Только участники клуба могут оставлять отзывы</p>
              </div>
              <div class="auth-actions">
                <router-link to="/login" class="btn btn-primary">
                  🔑 Войти в аккаунт
                </router-link>
                <router-link to="/register" class="btn btn-secondary">
                  🏃 Стать участником
                </router-link>
              </div>
            </div>
          </form>

          <form class="review-form" @submit.prevent="submitReview" v-else>
            <div class="form-group">
              <label>Ваша оценка *</label>
              <div class="rating-input">
                <button v-for="star in 5" :key="star" type="button"
                  :class="['star-btn', { 'active': newReview.rating >= star }]" @click="newReview.rating = star">
                  ★
                </button>
              </div>
            </div>

            <div class="form-row">
              <div class="form-group">
                <label for="achievement">Ваше достижение</label>
                <input id="achievement" v-model="newReview.achievement" type="text"
                  placeholder="Например: пробежал первый марафон">
              </div>
              <div class="form-group">
                <label for="distance">Любимая дистанция</label>
                <select id="distance" v-model="newReview.distance">
                  <option value="">Выберите дистанцию</option>
                  <option value="5 км">5 км</option>
                  <option value="10 км">10 км</option>
                  <option value="21.1 км">Полумарафон (21.1 км)</option>
                  <option value="42.2 км">Марафон (42.2 км)</option>
                  <option value="Трейл">Трейл</option>
                </select>
              </div>
            </div>

            <div class="form-group">
              <label for="review-text">Ваш отзыв *</label>
              <textarea id="review-text" v-model="newReview.text" rows="5"
                placeholder="Расскажите о вашем опыте в клубе, достижениях, атмосфере..." required></textarea>
              <div class="char-counter">
                {{ newReview.text.length }}/500 символов
              </div>
            </div>

            <div class="form-actions">
              <button type="submit" class="btn btn-primary" :disabled="!isFormValid || submitting">
                <span v-if="submitting">📤 Отправка...</span>
                <span v-else>📝 {{ editingReview ? 'Обновить отзыв' : 'Опубликовать отзыв' }}</span>
              </button>
              <button type="button" class="btn btn-outline" @click="resetForm">
                🗑️ Очистить
              </button>
            </div>
          </form>
        </div>
      </div>
    </section>

    <!-- Призыв к действию -->
    <section class="cta-section">
      <div class="container">
        <div class="cta-content">
          <h2>Готовы присоединиться к нашему сообществу?</h2>
          <p>Станьте следующей историей успеха в нашем клубе!</p>

          <div class="success-stories-preview">
            <div class="story-card">
              <div class="story-avatar">А</div>
              <div class="story-content">
                <h4>Анна</h4>
                <p>"С нуля до марафона за 1 год! Спасибо тренеру и команде!"</p>
                <span class="story-achievement">🏅 Марафон 4:20:15</span>
              </div>
            </div>
            <div class="story-card">
              <div class="story-avatar">Д</div>
              <div class="story-content">
                <h4>Данил</h4>
                <p>"Нашел друзей и улучшил результат на 10км на 15 минут"</p>
                <span class="story-achievement">⚡ 10км за 42:30</span>
              </div>
            </div>
          </div>

          <div class="cta-features">
            <div class="cta-feature">
              <div class="feature-icon">👨‍🏫</div>
              <div class="feature-text">
                <strong>Профессиональный тренер</strong>
                <span>Мастер спорта с индивидуальным подходом</span>
              </div>
            </div>
            <div class="cta-feature">
              <div class="feature-icon">👥</div>
              <div class="feature-text">
                <strong>Дружное сообщество</strong>
                <span>Поддержка и мотивация единомышленников</span>
              </div>
            </div>
            <div class="cta-feature">
              <div class="feature-icon">📈</div>
              <div class="feature-text">
                <strong>Личный прогресс</strong>
                <span>Регулярное улучшение результатов</span>
              </div>
            </div>
          </div>

          <div class="cta-actions">
            <router-link to="/training" class="btn btn-primary btn-large">
              🏃 Записаться на тренировку
            </router-link>
            <router-link to="/register" class="btn btn-secondary">
              👥 Вступить в клуб
            </router-link>
          </div>

          <div class="cta-contacts">
            <p>Есть вопросы? Свяжитесь с нами:</p>
            <div class="contact-links">
              <a href="https://t.me/begushiybashkir" class="contact-link">📱 Telegram</a>
              <a href="tel:+79273093095" class="contact-link">📞 +7 (927) 30-93-095</a>
            </div>
          </div>
        </div>
      </div>
    </section>
  </div>
</template>

<script>
import { apiClient } from '../stores/helpers/api';

export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: 'Reviews',
  data() {
    return {
      isAuthenticated: false,
      currentUser: null,
      loading: false,
      sortBy: 'newest',
      activeRatingFilter: 'all',
      currentPage: 1,
      reviewsPerPage: 6,
      totalPages: 1,
      totalItems: 0,
      submitting: false,
      editingReview: null,
      stats: {
        total_reviews: 0,
        average_rating: 0,
        success_stories: 0,
        rating_distribution: {5: 0, 4: 0, 3: 0, 2: 0, 1: 0}
      },
      ratingFilters: [
        { value: 'all', label: 'Все оценки' },
        { value: '5', label: '⭐ 5 звезд' },
        { value: '4', label: '⭐ 4+ звезды' },
        { value: '3', label: '⭐ 3+ звезды' }
      ],
      newReview: {
        rating: 0,
        text: '',
        achievement: '',
        distance: '',
        improvement: '',
        trainings: 0
      },
      reviews: [],
      // Захардкоженные отзывы как fallback
      hardcodedReviews: [
        {
          id: 1,
          author: {
            first_name: 'Данил',
            last_name: '',
            id: 1
          },
          rating: 5,
          text: 'В общем, краткие выводы и мысли от Бэкъярда: попробовать стоит, интересный опыт. Главное знать когда остановиться, чтобы потом не пришлось восстанавливаться долго. Подметил для себя 4 момента:\n- питаться надо привычной едой + соли различные, изотоник (регидрон), минералка, газировка. Горячее питание от организаторов хорошо заходило.\n- круг надо бегать в темпе 6:20-6:50, чтобы во время отдыха успевать немного восстановиться, но при этом сильно не остывать. Быстрее 06:00 если бежать, то можешь закислиться.\n- надо сразу психологию проработать, не ставить себе рамки и научиться не думать о дистанции и кругах, это реально выматывает.\n- саппорт (поддержка) нужная вещь, чтобы и массаж делать, и питание приготовить. Я был 16 кругов один, поэтому не всегда успевал нормально все делать.\n\nОтдельно хочу поблагодорить Загира, Сергея и Гаяза. Ваша помощь неоценима, пришли в самый тяжелый момент и как следует восстановили и смотивировали меня. Без вас планировал 15 (максимум 16) кругов сделать и сойти, так как мышцы уже реально "полнаелись". А так сделал 18 кругов и потенциально мог ещё 2 круга пробежать.\nЕщё хочу поблагодарить Марата, который оказывал психологическую поддержку.\nПарни, спасибо Вам большое.\n\nПриехал домой, умылся, чай попил, теперь восстанавливаться🤝',
          achievement: '18 кругов на Бэкъярде',
          distance: 'Ультрамарафон',
          improvement: 'Преодоление психологических барьеров',
          trainings: 50,
          verified: true,
          created_at: '2024-06-15T10:00:00Z'
        },
        {
          id: 2,
          author: {
            first_name: 'Айгуль',
            last_name: '',
            id: 2
          },
          rating: 5,
          text: 'У всех результаты, марафоны, цели, темпы….но а я просто любитель🤗\nВчера, как всегда, было весело, душевно, уютно, комфортно. Мой результат на 5 км для многих из вас - это просто пешком пройти😁 Даже если так, я очень довольна собой, что за день до марафона решилась идти, ведь я была в центре уфимских событий! Кстати, это была моя давняя мечта пробежать именно этот сентябрьский марафон✨ Но долгое отсутствие тренировок дало о себе знать, бежала тяжело(\nНезабываемые ощущения, эмоции от нашей точки поддержки - где мы уже по ту сторону стоим и поддерживаем бегунов - башкирская музыка, танцы, кумыс… и это круто!\nСпасибо тренеру, однокласснику, что он уговорил меня как-то прийти и попробовать в его клуб, долго откладывала это событие)\nСпасибо Всем вам, смотря на вас хочется лучше результаты и брать еще большие км, возможно когда-нибудь🙈🌝\nЗавершение вечера в MusicHall просто 🔥❤️',
          achievement: 'Первый забег 5 км',
          distance: '5 км',
          improvement: 'Преодоление страха перед стартом',
          trainings: 12,
          verified: true,
          created_at: '2024-09-10T14:30:00Z'
        },
        {
          id: 3,
          author: {
            first_name: 'Гаяз',
            last_name: 'Давлетбеков',
            id: 3
          },
          rating: 5,
          text: '🏃‍♂️🔥 «Белые Ночи – 3:34:33! Как Башкир сбросил час и покорил Питер» 🔥🏃‍♂️\n\n21 ноября 2024 я написал Загиру: «Хочу из 4х».\n5 июля 2025 я финишировал с 3:34:33 — и до сих пор не верю!\n\nЭто не просто личный рекорд. Это революция.\nС 4:45 на Московском марафоне до 3:34 в Петербурге – за 8 месяцев.\nМинус 71 минута – вот что значит правильный тренер, команда и… бурек!\n\n---\n\nКто помогал лететь:\n✊ Загир – тренер, который верил, даже когда я сам сомневался.\n💪 Сергей – друг-соперник, который не давал расслабляться (спасибо за «гонку» на тренировках!).\n👊 Вся семья «Бегущего Башкира» – без вас этот результат был бы просто цифрой.\n\n-Секреты успеха:\n✅ Образ «Бегущего Башкира»– бүрек + фирменная футболка = мощнейшая поддержка трибун. Казахи кричали «Жарайсың!», русские – «Давай, Башкир!», а я просто бежал и чувствовал силу предков которые передовались от их слов.\n✅ Тактика: Первые 30 км – как часы, последние 12 – как воин.\n✅ Питер – бежал по Дворцовому мосту, дышал невским ветром и ловил взгляды на стрелке Васильевского.\n\nФинишные эмоции:\nКогда увидел часы с 3:34 – понял: «Это не сон».\nЗагир сказал: «Ты мог бы и 3:30» – но я знаю, это только начало.\n\nСледующая цель? Может, Казань или Москва – но точно с бүреком на голове!\n\n### Благодарности:\n📣 Зрителям – ваши крики «Башкир, давай!» грели даже под питерским дождём.\n🏙️ Городу – ты сказочный, и твои мосты стали лучшими «подъёмами» на дистанции.\n🏆 Себе – за то, что не сдался, когда было тяжело.\n\nP.S. Теперь я знаю: «Невозможное» – это просто слово. Главное – найти свою команду и свой образ.\n\n*(Прикрепляю фото с финиша – лицо счастья и бүрек, переживший все 42 км!)* 😍🎽\n\n---\nP.P.S. Загир, готовь новый план – теперь мы летим за 3:20! 🚀',
          achievement: 'Марафон 3:34:33',
          distance: '42.2 км',
          improvement: 'Улучшение на 71 минуту',
          trainings: 120,
          verified: true,
          created_at: '2025-07-05T18:15:00Z'
        },
        {
          id: 4,
          author: {
            first_name: 'Камила',
            last_name: '',
            id: 4
          },
          rating: 5,
          text: 'Ғаяз, Айгөл, Ринат ҙуууур рәхмәт шундай байрам өсөн! Өҫтәл мул булды 👍🔥шулай ҡыҙыҡ тыуған көндәрегеҙ бер ваҡытта, тигәндәй! Ә хәҙер бер командалаһығыҙ! Гел шулай сағыу, мул, дәртле тормош алып барығыҙ! Һеҙ - Афариндар!!! 💪🤝🔥😎🔥',
          achievement: 'Активная участница мероприятий',
          distance: '5 км',
          improvement: 'Участие в командных забегах',
          trainings: 25,
          verified: true,
          created_at: '2024-08-20T09:45:00Z'
        },
        {
          id: 5,
          author: {
            first_name: 'Зарема',
            last_name: '',
            id: 5
          },
          rating: 4,
          text: 'Мне тоже очень понравилось!\nИ азарт появился\nНа след год тоже надо участвовать обязательно.\n\nКлассное окружение, все заряженные.\nСпасибо всем за эту атмосферу!\nИ благодарность тренеру, конечно ❤️\n\nСпасибо большое за угощения вкусные именинникам.\nВсех еще раз поздравляю 🥳',
          achievement: 'Участница клубных мероприятий',
          distance: '10 км',
          improvement: 'Регулярное участие в забегах',
          trainings: 30,
          verified: true,
          created_at: '2024-07-12T16:20:00Z'
        }
      ],
      useHardcodedData: false // Флаг для использования захардкоженных данных
    }
  },
  computed: {
    visiblePages() {
      const pages = []
      const startPage = Math.max(1, this.currentPage - 2)
      const endPage = Math.min(this.totalPages, startPage + 4)

      for (let i = startPage; i <= endPage; i++) {
        pages.push(i)
      }
      return pages
    },
    isFormValid() {
      return this.newReview.rating > 0 &&
        this.newReview.text.length >= 10 &&
        this.newReview.text.length <= 500
    }
  },
  methods: {
    handleFirstInteraction() {
      if (!this.hasInteracted) {
        this.hasInteracted = true
        this.showContent()
        clearTimeout(this.autoShowTimeout)
      }
    },
    showContent() {
      this.isContentVisible = true
      this.$emit('show-header')
    },

    async loadReviews() {
      this.loading = true
      try {
        const params = {
          page: this.currentPage,
          limit: this.reviewsPerPage,
          sort: this.sortBy,
          filter: this.activeRatingFilter === 'all' ? '' : this.activeRatingFilter
        }

        // Удаляем пустые параметры
        Object.keys(params).forEach(key => {
          if (params[key] === '' || params[key] === null || params[key] === undefined) {
            delete params[key]
          }
        })

        const response = await apiClient.get('/reviews', { params })
        
        if (response.data.reviews && response.data.reviews.length > 0) {
          // Используем данные из API
          this.reviews = response.data.reviews || []
          this.totalPages = response.data.total_pages || 1
          this.totalItems = response.data.total_items || 0
          this.currentPage = response.data.current_page || 1
          this.useHardcodedData = false
        } else {
          // Если API вернуло пустой ответ, используем захардкоженные данные
          this.useHardcodedFallback('reviews')
        }
      } catch (error) {
        console.error('Ошибка при загрузке отзывов:', error)
        // При ошибке используем захардкоженные данные
        this.useHardcodedFallback('reviews')
        this.showNotification('error', 'Ошибка', 'Не удалось загрузить отзывы. Показаны демо-данные.')
      } finally {
        this.loading = false
      }
    },

    async loadStats() {
      try {
        const response = await apiClient.get('/reviews/stats')
        if (response.data) {
          this.stats = response.data
          this.useHardcodedData = false
        } else {
          this.useHardcodedFallback('stats')
        }
      } catch (error) {
        console.error('Ошибка при загрузке статистики:', error)
        // Используем захардкоженную статистику при ошибке
        this.useHardcodedFallback('stats')
      }
    },

    useHardcodedFallback(type) {
      this.useHardcodedData = true
      
      if (type === 'reviews') {
        let filteredReviews = [...this.hardcodedReviews];
        
        // Применяем фильтрацию по рейтингу
        if (this.activeRatingFilter !== 'all') {
          const minRating = parseInt(this.activeRatingFilter);
          filteredReviews = filteredReviews.filter(review => review.rating >= minRating);
        }
        
        // Применяем сортировку
        switch (this.sortBy) {
          case 'newest':
            filteredReviews.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
            break;
          case 'oldest':
            filteredReviews.sort((a, b) => new Date(a.created_at) - new Date(b.created_at));
            break;
          case 'highest':
            filteredReviews.sort((a, b) => b.rating - a.rating);
            break;
          case 'lowest':
            filteredReviews.sort((a, b) => a.rating - b.rating);
            break;
        }
        
        // Пагинация
        const startIndex = (this.currentPage - 1) * this.reviewsPerPage;
        const endIndex = startIndex + this.reviewsPerPage;
        
        this.reviews = filteredReviews.slice(startIndex, endIndex);
        this.totalItems = filteredReviews.length;
        this.totalPages = Math.ceil(filteredReviews.length / this.reviewsPerPage);
        
      } else if (type === 'stats') {
        // Рассчитываем статистику на основе захардкоженных отзывов
        const totalReviews = this.hardcodedReviews.length;
        const averageRating = this.hardcodedReviews.reduce((sum, review) => sum + review.rating, 0) / totalReviews;
        const successStories = this.hardcodedReviews.filter(review => review.achievement).length;
        
        const ratingDistribution = {5: 0, 4: 0, 3: 0, 2: 0, 1: 0};
        this.hardcodedReviews.forEach(review => {
          ratingDistribution[review.rating]++;
        });
        
        this.stats = {
          total_reviews: totalReviews,
          average_rating: Math.round(averageRating * 10) / 10,
          success_stories: successStories,
          rating_distribution: ratingDistribution
        };
      }
    },

    async checkAuth() {
      try {
        const token = localStorage.getItem('auth_token')
        if (token) {
          try {
            const response = await apiClient.get('/user/profile')
            this.isAuthenticated = true
            this.currentUser = response.data
          } catch (error) {
            console.error('Токен невалиден:', error)
            this.handleAuthError()
          }
        } else {
          this.isAuthenticated = false
          this.currentUser = null
        }
      } catch (error) {
        console.error('Ошибка проверки авторизации:', error)
        this.handleAuthError()
      }
    },

    handleAuthError() {
      this.isAuthenticated = false
      this.currentUser = null
      localStorage.removeItem('auth_token')
    },

    getInitials(author) {
      if (!author) return '?'
      const firstName = author.first_name || ''
      const lastName = author.last_name || ''
      return (firstName.charAt(0) + lastName.charAt(0)).toUpperCase() || '?'
    },

    getReviewCardClass(rating) {
      return `rating-${rating}`
    },

    formatDate(dateString) {
      try {
        const date = new Date(dateString)
        return date.toLocaleDateString('ru-RU', {
          day: 'numeric',
          month: 'long',
          year: 'numeric'
        })
      } catch (error) {
        console.log(error)
        return 'Неизвестная дата'
      }
    },

    filterByRating(rating) {
      this.activeRatingFilter = rating
      this.currentPage = 1
      this.loadReviews()
    },

    changePage(page) {
      if (page >= 1 && page <= this.totalPages) {
        this.currentPage = page
        this.loadReviews()
        window.scrollTo({ top: 0, behavior: 'smooth' })
      }
    },

    getRatingCount(rating) {
      return this.stats.rating_distribution?.[rating] || 0
    },

    getRatingPercentage(rating) {
      const count = this.getRatingCount(rating)
      const total = this.stats.total_reviews || 1
      return (count / total) * 100
    },

    isMyReview(review) {
      return this.isAuthenticated && 
             this.currentUser && 
             review.author && 
             review.author.id === this.currentUser.id
    },

    async submitReview() {
      if (!this.isFormValid) {
        this.showNotification('error', 'Ошибка', 'Пожалуйста, заполните все обязательные поля правильно')
        return
      }

      this.submitting = true

      try {
        const reviewData = {
          rating: this.newReview.rating,
          text: this.newReview.text,
          achievement: this.newReview.achievement,
          distance: this.newReview.distance,
          improvement: this.newReview.improvement,
          trainings: this.newReview.trainings
        }

        if (this.editingReview) {
          // Редактирование существующего отзыва
          await apiClient.put(`/reviews/${this.editingReview.id}`, reviewData)
          this.showNotification('success', 'Успех', 'Отзыв успешно обновлен!')
          this.editingReview = null
        } else {
          // Создание нового отзыва
          await apiClient.post('/reviews', reviewData)
          this.showNotification('success', 'Успех', 'Спасибо за ваш отзыв! После проверки модератором он будет опубликован.')
        }

        this.resetForm()
        this.loadReviews()
        this.loadStats()

      } catch (error) {
        console.error('Ошибка при отправке отзыва:', error)
        let errorMessage = 'Произошла ошибка при отправке отзыва. Попробуйте еще раз.'
        
        if (error.response?.status === 401) {
          errorMessage = 'Необходимо авторизоваться для отправки отзыва'
          this.handleAuthError()
        } else if (error.response?.status === 403) {
          errorMessage = 'У вас нет прав для выполнения этого действия'
        } else if (error.response?.data?.message) {
          errorMessage = error.response.data.message
        }
        
        this.showNotification('error', 'Ошибка', errorMessage)
      } finally {
        this.submitting = false
      }
    },

    async editReview(review) {
      this.editingReview = review
      this.newReview = {
        rating: review.rating,
        text: review.text,
        achievement: review.achievement || '',
        distance: review.distance || '',
        improvement: review.improvement || '',
        trainings: review.trainings || 0
      }
      
      document.getElementById('add-review').scrollIntoView({ 
        behavior: 'smooth' 
      })
    },

    async deleteReview(reviewId) {
      if (!confirm('Вы уверены, что хотите удалить этот отзыв?')) {
        return
      }

      try {
        await apiClient.delete(`/reviews/${reviewId}`)

        this.loadReviews()
        this.loadStats()

        this.showNotification('success', 'Успех', 'Отзыв успешно удален')

      } catch (error) {
        console.error('Ошибка при удалении отзыва:', error)
        let errorMessage = 'Не удалось удалить отзыв'
        
        if (error.response?.status === 403) {
          errorMessage = 'Вы можете удалять только свои отзывы'
        } else if (error.response?.status === 401) {
          errorMessage = 'Необходимо авторизоваться'
          this.handleAuthError()
        } else if (error.response?.data?.message) {
          errorMessage = error.response.data.message
        }
        
        this.showNotification('error', 'Ошибка', errorMessage)
      }
    },

    resetForm() {
      this.newReview = {
        rating: 0,
        text: '',
        achievement: '',
        distance: '',
        improvement: '',
        trainings: 0
      }
      this.editingReview = null
    },

    showNotification(type, title, text) {
      if (this.$notify) {
        this.$notify({
          type: type,
          title: title,
          text: text
        })
      } else {
        const notification = document.createElement('div')
        notification.className = `notification notification-${type}`
        notification.innerHTML = `
          <strong>${title}</strong>
          <p>${text}</p>
        `
        document.body.appendChild(notification)
        
        setTimeout(() => {
          if (notification.parentNode) {
            document.body.removeChild(notification)
          }
        }, 5000)
      }
    }
  },
  mounted() {
    window.addEventListener('scroll', this.handleFirstInteraction, { passive: true, once: true })
    window.addEventListener('click', this.handleFirstInteraction, { once: true })
    window.addEventListener('touchstart', this.handleFirstInteraction, { once: true })
    this.autoShowTimeout = setTimeout(() => {
      if (!this.hasInteracted) {
        this.showContent()
      }
    }, 3000)
    this.checkAuth()
    this.loadReviews()
    this.loadStats()
  },
  beforeUnmount() {
    window.removeEventListener('scroll', this.handleFirstInteraction)
    window.removeEventListener('click', this.handleFirstInteraction)
    window.removeEventListener('touchstart', this.handleFirstInteraction)
    clearTimeout(this.autoShowTimeout)
  },
  watch: {
    sortBy() {
      this.currentPage = 1
      this.loadReviews()
    },
    activeRatingFilter() {
      this.currentPage = 1
      this.loadReviews()
    }
  }
}
</script>

<style scoped>

.notification {
  position: fixed;
  top: 20px;
  right: 20px;
  padding: 1rem 1.5rem;
  border-radius: 8px;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
  z-index: 1000;
  animation: slideInRight 0.3s ease;
  max-width: 400px;
}

.notification-success {
  background: #27ae60;
  color: white;
}

.notification-error {
  background: #e74c3c;
  color: white;
}

.notification-warning {
  background: #f39c12;
  color: white;
}

.notification-info {
  background: #3498db;
  color: white;
}

@keyframes slideInRight {
  from {
    transform: translateX(100%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

/* Остальные стили остаются такими же как в вашем файле */
.loading {
  text-align: center;
  padding: 3rem;
}

.spinner {
  border: 4px solid #f3f3f3;
  border-top: 4px solid #2e8b57;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  animation: spin 2s linear infinite;
  margin: 0 auto 1rem;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.no-reviews {
  text-align: center;
  padding: 3rem;
  color: #666;
}

.btn-edit,
.btn-delete {
  background: none;
  border: none;
  color: #2e8b57;
  cursor: pointer;
  font-size: 0.8rem;
  margin-right: 1rem;
}

.btn-delete {
  color: #e74c3c;
}

.btn-edit:hover {
  text-decoration: underline;
}

.btn-delete:hover {
  text-decoration: underline;
}


.notification {
  position: fixed;
  top: 20px;
  right: 20px;
  padding: 1rem 1.5rem;
  border-radius: 8px;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
  z-index: 1000;
  animation: slideInRight 0.3s ease;
  max-width: 400px;
}

.notification-success {
  background: #27ae60;
  color: white;
}

.notification-error {
  background: #e74c3c;
  color: white;
}

.notification-warning {
  background: #f39c12;
  color: white;
}

.notification-info {
  background: #3498db;
  color: white;
}

@keyframes slideInRight {
  from {
    transform: translateX(100%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

/* Остальные стили остаются такими же как в вашем файле */
.loading {
  text-align: center;
  padding: 3rem;
}

.spinner {
  border: 4px solid #f3f3f3;
  border-top: 4px solid #2e8b57;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  animation: spin 2s linear infinite;
  margin: 0 auto 1rem;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.no-reviews {
  text-align: center;
  padding: 3rem;
  color: #666;
}

.btn-edit,
.btn-delete {
  background: none;
  border: none;
  color: #2e8b57;
  cursor: pointer;
  font-size: 0.8rem;
  margin-right: 1rem;
}

.btn-delete {
  color: #e74c3c;
}

.btn-edit:hover {
  text-decoration: underline;
}

.btn-delete:hover {
  text-decoration: underline;
}
.loading {
  text-align: center;
  padding: 3rem;
}

.spinner {
  border: 4px solid #f3f3f3;
  border-top: 4px solid #2e8b57;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  animation: spin 2s linear infinite;
  margin: 0 auto 1rem;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

.no-reviews {
  text-align: center;
  padding: 3rem;
  color: #666;
}

.btn-edit,
.btn-delete {
  background: none;
  border: none;
  color: #2e8b57;
  cursor: pointer;
  font-size: 0.8rem;
  margin-right: 1rem;
}

.btn-delete {
  color: #e74c3c;
}

.btn-edit:hover {
  text-decoration: underline;
}

.btn-delete:hover {
  text-decoration: underline;
}

.reviews-page {
  min-height: 100vh;
  background: linear-gradient(135deg, #f8fff8 0%, #f0f8f0 100%);
}

/* Герой-секция */
.hero-section {
  background: linear-gradient(135deg, #2e8b57 0%, #26734a 100%);
  color: white;
  padding: 80px 0 60px;
  text-align: center;
}

.hero-title {
  font-size: 3rem;
  margin-bottom: 1rem;
  font-weight: 800;
}

.hero-subtitle {
  font-size: 1.3rem;
  opacity: 0.9;
  margin-bottom: 2rem;
}

.hero-stats {
  display: flex;
  justify-content: center;
  gap: 3rem;
  flex-wrap: wrap;
}

.stat {
  text-align: center;
}

.stat-number {
  font-size: 2.5rem;
  font-weight: 800;
  color: #ffd700;
  margin-bottom: 0.5rem;
}

.stat-label {
  font-size: 0.9rem;
  opacity: 0.8;
}

/* Основные стили */
.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 20px;
}

.section-title {
  font-size: 2.5rem;
  color: #2e8b57;
  margin-bottom: 1rem;
  font-weight: 700;
}

/* Заголовок отзывов */
.reviews-header {
  margin-bottom: 3rem;
}

.reviews-controls {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 2rem;
}

.sort-controls {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.sort-controls label {
  font-weight: 600;
  color: #333;
}

.sort-controls select {
  padding: 8px 12px;
  border: 2px solid #e9ecef;
  border-radius: 8px;
  background: white;
  cursor: pointer;
}

.filter-controls {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.filter-btn {
  padding: 8px 16px;
  border: 2px solid #e9ecef;
  background: white;
  border-radius: 20px;
  cursor: pointer;
  transition: all 0.3s ease;
  font-size: 0.9rem;
}

.filter-btn:hover {
  border-color: #2e8b57;
}

.filter-btn.active {
  background: #2e8b57;
  color: white;
  border-color: #2e8b57;
}

/* Сетка отзывов */
.reviews-section {
  padding: 4rem 0;
}

.reviews-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
  gap: 2rem;
  margin-bottom: 3rem;
}

.review-card {
  background: white;
  border-radius: 15px;
  padding: 2rem;
  box-shadow: 0 5px 20px rgba(0, 0, 0, 0.08);
  transition: all 0.3s ease;
  border: 2px solid transparent;
}

.review-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
}

/* Стили по рейтингу */
.review-card.rating-5 {
  border-color: #ffd700;
  background: linear-gradient(135deg, #fff9e6 0%, #fff3cc 100%);
}

.review-card.rating-4 {
  border-color: #a8e6cf;
  background: linear-gradient(135deg, #f0f8f0 0%, #e8f5e9 100%);
}

.review-card.rating-3 {
  border-color: #ffd8b2;
  background: linear-gradient(135deg, #fff3e0 0%, #ffe0b2 100%);
}

.review-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 1.5rem;
}

.reviewer-info {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
}

.reviewer-avatar {
  width: 50px;
  height: 50px;
  background: #2e8b57;
  color: white;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  font-size: 1.2rem;
  flex-shrink: 0;
}

.review-author {
  color: #2e8b57;
  margin: 0 0 0.3rem 0;
  font-size: 1.2rem;
}

.reviewer-achievement {
  color: #e74c3c;
  font-weight: 600;
  font-size: 0.9rem;
  margin: 0 0 0.3rem 0;
}

.review-membership {
  color: #666;
  font-size: 0.8rem;
  margin: 0;
}

.review-rating {
  text-align: right;
}

.stars {
  display: flex;
  gap: 2px;
  margin-bottom: 0.5rem;
  justify-content: flex-end;
}

.star {
  color: #ddd;
  font-size: 1.2rem;
}

.star.filled {
  color: #ffd700;
}

.rating-value {
  font-weight: bold;
  color: #333;
  font-size: 1.1rem;
}

.review-content {
  display: flex;
  flex-direction: column;
  gap: 1.5rem; /* Современный способ для Flexbox */
}

.review-text {
  line-height: 1.6;
  color: #333;
  margin-bottom: 1.5rem;
}

.review-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1rem;
}

.meta-items {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
}

.meta-item {
  background: rgba(46, 139, 87, 0.1);
  color: #2e8b57;
  padding: 0.3rem 0.8rem;
  border-radius: 15px;
  font-size: 0.8rem;
  font-weight: 600;
}

.review-date {
  color: #666;
  font-size: 0.9rem;
}

.review-actions {
  border-top: 1px solid #e9ecef;
  padding-top: 1rem;
}

.verified-badge {
  color: #27ae60;
  font-size: 0.8rem;
  font-weight: 600;
}

/* Пагинация */
.pagination {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin: 3rem 0;
}

.pagination-btn {
  padding: 10px 15px;
  border: 2px solid #e9ecef;
  background: white;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s ease;
  font-weight: 600;
}

.pagination-btn:hover:not(:disabled) {
  border-color: #2e8b57;
  background: #f8fff8;
}

.pagination-btn.active {
  background: #2e8b57;
  color: white;
  border-color: #2e8b57;
}

.pagination-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Статистика оценок */
.reviews-stats {
  background: white;
  padding: 2rem;
  border-radius: 15px;
  box-shadow: 0 5px 20px rgba(0, 0, 0, 0.08);
  margin-bottom: 3rem;
}

.reviews-stats h3 {
  color: #2e8b57;
  margin-bottom: 1.5rem;
  text-align: center;
}

.rating-bars {
  max-width: 400px;
  margin: 0 auto;
}

.rating-bar {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 0.8rem;
}

.rating-label {
  width: 80px;
}

.stars-small {
  display: flex;
  gap: 1px;
}

.star-small {
  color: #ddd;
  font-size: 0.8rem;
}

.star-small.filled {
  color: #ffd700;
}

.bar-container {
  flex: 1;
  height: 8px;
  background: #e9ecef;
  border-radius: 4px;
  overflow: hidden;
}

.bar-fill {
  height: 100%;
  background: #2e8b57;
  border-radius: 4px;
  transition: width 0.5s ease;
}

.rating-count {
  width: 30px;
  text-align: right;
  font-weight: 600;
  color: #333;
}

/* Форма отзыва */
.add-review-section {
  background: white;
  padding: 4rem 0;
  border-top: 1px solid #e9ecef;
}

.add-review-content {
  max-width: 600px;
  margin: 0 auto;
}

.form-header {
  text-align: center;
  margin-bottom: 3rem;
}

.form-header p {
  color: #666;
  font-size: 1.1rem;
}

.review-form {
  background: #f5fdf5;
  padding: 2rem;
  border-radius: 15px;
  border: 2px solid #e9ecef;
}

.auth-required {
  text-align: center;
  padding: 2rem;
}

.auth-message {
  margin-bottom: 2rem;
}

.auth-message h3 {
  color: #2e8b57;
  margin-bottom: 1rem;
}

.auth-actions {
  display: flex;
  gap: 1rem;
  justify-content: center;
  flex-wrap: wrap;
}

.form-group {
  margin-bottom: 1.5rem;
}

.form-group label {
  display: block;
  margin-bottom: 0.5rem;
  font-weight: 600;
  color: #333;
}

.rating-input {
  display: flex;
  gap: 0.5rem;
}

.star-btn {
  background: none;
  border: none;
  font-size: 2rem;
  color: #ddd;
  cursor: pointer;
  transition: all 0.2s ease;
  padding: 0.2rem;
}

.star-btn.active {
  color: #ffd700;
  transform: scale(1.1);
}

.star-btn:hover {
  transform: scale(1.2);
}

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

.form-group input,
.form-group select,
.form-group textarea {
  width: 100%;
  padding: 12px 15px;
  border: 2px solid #e9ecef;
  border-radius: 8px;
  font-size: 1rem;
  transition: border-color 0.3s ease;
  font-family: inherit;
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  outline: none;
  border-color: #2e8b57;
}

.char-counter {
  text-align: right;
  font-size: 0.8rem;
  color: #666;
  margin-top: 0.5rem;
}

.form-actions {
  display: flex;
  gap: 1rem;
  justify-content: center;
  flex-wrap: wrap;
}

/* CTA секция */
.cta-section {
  background: linear-gradient(135deg, #2e8b57 0%, #26734a 100%);
  color: white;
  padding: 80px 0;
  text-align: center;
}

.cta-content h2 {
  font-size: 2.5rem;
  margin-bottom: 1rem;
}

.cta-content p {
  font-size: 1.2rem;
  opacity: 0.9;
  margin-bottom: 3rem;
}

.success-stories-preview {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1.5rem;
  margin-bottom: 3rem;
  max-width: 600px;
  margin-left: auto;
  margin-right: auto;
}

.story-card {
  background: rgba(255, 255, 255, 0.1);
  padding: 1.5rem;
  border-radius: 10px;
  backdrop-filter: blur(10px);
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  text-align: left;
}

.story-avatar {
  width: 40px;
  height: 40px;
  background: #ffd700;
  color: #333;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  flex-shrink: 0;
}

.story-content h4 {
  margin: 0 0 0.5rem 0;
  color: white;
}

.story-content p {
  font-size: 0.9rem;
  opacity: 0.9;
  margin: 0 0 0.5rem 0;
  line-height: 1.4;
}

.story-achievement {
  color: #ffd700;
  font-size: 0.8rem;
  font-weight: 600;
}

.cta-features {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 2rem;
  margin-bottom: 3rem;
  max-width: 800px;
  margin-left: auto;
  margin-right: auto;
}

.cta-feature {
  display: flex;
  align-items: center;
  gap: 1rem;
  text-align: left;
}

.feature-icon {
  font-size: 2.5rem;
  flex-shrink: 0;
}

.feature-text {
  display: flex;
  flex-direction: column;
}

.feature-text strong {
  font-size: 1.1rem;
  margin-bottom: 0.3rem;
}

.feature-text span {
  opacity: 0.8;
  font-size: 0.9rem;
}

.cta-actions {
  display: flex;
  gap: 1rem;
  justify-content: center;
  flex-wrap: wrap;
  margin-bottom: 2rem;
}

.cta-contacts p {
  margin-bottom: 1rem;
  opacity: 0.8;
}

.contact-links {
  display: flex;
  gap: 1.5rem;
  justify-content: center;
  flex-wrap: wrap;
}

.contact-link {
  color: #ffd700;
  text-decoration: none;
  font-weight: 600;
  transition: opacity 0.3s ease;
}

.contact-link:hover {
  opacity: 0.8;
}

/* Кнопки */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 12px 24px;
  border-radius: 50px;
  text-decoration: none;
  font-weight: 600;
  transition: all 0.3s ease;
  border: 2px solid transparent;
  gap: 0.5rem;
  font-size: 1rem;
  cursor: pointer;
}

.btn-primary {
  background: #ffd700;
  color: #333;
}

.btn-primary:hover {
  background: #e6c200;
  transform: translateY(-2px);
}

.btn-secondary {
  background: transparent;
  color: rgb(162, 224, 198); /* Белый текст */
  border-color: white; /* Белая рамка */
}

.btn-secondary:hover {
  background: white;
  color: #2e8b57; /* Зеленый текст при hover */
  transform: translateY(-2px);
}

.btn-outline {
  background: transparent;
  color: #2e8b57;
  border-color: #2e8b57;
}

.btn-outline:hover {
  background: #2e8b57;
  color: white;
  transform: translateY(-2px);
}

.btn-large {
  padding: 15px 30px;
  font-size: 1.1rem;
}

.btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none !important;
}

/* Адаптивность */
@media (max-width: 768px) {
  .hero-title {
    font-size: 2.2rem;
  }

  .hero-stats {
    gap: 2rem;
  }

  .stat-number {
    font-size: 2rem;
  }

  .reviews-controls {
    flex-direction: column;
    align-items: stretch;
  }

  .sort-controls {
    justify-content: space-between;
  }

  .filter-controls {
    justify-content: center;
  }

  .reviews-grid {
    grid-template-columns: 1fr;
  }

  .form-row {
    grid-template-columns: 1fr;
  }

  .review-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 1rem;
  }

  .review-rating {
    align-self: flex-end;
  }

  .success-stories-preview {
    grid-template-columns: 1fr;
  }

  .cta-features {
    grid-template-columns: 1fr;
  }

  .cta-actions {
    flex-direction: column;
    align-items: center;
  }

  .btn {
    width: 100%;
    max-width: 300px;
  }

  .auth-actions {
    flex-direction: column;
  }
}

@media (max-width: 480px) {
  .hero-section {
    padding: 60px 0 40px;
  }

  .hero-title {
    font-size: 1.8rem;
  }

  .section-title {
    font-size: 2rem;
  }

  .container {
    padding: 0 15px;
  }

  .review-card {
    padding: 1.5rem;
  }

  .reviewer-info {
    flex-direction: column;
    text-align: center;
  }

  .reviewer-avatar {
    align-self: center;
  }

  .review-meta {
    flex-direction: column;
    gap: 1rem;
    align-items: flex-start;
  }

  .meta-items {
    flex-direction: column;
    gap: 0.5rem;
  }
}

/* Анимации */
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.review-card {
  animation: fadeInUp 0.6s ease;
}

@keyframes pulse {
  0% {
    transform: scale(1);
  }

  50% {
    transform: scale(1.05);
  }

  100% {
    transform: scale(1);
  }
}

.star-btn:hover {
  animation: pulse 0.3s ease;
}

/* Задержки для анимаций карточек */
.review-card:nth-child(odd) {
  animation-delay: 0.1s;
}

.review-card:nth-child(even) {
  animation-delay: 0.2s;
}

/* Состояния загрузки */
.loading {
  opacity: 0.6;
  pointer-events: none;
}

/* Улучшения доступности */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* Фокус-стили */
button:focus-visible,
a:focus-visible,
select:focus-visible,
input:focus-visible,
textarea:focus-visible {
  outline: 2px solid #2e8b57;
  outline-offset: 2px;
}

/* Кастомный скроллбар */
.reviews-section::-webkit-scrollbar {
  width: 8px;
}

.reviews-section::-webkit-scrollbar-track {
  background: #f1f1f1;
}

.reviews-section::-webkit-scrollbar-thumb {
  background: #2e8b57;
  border-radius: 4px;
}

.reviews-section::-webkit-scrollbar-thumb:hover {
  background: #26734a;
}

/* Утилитарные классы */
.text-center {
  text-align: center;
}

.mb-2 {
  margin-bottom: 2rem;
}

.mt-2 {
  margin-top: 2rem;
}

/* Состояния валидации формы */
.form-group.error input,
.form-group.error textarea,
.form-group.error select {
  border-color: #e74c3c;
}

.error-message {
  color: #e74c3c;
  font-size: 0.8rem;
  margin-top: 0.5rem;
}

/* Уведомления */
.notification {
  position: fixed;
  top: 20px;
  right: 20px;
  background: #27ae60;
  color: white;
  padding: 1rem 1.5rem;
  border-radius: 8px;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
  z-index: 1000;
  animation: slideInRight 0.3s ease;
}

@keyframes slideInRight {
  from {
    transform: translateX(100%);
    opacity: 0;
  }

  to {
    transform: translateX(0);
    opacity: 1;
  }
}

/* Адаптация для печати */
@media print {

  .hero-section,
  .add-review-section,
  .cta-section,
  .review-actions,
  .pagination {
    display: none;
  }

  .review-card {
    break-inside: avoid;
    box-shadow: none;
    border: 1px solid #ddd;
  }
}

</style>