<!-- Модалка жалобы на видео или плейлист: 2 шага (причина + анкета) с reCAPTCHA -->
<template>
  <transition mode="out-in">
    <UiPopup
      v-if="isReportPopupOpen"
      v-model="isReportPopupOpen"
      sheet
      :back="showBack"
      class="report-main"
      @back="activeStep === 'list' ? handleBack() : goToList()"
    >
      <template #title>{{ activeStep !== 'list' && activeCategory ? t(`report_form.${activeCategory.title}`) : t('report') }}</template>
      <template #fixedContent>
        <CardPlaylistMini
          v-if="reportTargetType === 'playlist'"
          :card="reportedPlaylistCard"
          class="report-main__video-card"
        />
        <CardVideoMini
          v-else
          :card="reportedVideoCard"
          class="report-main__video-card"
        />
      </template>

      <!-- Step 1: Category list -->
      <div
        v-if="activeStep === 'list'"
        class="report-main__popup-wrapper"
      >
        <div class="report-main__categories">
          <button
            v-for="(item, index) in reportFormsScheme"
            :key="`report-category-${index}`"
            class="report-main__category-button"
            @click="selectCategory(item.subject)"
          >
            {{ t(`report_form.${item.title}`) }}
            <UiIcon
              class="report-main__category-icon"
              name="chevron-right"
              size="20"
            />
          </button>
        </div>
      </div>

      <!-- Step 2: Report form -->
      <div
        v-else
        :class="{'_loading': loading}"
        class="report-main__popup-wrapper"
      >
        <div
          v-if="activeCategory"
          class="report-main__wrapper"
        >
          <p
            v-if="activeCategory.text"
            :class="{'--error': errorRadio && !hasReasonHeading}"
            class="report-main__form-text"
          >{{ t(`report_form.${activeCategory.text}`) }}
          </p>
          <p
            v-if="activeCategory.subtext"
            class="report-main__form-text"
          >{{ t(`report_form.${activeCategory.subtext}`) }}
          </p>
          <ul
            v-if="activeCategory.list && activeCategory.list.length > 0"
            class="report-main__form-menu"
          >
            <li
              v-for="(subItem, subIndex) in activeCategory.list"
              :key="`report-list-${subIndex}`"
              class="report-main__form-list"
            >{{ t(`report_form.${subItem.text}`) }}
            </li>
          </ul>
          <form class="report-main__form-wrapper">
            <div
              v-for="(subItem, subIndex) in activeCategory.items"
              :key="`${subItem.label}-${subIndex}`"
              :class="[{'--wide': subItem.wide},subItem.marginClass]"
            >
              <p
                v-if="subItem.type === 'heading'"
                :class="{'--error': errorRadio}"
                class="report-main__form-text"
              >{{ t(`report_form.${subItem.text}`) }}
              </p>
              <UiInput
                v-if="['text', 'email', 'tel', 'textarea'].includes(subItem.type)"
                :ref="(el) => setInputRef(subItem.value, el)"
                v-model="form.data[subItem.value] as string"
                :label="subItem.label ? t(`report_form.${subItem.label}`) : undefined"
                :hide-label="subItem.hideLabel"
                :type="subItem.type as InputTypes"
                :inputmode="subItem.type === 'email' ? 'email' : undefined"
                :enterkeyhint="subItem.type === 'textarea' ? undefined : (isLastTextInput(subItem.value) ? 'send' : 'next')"
                :placeholder="subItem.placeholder ? t(`report_form.${subItem.placeholder}`) : undefined"
                :required="subItem.required"
                :error="error[subItem.value]"
                @update:error="(val: boolean) => error[subItem.value] = val"
                @enter="onFieldEnter(subItem.value)"
              />
              <UiCheckbox
                v-if="subItem.type === 'checkbox'"
                v-model="form.data[subItem.value] as boolean"
                :required="subItem.required"
                :error="error[subItem.value]"
                @update:error="(val: boolean) => error[subItem.value] = val"
              >{{ t(`report_form.${subItem.text}`) }}
              </UiCheckbox>
              <UiRadio
                v-if="subItem.type === 'radio'"
                v-model="reasonValue"
                :value="subItem.value"
                :label="t(`report_form.${subItem.text}`)"
                :required="subItem.required"
                name="report-radio-value"
              />
            </div>
          </form>
        </div>
      </div>

      <template
        v-if="activeStep !== 'list'"
        #footer
      >
        <div class="report-main__send">
          <UiBtn
            :disabled="loading"
            class="report-main__send-button"
            wide
            size="l"
            theme="primary"
            @click="submit"
          >{{ t('report_form.send_report') }}
          </UiBtn>
        </div>
      </template>
    </UiPopup>
  </transition>
