import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from 'react';
import {
  getCvWizardStep,
  setCvWizardStep,
  showCvWizardStep,
  subscribeCvWizardStep,
} from './cv-wizard-state';

type Locale = 'ar' | 'en';

type Props = {
  locale: Locale;
  stepLabels: string[];
  initialStep?: number;
  formId: string;
  cancelHref: string;
};

function selectedText(form: HTMLFormElement, name: string): string {
  const el = form.elements.namedItem(name);
  if (el instanceof HTMLSelectElement) {
    return el.selectedOptions[0]?.textContent?.trim() ?? '—';
  }
  return '—';
}

function fieldValue(form: HTMLFormElement, name: string): string {
  const el = form.elements.namedItem(name);
  if (el instanceof HTMLInputElement) {
    if (el.type === 'checkbox') return el.checked ? 'yes' : '';
    return el.value.trim();
  }
  if (el instanceof HTMLSelectElement) return el.value;
  if (el instanceof HTMLTextAreaElement) return el.value.trim();
  return '';
}

function buildReviewHtml(form: HTMLFormElement, locale: Locale): string {
  const yes = locale === 'ar' ? 'نعم' : 'Yes';
  const no = locale === 'ar' ? 'لا' : 'No';
  const dash = '—';

  const rows: Array<[string, string]> = [
    [locale === 'ar' ? 'الجنسية' : 'Country', selectedText(form, 'country')],
    [locale === 'ar' ? 'المهنة' : 'Profession', selectedText(form, 'profession')],
    [locale === 'ar' ? 'العمر' : 'Age', fieldValue(form, 'age') || dash],
    [locale === 'ar' ? 'نوع الطلب' : 'Service type', selectedText(form, 'serviceType')],
    [
      locale === 'ar' ? 'الحالة الاجتماعية' : 'Marital status',
      selectedText(form, 'maritalStatus') !== '—' ? selectedText(form, 'maritalStatus') : dash,
    ],
    [locale === 'ar' ? 'سنوات الخبرة' : 'Experience years', fieldValue(form, 'experienceYears') || dash],
    [
      locale === 'ar' ? 'المستوى التعليمي' : 'Education',
      selectedText(form, 'educationLevel') !== '—' ? selectedText(form, 'educationLevel') : dash,
    ],
    [
      locale === 'ar' ? 'الديانة' : 'Religion',
      selectedText(form, 'religion') !== '—' ? selectedText(form, 'religion') : dash,
    ],
    [locale === 'ar' ? 'الراتب' : 'Salary', fieldValue(form, 'salary') || dash],
    [locale === 'ar' ? 'نوع السعر' : 'Price type', selectedText(form, 'priceType')],
    [locale === 'ar' ? 'فيديو' : 'Video', fieldValue(form, 'hasVideo') === 'yes' ? yes : no],
    [locale === 'ar' ? 'مميزة' : 'Featured', fieldValue(form, 'featured') === 'yes' ? yes : no],
    [locale === 'ar' ? 'الاسم (عربي)' : 'Name (Arabic)', fieldValue(form, 'ar_name') || dash],
    [locale === 'ar' ? 'الاسم (English)' : 'Name (English)', fieldValue(form, 'en_name') || dash],
  ];

  const photoInput = form.elements.namedItem('photo');
  const hasPhoto =
    photoInput instanceof HTMLInputElement && photoInput.files && photoInput.files.length > 0;
  rows.push([locale === 'ar' ? 'الصورة' : 'Photo', hasPhoto ? yes : dash]);

  return rows
    .map(
      ([label, value]) =>
        `<div class="flex flex-col gap-0.5 border-b border-base-200 py-2.5 sm:flex-row sm:justify-between sm:gap-4"><dt class="text-sm text-base-content/55">${label}</dt><dd class="text-sm font-medium">${value}</dd></div>`,
    )
    .join('');
}

type FormField = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;

/** First field in a step panel that fails native constraint validation (required, min, step, …). */
function findInvalidField(form: HTMLFormElement, stepIndex: number): FormField | null {
  const panel = form.querySelector(`[data-cv-wizard-step="${stepIndex}"]`);
  if (!panel) return null;

  const fields = panel.querySelectorAll<FormField>('input, select, textarea');
  for (const field of fields) {
    if (field.disabled) continue;
    if (field instanceof HTMLInputElement && (field.type === 'checkbox' || field.type === 'hidden')) continue;
    if (!field.checkValidity()) return field;
  }
  return null;
}

function useStep(initialStep: number) {
  return useSyncExternalStore(subscribeCvWizardStep, getCvWizardStep, () => initialStep);
}

