import React, { useState, useEffect, useCallback, Suspense, lazy } from 'react';
import { useTranslation } from 'react-i18next';
import { useTheme } from '@mui/material/styles';
import useMediaQuery from '@mui/material/useMediaQuery';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import Container from '@mui/material/Container';
import Paper from '@mui/material/Paper';
import Box from '@mui/material/Box';
import Snackbar from '@mui/material/Snackbar';
import Alert from '@mui/material/Alert';
import CircularProgress from '@mui/material/CircularProgress';
import Typography from '@mui/material/Typography';

import StepperNav from './components/StepperNav';
import { fetchWizardSettings, fetchDraft, saveDraft, publishOffer } from './hooks/useApi';

/* ── Lazy-loaded step components ─────────────────────────────── */
const Step0Welcome       = lazy(() => import('./steps/Step0Welcome'));
const Step1OfferType     = lazy(() => import('./steps/Step1OfferType'));
const Step2ProductSelect = lazy(() => import('./steps/Step2ProductSelect'));
const Step3Availability  = lazy(() => import('./steps/Step3Availability'));
const Step4Pricing       = lazy(() => import('./steps/Step4Pricing'));
const Step5Payment       = lazy(() => import('./steps/Step5Payment'));
const Step6Media         = lazy(() => import('./steps/Step6Media'));
const Step7Publish       = lazy(() => import('./steps/Step7Publish'));

/**
 * Step slug array – used everywhere for ordering & labelling.
 */
const STEP_SLUGS = [
  'welcome',
  'offerType',
  'inventory',
  'availability',
  'pricing',
  'payment',
  'media',
  'publish',
];

/**
 * Full-screen loading spinner while a step chunk is being fetched.
 */
function LoadingFallback() {
  const { t } = useTranslation();
  return (
    <Box display="flex" flexDirection="column" alignItems="center" justifyContent="center" minHeight="400px">
      <CircularProgress size={40} thickness={4} />
      <Typography variant="body2" color="text.secondary" sx={{ mt: 2 }}>
        {t('common.loading')}
      </Typography>
    </Box>
  );
}

/**
 * WizardApp – the main wizard container.
 *
 * Manages current step, draft persistence, and step rendering.
 */
