/**
 * Wizard State Hook
 * 
 * Manages the state and navigation for the Quick Setup Wizard
 */

import { useEffect, useRef, useState } from '@wordpress/element';
import apiFetch from '@wordpress/api-fetch';

const WIZARD_STORAGE_KEY = 'prorank_wizard_state';
const SITE_BASICS_KEYS = [
  'site_name',
  'site_alternate_name',
  'site_tagline',
  'title_separator',
  'site_logo',
  'site_logo_id',
  'site_image',
  'site_image_id',
  'google_verification',
  'bing_verification',
  'baidu_verification',
  'yandex_verification',
  'pinterest_verification',
  'norton_verification',
  'custom_meta_tags',
  'facebook_page_url',
  'facebook_authorship',
  'facebook_admin_id',
  'facebook_app_id',
  'facebook_secret',
  'twitter_username',
  'linkedin_url',
  'instagram_url',
  'youtube_url',
  'pinterest_url',
  'tiktok_url',
  'threads_url',
  'mastodon_url',
  'additional_profiles',
  'org_or_person',
  'org_name',
  'org_alternate_name',
  'org_logo',
  'org_logo_id',
  'person_logo',
  'person_logo_id',
  'person_user_id',
  'org_description',
  'org_email',
  'org_phone',
  'org_local_business_enabled',
  'org_legal_name',
  'org_founding_date',
  'org_num_employees',
  'org_vat_id',
  'org_tax_id',
  'org_iso_6523',
  'org_duns',
  'org_lei_code',
  'org_naics',
  'org_street_address',
  'org_address_locality',
  'org_address_region',
  'org_postal_code',
  'org_address_country',
];