export default function CvFormWizardFooter({
  locale,
  stepLabels,
  initialStep = 0,
  formId,
  cancelHref,
}: Props) {
  const step = useStep(initialStep);
  const reviewRef = useRef<HTMLDivElement>(null);
  const submittingRef = useRef(false);
  const [submitting, setSubmitting] = useState(false);
  const reviewStepIndex = stepLabels.length - 1;

  const refreshReview = useCallback(() => {
    const form = document.getElementById(formId) as HTMLFormElement | null;
    if (form && reviewRef.current) {
      reviewRef.current.innerHTML = buildReviewHtml(form, locale);
    }
  }, [formId, locale]);

  useEffect(() => {
    setCvWizardStep(initialStep);
    showCvWizardStep(formId, initialStep, initialStep === reviewStepIndex ? refreshReview : undefined);
  }, [formId, initialStep, refreshReview, reviewStepIndex]);

  useEffect(() => {
    if (step === reviewStepIndex) refreshReview();
  }, [step, reviewStepIndex, refreshReview]);

  // The form is `novalidate`: native validation can't surface errors on hidden step panels and
  // would silently cancel the submit, so we validate every step here and jump to the first bad field.
  useEffect(() => {
    const form = document.getElementById(formId) as HTMLFormElement | null;
    if (!form) return;

    function handleSubmit(event: SubmitEvent) {
      if (submittingRef.current) {
        event.preventDefault();
        return;
      }
      for (let i = 0; i < reviewStepIndex; i++) {
        const field = findInvalidField(form!, i);
        if (field) {
          event.preventDefault();
          showCvWizardStep(formId, i);
          field.reportValidity();
          field.focus();
          return;
        }
      }
      submittingRef.current = true;
      setSubmitting(true);
    }

    function handlePageShow(event: PageTransitionEvent) {
      // Restored from bfcache after navigating back: allow submitting again.
      if (event.persisted) {
        submittingRef.current = false;
        setSubmitting(false);
      }
    }

    form.addEventListener('submit', handleSubmit);
    window.addEventListener('pageshow', handlePageShow);
    return () => {
      form.removeEventListener('submit', handleSubmit);
      window.removeEventListener('pageshow', handlePageShow);
    };
  }, [formId, reviewStepIndex]);

  function validateCurrentStep(): boolean {
    const form = document.getElementById(formId) as HTMLFormElement | null;
    if (!form) return false;
    const field = findInvalidField(form, step);
    if (!field) return true;
    field.reportValidity();
    field.focus();
    return false;
  }

  function handleNext() {
    if (!validateCurrentStep()) return;
    if (step < reviewStepIndex) {
      const next = step + 1;
      showCvWizardStep(formId, next, next === reviewStepIndex ? refreshReview : undefined);
    }
  }

  function handleBack() {
    if (step > 0) showCvWizardStep(formId, step - 1);
  }

  const isReview = step === reviewStepIndex;
  const isFirst = step === 0;

  return (
    <div className="space-y-6">
      <div
        ref={reviewRef}
        className={`rounded-box border border-accent/25 bg-accent/5 p-4 ${isReview ? '' : 'hidden'}`}
        aria-hidden={!isReview}
      />

      <div className="flex flex-col-reverse gap-3 border-t border-base-300 pt-6 sm:flex-row sm:items-center sm:justify-between">
        <a href={cancelHref} className="btn btn-ghost btn-sm sm:btn-md">
          {locale === 'ar' ? 'إلغاء' : 'Cancel'}
        </a>
        <div className="flex flex-col-reverse gap-2 sm:flex-row">
          {!isFirst && (
            <button type="button" onClick={handleBack} className="btn btn-outline btn-sm sm:btn-md">
              {locale === 'ar' ? 'السابق' : 'Back'}
            </button>
          )}
          {!isReview ? (
            <button type="button" onClick={handleNext} className="btn btn-primary btn-sm sm:btn-md">
              {locale === 'ar' ? 'التالي' : 'Next'}
            </button>
          ) : (
            <button
              type="submit"
              form={formId}
              disabled={submitting}
              aria-busy={submitting}
              className="btn btn-primary btn-sm sm:btn-md"
            >
              {submitting && <span className="loading loading-spinner loading-sm" aria-hidden="true" />}
              {submitting
                ? locale === 'ar'
                  ? 'جارٍ الحفظ...'
                  : 'Saving...'
                : locale === 'ar'
                  ? 'إنشاء السيرة'
                  : 'Create CV'}
            </button>
          )}
        </div>
      </div>
    </div>
  );
}
