'use client';

import React, { createContext, useContext, useState, useEffect, useRef } from 'react';
import { RecordEvent, RecordingSession } from '@/types/record-mode';

interface RecordModeContextType {
  isActive: boolean;
  setIsActive: (active: boolean) => void;
  events: RecordEvent[];
  addEvent: (event: Omit<RecordEvent, 'id' | 'timestamp'>) => void;
  updateEvent: (id: string, event: Partial<RecordEvent>) => void;
  removeEvent: (id: string) => void;
  clearEvents: () => void;
  setEvents: (events: RecordEvent[]) => void;
  isPlaying: boolean;
  playEvents: () => void;
  stopPlayback: () => void;
  cursorPosition: { x: number; y: number };
  zoomLevel: number;
  isBlurry: boolean;
  currentSession: RecordingSession | null;
  saveSession: (name: string) => void;
  isFeedbackActive: boolean;
  setIsFeedbackActive: (active: boolean) => void;
  reorderEvents: (startIndex: number, endIndex: number) => void;
  hoveredEventId: string | null;
  setHoveredEventId: (id: string | null) => void;
  isClicking: boolean;
  isEnabled: boolean;
}

const RecordModeContext = createContext<RecordModeContextType | null>(null);

export function useRecordMode(): RecordModeContextType {
  const context = useContext(RecordModeContext);
  if (!context) {
    return {
      isActive: false,
      setIsActive: () => {},
      events: [],
      addEvent: () => {},
      updateEvent: () => {},
      removeEvent: () => {},
      clearEvents: () => {},
      isPlaying: false,
      playEvents: () => {},
      stopPlayback: () => {},
      cursorPosition: { x: 0, y: 0 },
      zoomLevel: 1,
      isBlurry: false,
      currentSession: null,
      isFeedbackActive: false,
      setIsFeedbackActive: () => {},
      saveSession: () => {},
      reorderEvents: () => {},
      hoveredEventId: null,
      setHoveredEventId: () => {},
      setEvents: () => {},
      isClicking: false,
      isEnabled: false,
    };
  }
  return context;
}

