/* Reviews */

function ReviewStars({ value, compact = false }) {
  const rating = Math.max(0, Math.min(5, Number(value) || 0));
  return (
    <div className={`review-stars ${compact ? 'is-compact' : ''}`} aria-label={`${rating} из 5`}>
      {[1, 2, 3, 4, 5].map((star) => (
        <span key={star} className={star <= rating ? 'is-on' : ''}>★</span>
      ))}
    </div>
  );
}

function RatingInput({ value, onChange }) {
  return (
    <div className="rating-input" role="radiogroup" aria-label="Оценка">
      {[1, 2, 3, 4, 5].map((star) => (
        <button
          key={star}
          type="button"
          className={`rating-star ${star <= value ? 'is-on' : ''}`}
          onClick={() => onChange(star)}
          aria-checked={star === value}
          role="radio"
        >
          ★
        </button>
      ))}
    </div>
  );
}

function ReviewsPanel({ serviceSlug = '', serviceTitle = '' }) {
  const data = window.__PUBLIC_DATA__ || {};
  const services = data.services || [];
  const allReviews = data.reviews || [];
  const initialReviews = serviceSlug
    ? allReviews.filter((review) => review.service_slug === serviceSlug)
    : allReviews;
  const defaultService = serviceSlug || services[0]?.slug || '';

  const [reviews, setReviews] = React.useState(initialReviews);
  const [rating, setRating] = React.useState(5);
  const [selectedService, setSelectedService] = React.useState(defaultService);
  const [error, setError] = React.useState('');
  const [sent, setSent] = React.useState(false);
  const fileRef = React.useRef(null);

  React.useEffect(() => {
    setReviews(serviceSlug ? allReviews.filter((review) => review.service_slug === serviceSlug) : allReviews);
    setSelectedService(serviceSlug || services[0]?.slug || '');
  }, [serviceSlug]);

  const handleSubmit = async (event) => {
    event.preventDefault();
    setError('');
    setSent(false);

    const form = event.currentTarget;
    const payload = new FormData(form);
    payload.set('rating', String(rating));
    payload.set('service_slug', serviceSlug || selectedService);

    try {
      const response = await fetch('/reviews/', {
        method: 'POST',
        body: payload,
        credentials: 'same-origin',
      });
      const body = await response.json();
      if (!response.ok || !body.ok) {
        const message = Object.values(body.errors || {}).join(' ') || 'Не получилось отправить отзыв.';
        throw new Error(message);
      }

      if (body.review) {
        setReviews((current) => [body.review, ...current]);
      }
      setSent(true);
      setRating(5);
      form.reset();
      if (fileRef.current) fileRef.current.value = '';
      window.setTimeout(() => setSent(false), 4000);
    } catch (err) {
      setError(err.message || 'Не получилось отправить отзыв.');
    }
  };

  return (
    <section id={serviceSlug ? 'service-reviews' : 'reviews'} className="reviews-section">
      <div className="container">
        <div className="reviews-head">
          <div>
            <Reveal as="div" className="section-label">// отзывы</Reveal>
            <Reveal as="h2" className="section-title" delay={60}>
              {serviceSlug ? <>Отзывы <em>по услуге</em></> : <>Отзывы <em>клиентов</em></>}
            </Reveal>
            <Reveal as="p" className="section-lead" delay={120}>
              {serviceSlug
                ? `Здесь показываются только отзывы по услуге «${serviceTitle || serviceSlug}».`
                : 'Все отзывы по услугам на сайте.'}
            </Reveal>
          </div>
          <Reveal delay={140} className="reviews-score-card">
            <div className="reviews-score-value">{reviews.length || 0}</div>
            <div className="reviews-score-label">{serviceSlug ? 'отзывов по услуге' : 'отзывов всего'}</div>
          </Reveal>
        </div>

        <div className="reviews-layout">
          <Reveal className="reviews-list" delay={160}>
            {reviews.length > 0 ? reviews.map((review) => (
              <article className="review-card" key={review.id || `${review.author_name}-${review.created_at}`}>
                <div className="review-card-head">
                  <div>
                    <h3>{review.author_name}</h3>
                    <div className="review-meta">
                      <ReviewStars value={review.rating} compact />
                      {review.created_at_label && <span>{review.created_at_label}</span>}
                    </div>
                  </div>
                  {!serviceSlug && review.service_title && (
                    <a className="review-service-pill" href={review.service_href || '#'}>{review.service_title}</a>
                  )}
                </div>
                <p>{review.text}</p>
                {review.photo_path && <img className="review-photo" src={review.photo_path} alt={`Фото к отзыву от ${review.author_name}`} loading="lazy" />}
                {review.admin_reply && (
                  <div className="review-reply">
                    <span>Ответ администратора</span>
                    <p>{review.admin_reply}</p>
                  </div>
                )}
              </article>
            )) : (
              <div className="review-empty">
                <h3>Отзывов пока нет</h3>
                <p>Можно оставить первый отзыв после выполненной задачи. Он появится в этом блоке с привязкой к услуге.</p>
              </div>
            )}
          </Reveal>

          <Reveal as="form" className="form review-form" delay={220} onSubmit={handleSubmit}>
            <div className="form-head">
              <span className="prompt">$</span>
              <span>winetlab review</span>
              <span style={{ marginLeft: 'auto', color: 'var(--term-green)' }}>● open</span>
            </div>

            <div className="form-row">
              <label>name</label>
              <input name="author_name" type="text" placeholder="Как вас подписать" maxLength="80" required />
            </div>

            {serviceSlug ? (
              <div className="review-service-fixed">
                <span>Услуга</span>
                <strong>{serviceTitle || serviceSlug}</strong>
                <input name="service_slug" type="hidden" value={serviceSlug} />
              </div>
            ) : (
              <div className="form-row">
                <label>service</label>
                <select name="service_slug" value={selectedService} onChange={(e) => setSelectedService(e.target.value)} required>
                  {services.map((service) => (
                    <option key={service.slug} value={service.slug}>{service.title}</option>
                  ))}
                </select>
              </div>
            )}

            <div className="form-row">
              <label>rating</label>
              <RatingInput value={rating} onChange={setRating} />
            </div>

            <div className="form-row">
              <label>review</label>
              <textarea name="text" placeholder="Что делали, что понравилось, какой результат получили" maxLength="1600" required />
            </div>

            <div className="form-row">
              <label>photo</label>
              <input ref={fileRef} name="photo" type="file" accept="image/png,image/jpeg,image/webp,image/gif,image/avif" />
            </div>

            <label className="form-consent">
              <input name="pd_consent" type="checkbox" value="yes" defaultChecked />
              <span>
                Согласен на публикацию отзыва и обработку персональных данных по{' '}
                <a href="/privacy/" target="_blank" rel="noopener noreferrer">политике</a>.
              </span>
            </label>
            <input className="review-hp" type="text" name="website" tabIndex="-1" autoComplete="off" />
            {error && <div className="form-error">{error}</div>}
            {sent && <div className="form-success">Спасибо, отзыв опубликован.</div>}

            <button className="btn btn-primary form-submit" type="submit">
              Отправить отзыв <span className="btn-arrow">→</span>
            </button>
          </Reveal>
        </div>
      </div>
    </section>
  );
}

window.ReviewsPanel = ReviewsPanel;
