import { useCallback, useEffect, useMemo, useState } from 'react';
import { useAppSelector } from '@akinon/next/redux/hooks';
import { useSession } from 'next-auth/react';
import type { RootState } from '@theme/redux/store';
import type { SectionStatus } from '../accordion-section';

export type SectionId = 'contact' | 'address' | 'shipping' | 'payment';

export interface SectionState {
  id: SectionId;
  status: SectionStatus;
  isComplete: boolean;
}

interface UseSectionStateOptions {
  autoAdvance?: boolean;
}

export const useSectionState = ({ autoAdvance = true }: UseSectionStateOptions = {}) => {
  const { data: session } = useSession();
  const preOrder = useAppSelector(
    (state: RootState) => state.checkout.preOrder
  );

  const isAuthenticated = Boolean(session?.user);
  const contactComplete = isAuthenticated || Boolean(preOrder?.is_guest);
  const addressComplete = Boolean(
    preOrder?.shipping_address?.pk && preOrder?.billing_address?.pk
  );
  const shippingComplete = Boolean(preOrder?.shipping_option?.pk);

  const completion = useMemo(
    () => ({
      contact: contactComplete,
      address: addressComplete,
      shipping: shippingComplete,
      payment: false
    }),
    [contactComplete, addressComplete, shippingComplete]
  );

  const firstIncomplete = useMemo<SectionId>(() => {
    if (!completion.contact) return 'contact';
    if (!completion.address) return 'address';
    if (!completion.shipping) return 'shipping';
    return 'payment';
  }, [completion]);

  const [activeSection, setActiveSection] = useState<SectionId>(firstIncomplete);
  const [touchedSections, setTouchedSections] = useState<Set<SectionId>>(
    () => new Set()
  );

  useEffect(() => {
    if (!autoAdvance) return;
    if (touchedSections.has(activeSection)) return;
    if (firstIncomplete !== activeSection) {
      setActiveSection(firstIncomplete);
    }
  }, [firstIncomplete, autoAdvance, activeSection, touchedSections]);

  const openSection = useCallback((id: SectionId) => {
    setActiveSection(id);
    setTouchedSections((prev) => {
      const next = new Set(prev);
      next.add(id);
      return next;
    });
  }, []);

  const sections = useMemo<SectionState[]>(() => {
    const order: SectionId[] = ['contact', 'address', 'shipping', 'payment'];
    return order.map((id) => {
      const isComplete = completion[id];
      let status: SectionStatus;
      if (id === activeSection) {
        status = 'active';
      } else if (isComplete) {
        status = 'completed';
      } else {
        const indexCurrent = order.indexOf(activeSection);
        const indexThis = order.indexOf(id);
        status = indexThis < indexCurrent ? 'completed' : 'locked';
      }
      return { id, status, isComplete };
    });
  }, [completion, activeSection]);

  const allComplete = completion.contact && completion.address && completion.shipping;

  return {
    sections,
    activeSection,
    openSection,
    allComplete,
    completion,
    isAuthenticated
  };
};