</template>

<script setup lang="ts">
import { reportFormsScheme } from '../../lib';
import { checkDeviceWidth, ReportFormsSubjects, validateEmail, validatePhone } from '../../runtime';
import type { InputTypes, IReportForm, IReportRequest } from '../../types';
import { CSS_BREAKPOINTS } from '../../config/css-breakpoints';

const { initRecaptcha, getRecaptchaToken } = useRecaptcha();

const reasonValue = ref('');
const errorRadio = ref(false);
const error = ref<Record<string, boolean>>({});

const { t } = useI18n();

type ReportStep = 'list' | ReportFormsSubjects;
const activeStep = ref<ReportStep>('list');

const form = ref<IReportForm>({
  categoryName: ReportFormsSubjects.DMCA,
  reason: '',
  url: '',
  token: '',
  data: {},
});

const {
  isReportPopupOpen,
  closeReportPopup,
  reportedVideoCard,
  reportedPlaylistCard,
  reportTargetType,
  reportedUrl,
  reportedGuid,
  onBack,
} = useReportPopup();

const { isTablet } = checkDeviceWidth(CSS_BREAKPOINTS);

/* Возврат в меню карточки имеет смысл только там, где оно само — шит (до md);
   на десктопе стрелка остаётся только для перехода со второго шага на список причин */
const showBack = computed(() => activeStep.value !== 'list' || (!!onBack.value && isTablet.value));

function handleBack() {
  const callback = onBack.value;
  closeReportPopup();
  callback?.();
}

function selectCategory(subject: ReportFormsSubjects) {
  resetForm();
  form.value.categoryName = subject;
  activeStep.value = subject;
}

function goToList() {
  resetForm();
  activeStep.value = 'list';
}

watch(isReportPopupOpen, (val) => {
  if (val) {
    resetForm();
  } else {
    activeStep.value = 'list';
  }
});

watch(reasonValue, (val) => {
  if (val) errorRadio.value = false;
});

const reportGuid = computed(() => reportedGuid.value);

const loading = ref(false);

const activeCategory = computed(() => reportFormsScheme.find((subItem) => subItem.subject === activeStep.value));
const requiredFields = computed(() => activeCategory.value?.items?.filter(item => item.required).map(item => item.value));
const hasReasonHeading = computed(() => activeCategory.value?.items?.some(item => item.type === 'heading'));

// Навигация по Enter: однострочные поля (text/email/tel) — фокус на следующее, последнее — сабмит; textarea не участвует
const inputRefs = ref<Record<string, { focus: () => void }>>({});

function setInputRef(value: string, el: { focus: () => void } | null) {
  if (el) inputRefs.value[ value ] = el;
  else delete inputRefs.value[ value ];
}

const textInputValues = computed(() =>
    activeCategory.value?.items?.filter(item => ['text', 'email', 'tel'].includes(item.type)).map(item => item.value) ?? []
);

function isLastTextInput(value: string) {
  return textInputValues.value.at(-1) === value;
}

function onFieldEnter(value: string) {
  const list = textInputValues.value;
  const index = list.indexOf(value);
  if (index === -1) return;
  if (index === list.length - 1) submit();
  else inputRefs.value[ list[ index + 1 ] ]?.focus();
}

const { show, showError, resetSnackbar } = useSnackbar();

function resetForm() {
  Object.keys(form.value).forEach((key) => {
    if (key === 'data') {
      form.value.data = {};
    }
  });
  reasonValue.value = '';
  Object.keys(error.value).forEach(key => error.value[ key ] = false);
  errorRadio.value = false;
}

