import { createSignal, Show, For, createEffect } from "solid-js";

interface ReviewFormProps {
  onSubmit: (data: {
    name: string;
    surname: string;
    profession: string;
    rating: number;
    text: string;
  }) => void;
  onCancel?: () => void;
  user?: {
    name: string;
    email: string;
    avatar?: string;
  };
}

const DANGEROUS_PATTERNS = [
  /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
  /javascript:/gi,
  /on\w+\s*=/gi,
  /<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,
  /<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi,
  /<embed\b[^<]*>/gi,
  /data:text\/html/gi,
  /expression\s*\(/gi,
  /url\s*\(\s*['"]*\s*javascript:/gi,
];

const MAX_TEXT_LENGTH = 500;
const MIN_TEXT_LENGTH = 50;
const MAX_NAME_LENGTH = 50;
const MAX_PROFESSION_LENGTH = 100;

interface ValidationErrors {
  name?: string;
  surname?: string;
  profession?: string;
  rating?: string;
  text?: string;
}

const RATING_LABELS: Record<number, string> = {
  1: "Плохо",
  2: "Не очень",
  3: "Нормально",
  4: "Хорошо",
  5: "Отлично",
};

export default function ReviewForm(props: ReviewFormProps) {
  const [name, setName] = createSignal("");
  const [surname, setSurname] = createSignal("");
  const [profession, setProfession] = createSignal("");
  const [rating, setRating] = createSignal(0);
  const [hoverRating, setHoverRating] = createSignal(0);
  const [text, setText] = createSignal("");
  const [errors, setErrors] = createSignal<ValidationErrors>({});
  const [touched, setTouched] = createSignal<{ [key: string]: boolean }>({});

  createEffect(() => {
    if (props.user?.name) {
      const parts = props.user.name.split(" ");
      if (parts.length >= 2) {
        setName(parts[0]);
        setSurname(parts.slice(1).join(" "));
      } else {
        setName(props.user.name);
      }
    }
  });

  const sanitizeInput = (input: string): string => {
    return input
      .replace(/[<>]/g, "")
      .replace(/"/g, "&quot;")
      .replace(/'/g, "&#x27;")
      .replace(/&/g, "&amp;");
  };

  const containsDangerousContent = (input: string): boolean => {
    return DANGEROUS_PATTERNS.some((pattern) => pattern.test(input));
  };

  const validateName = (value: string): string | undefined => {
    const trimmed = value.trim();
    if (!trimmed) return "Введите имя";
    if (trimmed.length > MAX_NAME_LENGTH) return `Макс. ${MAX_NAME_LENGTH} символов`;
    return undefined;
  };

  const validateSurname = (value: string): string | undefined => {
    const trimmed = value.trim();
    if (!trimmed) return "Введите фамилию";
    if (trimmed.length > MAX_NAME_LENGTH) return `Макс. ${MAX_NAME_LENGTH} символов`;
    return undefined;
  };

  const validateProfession = (value: string): string | undefined => {
    const trimmed = value.trim();
    if (!trimmed) return "Укажите профессию";
    if (trimmed.length > MAX_PROFESSION_LENGTH) return `Макс. ${MAX_PROFESSION_LENGTH} символов`;
    return undefined;
  };

  const validateRating = (value: number): string | undefined => {
    if (!value || value < 1 || value > 5) return "Поставьте оценку";
    return undefined;
  };

  const validateText = (value: string): string | undefined => {
    const trimmed = value.trim();
    if (!trimmed) return "Напишите отзыв";
    if (trimmed.length < MIN_TEXT_LENGTH)
      return `Минимум ${MIN_TEXT_LENGTH} символов`;
    if (trimmed.length > MAX_TEXT_LENGTH)
      return `Макс. ${MAX_TEXT_LENGTH} символов`;
    if (containsDangerousContent(trimmed)) return "Недопустимый контент";
    return undefined;
  };

  const handleTextChange = (e: Event) => {
    const target = e.target as HTMLTextAreaElement;
    let value = target.value;

    if (containsDangerousContent(value)) {
      DANGEROUS_PATTERNS.forEach((pattern) => {
        value = value.replace(pattern, "");
      });
    }

    if (value.length > MAX_TEXT_LENGTH) {
      value = value.slice(0, MAX_TEXT_LENGTH);
    }

    setText(value);
    if (touched().text) {
      setErrors((prev) => ({ ...prev, text: validateText(value) }));
    }
  };

  const validateForm = (): boolean => {
    const newErrors: ValidationErrors = {
      name: validateName(name()),
      surname: validateSurname(surname()),
      profession: validateProfession(profession()),
      rating: validateRating(rating()),
      text: validateText(text()),
    };

    setErrors(newErrors);
    setTouched({
      name: true,
      surname: true,
      profession: true,
      rating: true,
      text: true,
    });

    return !Object.values(newErrors).some((error) => error);
  };

  const handleSubmit = (e: Event) => {
    e.preventDefault();
    if (!validateForm()) return;

    props.onSubmit({
      name: sanitizeInput(name().trim()),
      surname: sanitizeInput(surname().trim()),
      profession: sanitizeInput(profession().trim()),
      rating: rating(),
      text: sanitizeInput(text().trim()),
    });

    setName("");
    setSurname("");
    setProfession("");
    setRating(0);
    setText("");
    setErrors({});
    setTouched({});
  };

  const handleBlur = (field: string) => {
    setTouched((prev) => ({ ...prev, [field]: true }));

    const fieldValidators: Record<string, () => string | undefined> = {
      name: () => validateName(name()),
      surname: () => validateSurname(surname()),
      profession: () => validateProfession(profession()),
      rating: () => validateRating(rating()),
      text: () => validateText(text()),
    };

    setErrors((prev) => ({
      ...prev,
      [field]: fieldValidators[field](),
    }));
  };

  const isValid = () => {
    return !errors().name && !errors().surname && !errors().profession &&
           !errors().rating && !errors().text &&
           name().trim() && surname().trim() && profession().trim() &&
           rating() > 0 && text().trim();
  };

  const getFieldClass = (field: keyof ValidationErrors) => {
    const hasError = errors()[field] && touched()[field];
    return `w-full px-4 py-3 rounded-xl border transition-all resize-none bg-white text-gray-900 placeholder-gray-400 outline-none ${
      hasError
        ? "border-red-300 focus:border-red-500 focus:ring-2 focus:ring-red-200"
        : "border-gray-200 focus:border-blue-500 focus:ring-2 focus:ring-blue-200"
    }`;
  };

  const displayRating = () => hoverRating() || rating();

  return (
    <div class="review-form-wrapper">
      <div class="review-form-card">
        <div class="review-form-header">
          <h3 class="review-form-title">Оставить отзыв</h3>
          <p class="review-form-subtitle">Ваш опыт поможет другим клиентам</p>
        </div>

        <form onSubmit={handleSubmit} class="review-form">
          <div class="form-section">
            <div class="name-row">
              <div class="field-group">
                <label class="field-label">Имя</label>
                <input
                  type="text"
                  value={name()}
                  onInput={(e) => setName(e.currentTarget.value)}
                  onBlur={() => handleBlur("name")}
                  placeholder="Иван"
                  class={getFieldClass("name")}
                />
                <Show when={errors().name && touched().name}>
                  <p class="field-error">{errors().name}</p>
                </Show>
              </div>
              <div class="field-group">
                <label class="field-label">Фамилия</label>
                <input
                  type="text"
                  value={surname()}
                  onInput={(e) => setSurname(e.currentTarget.value)}
                  onBlur={() => handleBlur("surname")}
                  placeholder="Иванов"
                  class={getFieldClass("surname")}
                />
                <Show when={errors().surname && touched().surname}>
                  <p class="field-error">{errors().surname}</p>
                </Show>
              </div>
            </div>
          </div>

          <div class="form-section">
            <div class="field-group">
              <label class="field-label">Профессия</label>
              <input
                type="text"
                value={profession()}
                onInput={(e) => setProfession(e.currentTarget.value)}
                onBlur={() => handleBlur("profession")}
                placeholder="Например: Водитель, Предприниматель..."
                class={getFieldClass("profession")}
              />
              <Show when={errors().profession && touched().profession}>
                <p class="field-error">{errors().profession}</p>
              </Show>
            </div>
          </div>

          <div class="form-section">
            <div class="field-group">
              <label class="field-label">Ваша оценка</label>
              <div class="rating-stars-wrapper">
                <div class="rating-stars">
                  <For each={[1, 2, 3, 4, 5]}>
                    {(star) => (
                      <button
                        type="button"
                        class={`star-btn ${star <= displayRating() ? "active" : ""}`}
                        onClick={() => {
                          setRating(star);
                          if (touched().rating) {
                            setErrors((prev) => ({ ...prev, rating: validateRating(star) }));
                          }
                          setTouched((prev) => ({ ...prev, rating: true }));
                        }}
                        onMouseEnter={() => setHoverRating(star)}
                        onMouseLeave={() => setHoverRating(0)}
                        aria-label={`Оценка ${star}`}
                      >
                        <svg viewBox="0 0 24 24" fill="currentColor">
                          <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
                        </svg>
                      </button>
                    )}
                  </For>
                </div>
                <Show when={rating() > 0}>
                  <span class="rating-label">{RATING_LABELS[rating()]}</span>
                </Show>
              </div>
              <Show when={errors().rating && touched().rating}>
                <p class="field-error">{errors().rating}</p>
              </Show>
            </div>
          </div>

          <div class="form-section">
            <div class="field-group">
              <label class="field-label">Ваш отзыв</label>
              <div class="review-textarea-wrapper">
                <textarea
                  value={text()}
                  onInput={handleTextChange}
                  onBlur={() => handleBlur("text")}
                  placeholder="Расскажите о вашем опыте работы с нами..."
                  rows={5}
                  class={getFieldClass("text")}
                />
                <div class="textarea-progress">
                  <div
                    class="progress-bar"
                    style={{ width: `${Math.min(100, (text().length / MIN_TEXT_LENGTH) * 100)}%` }}
                  />
                </div>
              </div>
              <div class="textarea-footer">
                <div class="textarea-info">
                  <Show when={text().length > 0 && text().length < MIN_TEXT_LENGTH}>
                    <p class="min-chars-hint">
                      Ещё {MIN_TEXT_LENGTH - text().length} символов до отправки
                    </p>
                  </Show>
                  <Show when={text().length >= MIN_TEXT_LENGTH}>
                    <p class="text-ready-hint">Готово к отправке</p>
                  </Show>
                </div>
                <p
                  class={`char-count ${text().length > MAX_TEXT_LENGTH * 0.9 ? "warning" : ""}`}
                >
                  {text().length}/{MAX_TEXT_LENGTH}
                </p>
              </div>
              <div class="moderation-notice">
                <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
                </svg>
                <span>Все отзывы проходят модерацию перед публикацией</span>
              </div>
            </div>
          </div>

          <button
            type="submit"
            disabled={!isValid()}
            class="submit-btn"
          >
            <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"/>
            </svg>
            Отправить отзыв
          </button>

          <p class="privacy-note">
            Нажимая кнопку, вы соглашаетесь с{" "}
            <a href="/privacy" class="privacy-link">политикой конфиденциальности</a>
          </p>
        </form>
      </div>

      <style>{`
        .review-form-wrapper {
          display: flex;
          justify-content: center;
          padding: 2rem 1rem;
        }

        .review-form-card {
          width: 100%;
          max-width: 520px;
          background: #ffffff;
          border-radius: 20px;
          border: 1px solid #e2e8f0;
          box-shadow: 0 4px 24px rgba(0, 0, 0, 0.06);
          overflow: hidden;
        }

        .review-form-header {
          padding: 1.75rem 2rem;
          background: linear-gradient(135deg, #1e3050 0%, #2d4a6f 100%);
          text-align: center;
        }

        .review-form-title {
          color: #ffffff;
          font-size: 1.35rem;
          font-weight: 700;
          margin: 0 0 0.25rem 0;
        }

        .review-form-subtitle {
          color: rgba(255, 255, 255, 0.7);
          font-size: 0.9rem;
          margin: 0;
        }

        .review-form {
          padding: 1.5rem 2rem 2rem;
          display: flex;
          flex-direction: column;
          gap: 1.25rem;
        }

        .form-section {
          display: flex;
          flex-direction: column;
        }

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

        @media (max-width: 480px) {
          .name-row {
            grid-template-columns: 1fr;
          }
        }

        .field-group {
          display: flex;
          flex-direction: column;
          gap: 0.4rem;
        }

        .field-label {
          font-size: 0.85rem;
          font-weight: 600;
          color: #1e3050;
        }

        .field-error {
          font-size: 0.8rem;
          color: #ef4444;
          margin: 0;
          display: flex;
          align-items: center;
          gap: 0.25rem;
        }

        .rating-stars-wrapper {
          display: flex;
          align-items: center;
          gap: 1rem;
          padding: 0.5rem 0;
        }

        .rating-stars {
          display: flex;
          gap: 0.35rem;
        }

        .star-btn {
          background: none;
          border: none;
          padding: 0;
          cursor: pointer;
          color: #e2e8f0;
          transition: all 0.2s ease;
          transform-origin: center;
        }

        .star-btn:hover,
        .star-btn.active {
          color: #eac26e;
        }

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

        .star-btn svg {
          width: 28px;
          height: 28px;
        }

        .rating-label {
          font-size: 0.9rem;
          font-weight: 600;
          color: #1e3050;
        }

        .char-count {
          font-size: 0.75rem;
          color: #94a3b8;
          margin: 0;
        }

        .char-count.warning {
          color: #f59e0b;
        }

        .review-textarea-wrapper {
          position: relative;
        }

        .review-textarea-wrapper textarea {
          padding-bottom: 6px;
        }

        .textarea-progress {
          position: absolute;
          bottom: 0;
          left: 0;
          right: 0;
          height: 3px;
          background: #e2e8f0;
          border-radius: 0 0 12px 12px;
          overflow: hidden;
        }

        .progress-bar {
          height: 100%;
          background: linear-gradient(90deg, #eac26e 0%, #ce9f40 100%);
          transition: width 0.3s ease;
          border-radius: 0 0 12px 12px;
        }

        .textarea-footer {
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-top: 0.35rem;
          min-height: 1.2rem;
        }

        .textarea-info {
          display: flex;
          align-items: center;
        }

        .min-chars-hint {
          font-size: 0.75rem;
          color: #94a3b8;
          margin: 0;
        }

        .text-ready-hint {
          font-size: 0.75rem;
          color: #22c55e;
          margin: 0;
          font-weight: 600;
        }

        .moderation-notice {
          display: flex;
          align-items: center;
          gap: 0.4rem;
          padding: 0.6rem 0.75rem;
          background: #f8fafc;
          border-radius: 8px;
          margin-top: 0.5rem;
          border: 1px solid #e2e8f0;
        }

        .moderation-notice svg {
          width: 14px;
          height: 14px;
          color: #64748b;
          flex-shrink: 0;
        }

        .moderation-notice span {
          font-size: 0.75rem;
          color: #64748b;
        }

        .submit-btn {
          display: flex;
          align-items: center;
          justify-content: center;
          gap: 0.5rem;
          width: 100%;
          padding: 1rem 1.5rem;
          background: linear-gradient(135deg, #eac26e 0%, #ce9f40 100%);
          border: none;
          border-radius: 12px;
          color: #ffffff;
          font-size: 1rem;
          font-weight: 700;
          cursor: pointer;
          transition: all 0.3s ease;
          margin-top: 0.5rem;
        }

        .submit-btn:hover:not(:disabled) {
          transform: translateY(-2px);
          box-shadow: 0 6px 20px rgba(234, 194, 110, 0.4);
        }

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

        .privacy-note {
          font-size: 0.75rem;
          color: #94a3b8;
          text-align: center;
          margin: 0;
        }

        .privacy-link {
          color: #2563eb;
          text-decoration: none;
        }

        .privacy-link:hover {
          text-decoration: underline;
        }

        @media (max-width: 480px) {
          .review-form {
            padding: 1.25rem 1.25rem 1.5rem;
          }

          .review-form-header {
            padding: 1.5rem 1.25rem;
          }
        }
      `}</style>
    </div>
  );
}