export default function WizardApp() {
  const { t } = useTranslation();
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down('md'));
  const queryClient = useQueryClient();

  /* ── State ─────────────────────────────────────────────────── */
  const [currentStep, setCurrentStep] = useState(0);
  const [draftId, setDraftId] = useState(null);
  const [productId, setProductId] = useState(null);
  const [versionHash, setVersionHash] = useState(null);
  const [wizardData, setWizardData] = useState({});
  const [snackbar, setSnackbar] = useState({ open: false, message: '', severity: 'success' });

  /* ── Queries ───────────────────────────────────────────────── */
  const { data: settings } = useQuery({
    queryKey: ['wizard-settings'],
    queryFn: fetchWizardSettings,
    staleTime: Infinity,
  });

  const { data: draftResponse } = useQuery({
    queryKey: ['wizard-draft'],
    queryFn: () => fetchDraft(),
    staleTime: 1000 * 60 * 5,
  });

  // Hydrate state from existing draft when it loads
  useEffect(() => {
    if (draftResponse?.draft) {
      const draft = draftResponse.draft;
      setDraftId(draft.draft_id);
      setProductId(draft.product_id || null);
      setWizardData(draft.wizard_data || {});
      setVersionHash(draft.version_hash || null);
    }
  }, [draftResponse]);

  /* ── Mutations ─────────────────────────────────────────────── */
  const saveMutation = useMutation({
    mutationFn: saveDraft,
    onSuccess: (result) => {
      if (result.draft_id) setDraftId(result.draft_id);
      if (result.version_hash) setVersionHash(result.version_hash);
      queryClient.invalidateQueries(['wizard-draft']);
    },
    onError: (error) => {
      if (error.status === 409) {
        setSnackbar({
          open: true,
          message: t('common.versionConflict'),
          severity: 'error',
        });
      }
    },
  });

  const publishMutation = useMutation({
    mutationFn: publishOffer,
    onSuccess: (result) => {
      setSnackbar({ open: true, message: t('step7.publishSuccess'), severity: 'success' });
      if (result.product_url) {
        setTimeout(() => {
          window.location.href = result.product_url;
        }, 2000);
      }
    },
    onError: (error) => {
      setSnackbar({ open: true, message: error.message || t('common.error'), severity: 'error' });
    },
  });

  /* ── Callbacks ─────────────────────────────────────────────── */
  const updateStepData = useCallback((key, data) => {
    setWizardData((prev) => ({ ...prev, [key]: data }));
  }, []);

  const doSave = useCallback(async () => {
    const stepKey = `step_${currentStep}`;
    const stepData = wizardData[stepKey] || {};
    try {
      await saveMutation.mutateAsync({
        draft_id: draftId,
        product_id: productId,
        current_step: currentStep,
        step_data: stepData,
        version_hash: versionHash,
      });
      return true;
    } catch (err) {
      console.error('Failed to save draft:', err);
      setSnackbar({
        open: true,
        message: err.message || t('common.error'),
        severity: 'error',
      });
      return false;
    }
  }, [currentStep, draftId, productId, wizardData, versionHash, saveMutation, t]);

  const onNext = useCallback(async () => {
    const saved = await doSave();
    if (saved) {
      setCurrentStep((s) => Math.min(s + 1, STEP_SLUGS.length - 1));
    }
  }, [doSave]);

  const onBack = useCallback(() => {
    setCurrentStep((s) => Math.max(s - 1, 0));
  }, []);

  const onStepClick = useCallback(
    (index) => {
      if (index < currentStep) setCurrentStep(index);
    },
    [currentStep],
  );

  const onPublish = useCallback(async () => {
    if (!draftId) await doSave();
    publishMutation.mutate(draftId);
  }, [draftId, doSave, publishMutation]);

  const closeSnackbar = () => {
    setSnackbar((prev) => ({ ...prev, open: false }));
  };

  /* ── Step rendering ────────────────────────────────────────── */
  const renderStep = () => {
    const commonProps = {
      wizardData,
      updateStepData,
      settings: settings || {},
      productId,
      setProductId,
      onNext,
      onBack,
      isMobile,
    };

    switch (currentStep) {
      case 0:
        return (
          <Step0Welcome
            {...commonProps}
            hasDraft={!!draftResponse?.draft}
            draftData={draftResponse?.draft}
            onContinueDraft={() => {
              if (draftResponse?.draft?.current_step) {
                setCurrentStep(draftResponse.draft.current_step);
              } else {
                onNext();
              }
            }}
          />
        );
      case 1:
        return <Step1OfferType {...commonProps} />;
      case 2:
        return <Step2ProductSelect {...commonProps} />;
      case 3:
        return <Step3Availability {...commonProps} />;
      case 4:
        return <Step4Pricing {...commonProps} />;
      case 5:
        return <Step5Payment {...commonProps} />;
      case 6:
        return <Step6Media {...commonProps} />;
      case 7:
        return (
          <Step7Publish
            {...commonProps}
            onPublish={onPublish}
            isPublishing={publishMutation.isPending}
          />
        );
      default:
        return null;
    }
  };

  /* ── Layout ────────────────────────────────────────────────── */
  return (
    <Container maxWidth="lg" sx={{ py: { xs: 2, md: 4 } }}>
      <Paper
        elevation={0}
        sx={{
          p: { xs: 2, md: 4 },
          backgroundColor: 'background.paper',
          borderRadius: 2,
          minHeight: '70vh',
        }}
      >
        <StepperNav
          steps={STEP_SLUGS}
          currentStep={currentStep}
          onStepClick={onStepClick}
          isMobile={isMobile}
        />

        <Box sx={{ mt: { xs: 3, md: 4 } }}>
          <Suspense fallback={<LoadingFallback />}>
            {renderStep()}
          </Suspense>
        </Box>
      </Paper>

      <Snackbar
        open={snackbar.open}
        autoHideDuration={6000}
        onClose={closeSnackbar}
        anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
      >
        <Alert onClose={closeSnackbar} severity={snackbar.severity} sx={{ width: '100%' }}>
          {snackbar.message}
        </Alert>
      </Snackbar>
    </Container>
  );
}