export function RecordModeProvider({
  children,
  isEnabled = false,
}: {
  children: React.ReactNode;
  isEnabled?: boolean;
}) {
  const [isActive, setIsActiveState] = useState(false);
  const [events, setEvents] = useState<RecordEvent[]>([]);
  const [isPlaying, setIsPlaying] = useState(false);
  const [cursorPosition, setCursorPosition] = useState({ x: 0, y: 0 });
  const [zoomLevel, setZoomLevel] = useState(1);
  const [isBlurry, setIsBlurry] = useState(false);
  const [isFeedbackActive, setIsFeedbackActiveState] = useState(false);
  const [hoveredEventId, setHoveredEventId] = useState<string | null>(null);
  const [isClicking, setIsClicking] = useState(false);
  const [isEmbedded, setIsEmbedded] = useState(false);

  useEffect(() => {
    console.log('[RecordModeProvider] Mounted with isEnabled:', isEnabled);
  }, [isEnabled]);

  useEffect(() => {
    if (!isEnabled) return;
    const embedded =
      typeof window !== 'undefined' &&
      (window.location.search.includes('embedded=true') ||
        window.name === 'record-mode-iframe' ||
        window.self !== window.top);
    setIsEmbedded(embedded);
  }, [isEnabled]);

  const setIsActive = (active: boolean) => {
    if (!isEnabled) return;
    setIsActiveState(active);
    if (active) setIsFeedbackActiveState(false);
  };

  const setIsFeedbackActive = (active: boolean) => {
    setIsFeedbackActiveState(active);
    if (active && isEnabled) setIsActiveState(false);
  };

  const isPlayingRef = useRef(false);
  const isLoadedRef = useRef(false);

  useEffect(() => {
    if (!isEnabled) return;
    const savedEvents = localStorage.getItem('klz-record-events');
    const savedActive = localStorage.getItem('klz-record-active');
    if (savedEvents) setEvents(JSON.parse(savedEvents));
    if (savedActive) setIsActive(JSON.parse(savedActive));
    isLoadedRef.current = true;
  }, [isEnabled]);

  useEffect(() => {
    if (!isEnabled || !isLoadedRef.current) return;
    localStorage.setItem('klz-record-events', JSON.stringify(events));
  }, [events, isEnabled]);

  useEffect(() => {
    if (!isEnabled) return;
    localStorage.setItem('klz-record-active', JSON.stringify(isActive));
  }, [isActive, isEnabled]);

  useEffect(() => {
    if (!isEnabled) return;
    if (isEmbedded) {
      const handlePlaybackMessage = (e: MessageEvent) => {
        if (e.data.type === 'PLAY_EVENT') {
          const { event } = e.data;
          const el = event.selector
            ? (document.querySelector(event.selector) as HTMLElement)
            : null;
          if (el) {
            if (event.type === 'scroll') {
              el.scrollIntoView({ behavior: 'smooth', block: 'center' });
            } else if (event.type === 'mouse') {
              const currentRect = el.getBoundingClientRect();
              let targetX = currentRect.left + currentRect.width / 2;
              let targetY = currentRect.top + currentRect.height / 2;

              if (event.clickOrigin === 'top-left') {
                targetX = currentRect.left + 5;
                targetY = currentRect.top + 5;
              } else if (event.clickOrigin === 'top-right') {
                targetX = currentRect.right - 5;
                targetY = currentRect.top + 5;
              } else if (event.clickOrigin === 'bottom-left') {
                targetX = currentRect.left + 5;
                targetY = currentRect.bottom - 5;
              } else if (event.clickOrigin === 'bottom-right') {
                targetX = currentRect.right - 5;
                targetY = currentRect.bottom - 5;
              }

              const eventCoords = { clientX: targetX, clientY: targetY };
              const dispatchMouse = (type: string) => {
                el.dispatchEvent(
                  new MouseEvent(type, {
                    view: window,
                    bubbles: true,
                    cancelable: true,
                    ...eventCoords,
                  }),
                );
              };

              if (event.interactionType === 'click') {
                setIsClicking(true);
                dispatchMouse('mousedown');
                setTimeout(() => {
                  dispatchMouse('mouseup');
                  if (event.realClick) {
                    dispatchMouse('click');
                    el.click();
                  }
                  setIsClicking(false);
                }, 150);
              } else {
                dispatchMouse('mousemove');
                dispatchMouse('mouseover');
                dispatchMouse('mouseenter');
              }
            }
          }
        }
      };
      window.addEventListener('message', handlePlaybackMessage);
      return () => window.removeEventListener('message', handlePlaybackMessage);
    }
  }, [isEmbedded, isEnabled]);

  useEffect(() => {
    if (!isEnabled || isEmbedded || !isActive) return;
    const event = events.find((e) => e.id === hoveredEventId);
    const iframe = document.querySelector('iframe[name="record-mode-iframe"]') as HTMLIFrameElement;
    if (iframe?.contentWindow) {
      iframe.contentWindow.postMessage(
        { type: 'SET_HOVER_SELECTOR', selector: event?.selector || null },
        '*',
      );
    }
  }, [hoveredEventId, events, isActive, isEmbedded, isEnabled]);

  const addEvent = (event: Omit<RecordEvent, 'id' | 'timestamp'>) => {
    if (!isEnabled) return;
    const newEvent: RecordEvent = {
      realClick: false,
      ...event,
      id: Math.random().toString(36).substr(2, 9),
      timestamp: Date.now(),
    };
    setEvents((prev) => [...prev, newEvent]);
  };

  const updateEvent = (id: string, updatedFields: Partial<RecordEvent>) => {
    if (!isEnabled) return;
    setEvents((prev) =>
      prev.map((event) => (event.id === id ? { ...event, ...updatedFields } : event)),
    );
  };

  const reorderEvents = (startIndex: number, endIndex: number) => {
    if (!isEnabled) return;
    const result = Array.from(events);
    const [removed] = result.splice(startIndex, 1);
    result.splice(endIndex, 0, removed);
    setEvents(result);
  };

  const removeEvent = (id: string) => {
    if (!isEnabled) return;
    setEvents((prev) => prev.filter((event) => event.id !== id));
  };

  const clearEvents = () => {
    if (!isEnabled) return;
    if (confirm('Clear all recorded events?')) setEvents([]);
  };

  const currentSession: RecordingSession | null =
    events.length > 0
      ? {
          id: 'draft',
          name: 'Draft Session',
          events,
          createdAt: new Date().toISOString(),
        }
      : null;

  const saveSession = (name: string) => {
    if (!isEnabled) return;
    console.log('Saving session:', name, events);
  };

  const playEvents = async () => {
    if (!isEnabled || events.length === 0 || isPlayingRef.current) return;
    setIsPlaying(true);
    isPlayingRef.current = true;
    const sortedEvents = [...events].sort((a, b) => (a.timestamp || 0) - (b.timestamp || 0));

    for (const event of sortedEvents) {
      if (!isPlayingRef.current) break;
      if (event.rect && !isEmbedded) {
        const iframe = document.querySelector(
          'iframe[name="record-mode-iframe"]',
        ) as HTMLIFrameElement;
        const iframeRect = iframe?.getBoundingClientRect();
        setCursorPosition({
          x: (iframeRect?.left || 0) + event.rect.x + event.rect.width / 2,
          y: (iframeRect?.top || 0) + event.rect.y + event.rect.height / 2,
        });
      }

      if (event.selector) {
        if (!isEmbedded) {
          const iframe = document.querySelector(
            'iframe[name="record-mode-iframe"]',
          ) as HTMLIFrameElement;
          if (iframe?.contentWindow)
            iframe.contentWindow.postMessage({ type: 'PLAY_EVENT', event }, '*');
        } else {
          const el = document.querySelector(event.selector) as HTMLElement;
          if (el) {
            if (event.type === 'scroll') el.scrollIntoView({ behavior: 'smooth', block: 'center' });
            else if (event.type === 'mouse') {
              const currentRect = el.getBoundingClientRect();
              let targetX = currentRect.left + currentRect.width / 2;
              let targetY = currentRect.top + currentRect.height / 2;

              if (event.clickOrigin === 'top-left') {
                targetX = currentRect.left + 5;
                targetY = currentRect.top + 5;
              } else if (event.clickOrigin === 'top-right') {
                targetX = currentRect.right - 5;
                targetY = currentRect.top + 5;
              } else if (event.clickOrigin === 'bottom-left') {
                targetX = currentRect.left + 5;
                targetY = currentRect.bottom - 5;
              } else if (event.clickOrigin === 'bottom-right') {
                targetX = currentRect.right - 5;
                targetY = currentRect.bottom - 5;
              }

              const eventCoords = { clientX: targetX, clientY: targetY };
              const dispatchMouse = (type: string) => {
                el.dispatchEvent(
                  new MouseEvent(type, {
                    view: window,
                    bubbles: true,
                    cancelable: true,
                    ...eventCoords,
                  }),
                );
              };

              if (event.interactionType === 'click') {
                setIsClicking(true);
                dispatchMouse('mousedown');
                setTimeout(() => {
                  dispatchMouse('mouseup');
                  if (event.realClick) {
                    dispatchMouse('click');
                    el.click();
                  }
                  setIsClicking(false);
                }, 150);
              } else {
                dispatchMouse('mousemove');
                dispatchMouse('mouseover');
                dispatchMouse('mouseenter');
              }
            }
          }
        }
      }

      if (event.zoom) setZoomLevel(event.zoom);
      if (event.motionBlur) setIsBlurry(true);
      await new Promise((resolve) => setTimeout(resolve, event.duration || 1000));
      setIsBlurry(false);
    }
    setIsPlaying(false);
    isPlayingRef.current = false;
    setZoomLevel(1);
  };

  const stopPlayback = () => {
    setIsPlaying(false);
    isPlayingRef.current = false;
    setZoomLevel(1);
    setIsBlurry(false);
  };

  return (
    <RecordModeContext.Provider
      value={{
        isActive,
        setIsActive,
        events,
        addEvent,
        updateEvent,
        removeEvent,
        clearEvents,
        setEvents,
        isPlaying,
        playEvents,
        stopPlayback,
        cursorPosition,
        zoomLevel,
        isBlurry,
        currentSession,
        saveSession,
        isFeedbackActive,
        setIsFeedbackActive,
        reorderEvents,
        hoveredEventId,
        setHoveredEventId,
        isClicking,
        isEnabled,
      }}
    >
      {children}
    </RecordModeContext.Provider>
  );
}