const emit = defineEmits<{
  (eventName: 'submit', eventValue: IReportRequest): IReportRequest
}>();

// Загружаем reCAPTCHA при открытии формы (onMounted) — даёт Google время собрать данные о поведении
onMounted(async () => {
  try {
    await initRecaptcha();
    console.log('reCAPTCHA готов для этой формы');
  } catch (err) {
    console.error('Ошибка инициализации reCAPTCHA:', err);
  }
});

async function submit() {
  resetSnackbar();
  errorRadio.value = false;
  Object.keys(error.value).forEach(key => error.value[ key ] = false);

  let valid = true;

  if (activeCategory.value?.hasReason) {
    errorRadio.value = !reasonValue.value;
    if (errorRadio.value) valid = false;
  }

  if (requiredFields.value && requiredFields.value.length > 0) {
    requiredFields.value.forEach(item => {
      const val = form.value.data[ item ];

      if (item === 'from' && !validateEmail(val as string)) {
        error.value[ item ] = true;
        showError('error_email');
      } else if (item === 'phone' && !validatePhone(val as string)) {
        error.value[ item ] = !validatePhone(val as string);
        showError('error_phone');
      } else if (['confirmTrue', 'confirmOwner'].includes(item)) {
        error.value[ item ] = !val;
      } else {
        error.value[ item ] = val === undefined || val === null || String(val).trim() === '';
        if (error.value[ item ]) showError('error_text');
      }

      if (error.value[ item ]) valid = false;
    });
  }

  if (!valid) return;

  try {
    const baseURL = import.meta.client ? window.location.origin : '';
    loading.value = true;
    form.value.token = await getRecaptchaToken('contact_form');
    form.value.url = `${baseURL}${reportedUrl.value}`;

    if (reasonValue.value) {
      form.value.data[ 'reason' ] = reasonValue.value;
    }
    emit('submit', {
      form: form.value,
      guid: reportGuid.value
    });
    closeReportPopup();
    resetForm();
    show('email_send');
  } catch (error) {
    console.log('error send email', error);
    showError('email_error');
  } finally {
    loading.value = false;
  }
}
</script>

<style lang="scss">
.report-main .ui-popup__content {
  padding: 0;
}

.report-main__popup-wrapper {
  display: grid;

  @include from-br(sm) {
    width: 574px;
    max-width: 700px;
  }
}

.report-main__categories {
  @include to-br(sm) {
    padding-top: 2px;
    padding-bottom: 16px;
  }
}

.report-main__category-button {
  @include font-md;

  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 16px 20px;
  column-gap: 8px;
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
  text-align: left;

  &:not(:last-child) {
    border-bottom: 1px solid $report-category-border;
  }

  @include from-br(sm) {
    @include font-base;

    font-weight: 500;
    padding: 16px 24px;
  }

  @include hover(background-color) {
    background-color: $report-category-bg--hover;
  }
}

.report-main__category-icon {
  flex-shrink: 0;
  color: $report-category-icon;

  @include from-br(sm) {
    color: $report-category-icon-desktop;
  }
}

.report-main__form-wrapper {
  display: grid;
  column-gap: 12px;
  grid-template-columns: 1fr 1fr;
}

.report-main__form-wrapper .--wide {
  grid-column: 1/3;
}

.report-main__form-text {
  margin-bottom: 16px;

  &:has(+ .report-main__form-menu) {
    margin-bottom: 8px;
  }
}

.report-main__form-list,
.report-main__form-text {
  @include font-sm;

  color: $report-text;
}

.report-main__form-text.--error {
  color: $report-text--error;
}

.report-main__form-text.--error::before {
  content: '*';
  margin-right: 4px;
  color: $report-required;
}

.report-main__form-list {
  margin-bottom: 4px;
  color: $report-text;
}

.report-main__send-button {
  @include to-br(sm) {
    height: 56px;
    border-radius: 14px;
  }
}

.report-main__wrapper {
  padding: 16px;

  @include from-br(sm) {
    padding: 24px 24px 0;
  }
}

ul.report-main__form-menu {
  list-style-position: inside;
  list-style-type: disc;
  margin-bottom: 16px;
}
</style>