export const useWizardState = () => {
  // Initialise from localStorage for instant UX, then hydrate from server.
  const [currentStep, setCurrentStep] = useState(() => {
    const saved = localStorage.getItem(WIZARD_STORAGE_KEY);
    if (saved) {
      const parsed = JSON.parse(saved);
      return parsed.currentStep ?? 0;
    }
    return 0;
  });

  const [completedSteps, setCompletedSteps] = useState(() => {
    const saved = localStorage.getItem(WIZARD_STORAGE_KEY);
    if (saved) {
      const parsed = JSON.parse(saved);
      return parsed.completedSteps || [];
    }
    return [];
  });

  const [wizardData, setWizardData] = useState(() => {
    const saved = localStorage.getItem(WIZARD_STORAGE_KEY);
    if (saved) {
      const parsed = JSON.parse(saved);
      return parsed.wizardData || {};
    }
    return {};
  });

  const [isWizardCompleted, setIsWizardCompleted] = useState(false);
  const [saving, setSaving] = useState(false);
  const [lastSaved, setLastSaved] = useState(null);
  const [hydrated, setHydrated] = useState(false);
  const saveTimeoutRef = useRef(null);

  const buildSiteBasicsPayload = () => {
    const siteBasics = {};

    SITE_BASICS_KEYS.forEach((key) => {
      if (Object.prototype.hasOwnProperty.call(wizardData, key)) {
        siteBasics[key] = wizardData[key];
      }
    });

    // Backward compatibility with older wizard payload keys.
    if (!Object.prototype.hasOwnProperty.call(siteBasics, 'org_or_person') && wizardData.site_representation) {
      siteBasics.org_or_person = wizardData.site_representation;
    }
    if (!Object.prototype.hasOwnProperty.call(siteBasics, 'org_name') && wizardData.organization_name) {
      siteBasics.org_name = wizardData.organization_name;
    }
    if (!Object.prototype.hasOwnProperty.call(siteBasics, 'org_logo') && wizardData.organization_logo) {
      siteBasics.org_logo = wizardData.organization_logo;
    }

    return siteBasics;
  };

  // Hydrate from server option.
  useEffect(() => {
    let isMounted = true;
    const hydrate = async () => {
      try {
        const response = await apiFetch({ path: '/prorank-seo/v1/wizard/state' });
        if (!isMounted || !response?.data) return;

        const { currentStep: step = 0, completedSteps: completed = [], wizardData: data = {}, updated_at } = response.data;
        setCurrentStep(step);
        setCompletedSteps(Array.isArray(completed) ? completed : []);
        setWizardData(data || {});
        setLastSaved(updated_at || new Date().toISOString());
        setIsWizardCompleted(!!data?.wizardCompleted);
      } catch (err) {
        // Silent fail: keep local state
      } finally {
        if (isMounted) setHydrated(true);
      }
    };

    hydrate();
    return () => {
      isMounted = false;
    };
  }, []);

  // Persist to localStorage for resilience.
  useEffect(() => {
    const stateToSave = {
      currentStep,
      completedSteps,
      wizardData,
      lastUpdated: new Date().toISOString(),
    };
    localStorage.setItem(WIZARD_STORAGE_KEY, JSON.stringify(stateToSave));
  }, [currentStep, completedSteps, wizardData]);

  // Persist to server (debounced) once hydrated.
  useEffect(() => {
    if (!hydrated) return;
    if (saveTimeoutRef.current) {
      clearTimeout(saveTimeoutRef.current);
    }

    saveTimeoutRef.current = setTimeout(async () => {
      setSaving(true);
      try {
        const response = await apiFetch({
          path: '/prorank-seo/v1/wizard/state',
          method: 'POST',
          data: {
            currentStep,
            completedSteps,
            wizardData,
          },
        });
        setLastSaved(response?.data?.updated_at || new Date().toISOString());
      } catch (err) {
        // Keep silent but mark saving finished
      } finally {
        setSaving(false);
      }
    }, 300);

    return () => {
      if (saveTimeoutRef.current) {
        clearTimeout(saveTimeoutRef.current);
      }
    };
  }, [currentStep, completedSteps, wizardData, hydrated]);

  // Navigation functions
  const goToStep = (stepIndex) => {
    setCurrentStep(stepIndex);
  };

  const nextStep = () => {
    setCurrentStep((prev) => prev + 1);
  };

  const previousStep = () => {
    setCurrentStep((prev) => Math.max(0, prev - 1));
  };

  const markStepCompleted = (stepIndex) => {
    setCompletedSteps((prev) => {
      if (!prev.includes(stepIndex)) {
        return [...prev, stepIndex];
      }
      return prev;
    });
  };

  const updateWizardData = (key, value) => {
    setWizardData((prev) => ({
      ...prev,
      [key]: value,
    }));
  };

  const resetWizard = () => {
    setCurrentStep(0);
    setCompletedSteps([]);
    setWizardData({});
    localStorage.removeItem(WIZARD_STORAGE_KEY);
  };

  const completeWizard = async () => {
    setIsWizardCompleted(true);
    const completedAt = new Date().toISOString();

    // Persist Site Basics captured in the wizard to canonical settings.
    try {
      const siteBasics = buildSiteBasicsPayload();

      if (Object.keys(siteBasics).length > 0) {
        await apiFetch({
          path: '/prorank-seo/v1/settings/site_basics',
          method: 'POST',
          data: {
            settings: siteBasics,
          },
        });
      }
    } catch (err) {
      // Non-blocking: wizard completion should still proceed.
    }

    try {
      const selectedModules = wizardData.selectedModules;
      if (selectedModules && typeof selectedModules === 'object' && Object.keys(selectedModules).length > 0) {
        await Promise.allSettled(
          Object.entries(selectedModules).map(([slug, enabled]) =>
            apiFetch({
              path: `/prorank-seo/v1/modules/groups/${slug}/status`,
              method: 'POST',
              data: { enabled: !!enabled },
            })
          )
        );
      }
    } catch (err) {
      // Non-blocking: module selection should not block completion.
    }

    try {
      const clarityState = wizardData.analytics_status?.clarity;
      if (clarityState && typeof clarityState === 'object') {
        await apiFetch({
          path: '/prorank-seo/v1/settings/clarity',
          method: 'POST',
          data: {
            settings: {
              enabled: !!clarityState.enabled,
              project_id: clarityState.projectId || '',
            },
          },
        });
      }
    } catch (err) {
      // Non-blocking: analytics integrations can be refined later.
    }

    try {
      const psiState = wizardData.analytics_status?.psi;
      if (psiState && typeof psiState === 'object' && Object.prototype.hasOwnProperty.call(psiState, 'apiKey')) {
        await apiFetch({
          path: '/prorank-seo/v1/settings/psi',
          method: 'POST',
          data: {
            settings: {
              api_key: psiState.apiKey || '',
            },
          },
        });
      }
    } catch (err) {
      // Non-blocking: analytics integrations can be refined later.
    }

    try {
      const completedWizardData = {
        ...wizardData,
        wizardCompleted: true,
        completedAt,
      };
      await apiFetch({
        path: '/prorank-seo/v1/wizard/state',
        method: 'POST',
        data: {
          currentStep,
          completedSteps,
          wizardData: completedWizardData,
        },
      });
      setWizardData(completedWizardData);
      setLastSaved(completedAt);
    } catch (err) {
      // ignore
    }

    localStorage.removeItem(WIZARD_STORAGE_KEY);
  };

  const restartWizard = async () => {
    setSaving(true);

    try {
      await apiFetch({
        path: '/prorank-seo/v1/wizard/state',
        method: 'POST',
        data: {
          currentStep: 0,
          completedSteps: [],
          wizardData: {},
        },
      });
    } catch (err) {
      // Non-blocking
    }

    setCurrentStep(0);
    setCompletedSteps([]);
    setWizardData({});
    setIsWizardCompleted(false);
    setLastSaved(new Date().toISOString());
    localStorage.removeItem(WIZARD_STORAGE_KEY);
    setSaving(false);
  };

  const isStepCompleted = (stepIndex) => completedSteps.includes(stepIndex);

  const canNavigateToStep = (stepIndex) => {
    // Can always go back
    if (stepIndex < currentStep) return true;
    // Can go to next step if current is completed
    if (stepIndex === currentStep + 1) {
      return isStepCompleted(currentStep);
    }
    // Can skip to any previously completed step
    return isStepCompleted(stepIndex - 1);
  };

  return {
    currentStep,
    completedSteps,
    wizardData,
    isWizardCompleted,
    goToStep,
    nextStep,
    previousStep,
    markStepCompleted,
    updateWizardData,
    resetWizard,
    restartWizard,
    completeWizard,
    isStepCompleted,
    canNavigateToStep,
    saving,
    lastSaved,
    hydrated,
  };
};
