'use client';

import { observer } from 'mobx-react-lite';
import { useSearchParams } from 'next/navigation';
import { useCallback, useEffect, useState } from 'react';
import { useLocalStorage } from 'usehooks-ts';

import { useStores } from '@/app/(root)/AppProviders';
import CloneProjectModal from '@/components/studio/CloneProjectModal';
import {
  StudioProjectManagementContext,
  useStudioProjectManagement,
} from '@/components/studio/StudioProjectManagementContext';
import getStudioModeStateForClip from '@/components/studio/getStudioModeStateForClip';
import { StudioProjectState } from '@/components/studio/types';
import logWebUserEvent from '@/logging/logWebUserEvent';

// Enhanced localStorage structure for project management
interface StoredProjectInfo {
  projectId: string;
  trackLatestVersion: boolean;
  sourceVersionId?: string; // Track if loaded from version
  lastUpdated: number; // timestamp
}

interface StudioProjectInitializerProps {
  userId: string;
  children: (props: {
    loadedProject: {
      title: string;
      state: StudioProjectState;
      id: string;
    } | null;
  }) => React.ReactNode;
}

export const StudioProjectInitializer = observer(
  function StudioProjectInitializer({
    userId,
    children,
  }: StudioProjectInitializerProps) {
    const { clips: clipsStore } = useStores();
    const searchParams = useSearchParams();

    const [loadedProject, setLoadedProjectState] = useState<{
      title: string;
      state: StudioProjectState;
      id: string;
    } | null>(null);

    const [storedProjectInfo, setStoredProjectInfo] =
      useLocalStorage<StoredProjectInfo | null>(
        `studio-project-management-project-info-v2-${userId}`,
        null
      );

    // Helper functions for managing enhanced localStorage
    const updateStoredProjectInfo = useCallback(
      (
        projectId: string,
        trackLatestVersion: boolean,
        sourceVersionId?: string
      ) => {
        setStoredProjectInfo({
          projectId,
          trackLatestVersion,
          sourceVersionId,
          lastUpdated: Date.now(),
        });
      },
      [setStoredProjectInfo]
    );

    const clearStoredProjectInfo = useCallback(() => {
      setStoredProjectInfo(null);
    }, [setStoredProjectInfo]);

    const setLoadedProject = useCallback(
      (
        project: {
          title: string;
          state: StudioProjectState;
          id: string;
        } | null,
        options?: {
          sourceVersionId?: string;
          skipLocalStorage?: boolean;
        }
      ) => {
        setLoadedProjectState(project);

        // Update localStorage unless explicitly skipped
        if (project && !options?.skipLocalStorage) {
          // For localStorage, we need to check if we stick with one version or always track the latest version
          const trackLatestVersion = !options?.sourceVersionId; // No sourceVersionId = always track the latest version
          updateStoredProjectInfo(
            project.id,
            trackLatestVersion,
            options?.sourceVersionId
          );
        } else if (!project) {
          clearStoredProjectInfo();
        }
      },
      [updateStoredProjectInfo, clearStoredProjectInfo]
    );

    const studioProjectManagement = useStudioProjectManagement(
      loadedProject,
      setLoadedProject
    );

    // Extract stable method references to include in dependencies
    const {
      loadProject,
      loadProjectByVersionId,
      createAndLoadNewStudioProject,
    } = studioProjectManagement;

    const [preparingInitialProject, setPreparingInitialProject] =
      useState(false);
    const [showCloneModal, setShowCloneModal] = useState(false);
    const [sharedProjectInfo, setSharedProjectInfo] = useState<{
      versionId: string;
      projectTitle: string;
    } | null>(null);

    const initialProjectId = searchParams?.get('initial_project_id');
    const projectVersionId = searchParams?.get('project_version_id');
    const forClipId = searchParams?.get('for_clip_id');

    const handleCloneProject = useCallback(
      async (title?: string) => {
        if (!sharedProjectInfo) throw new Error('No shared project info');

        return await studioProjectManagement.cloneProject(
          sharedProjectInfo.versionId,
          title
        );
      },
      [sharedProjectInfo, studioProjectManagement]
    );

    const handleCloseCloneModal = useCallback(() => {
      setShowCloneModal(false);
      setSharedProjectInfo(null);
    }, []);

    useEffect(() => {
      if (loadedProject) return;

      // URL cleanup function - only call after successful loading
      const cleanupUrl = () => {
        const url = new URL(window.location.href);
        url.searchParams.delete('initial_project_id');
        // Keep project_version_id to maintain version loading across refreshes
        url.searchParams.delete('for_clip_id');
        window.history.replaceState({}, '', url.toString());
      };

      // Handle URL-based loading first (highest priority)
      if (projectVersionId) {
        setPreparingInitialProject(true);
        loadProjectByVersionId(
          projectVersionId,
          'studio',
          (versionId: string, projectTitle: string) => {
            // This callback is triggered when the project is shared (not owned by user)
            setSharedProjectInfo({ versionId, projectTitle });
            setShowCloneModal(true);
            setPreparingInitialProject(false);
          }
        )
          .then(() => {
            setPreparingInitialProject(false);
          })
          .catch(() => {
            // On project version load failure, clean up URL and redirect to main studio
            const url = new URL(window.location.href);
            url.searchParams.delete('project_version_id');
            window.history.replaceState({}, '', url.toString());
            setPreparingInitialProject(false);
            // Use window.location.href for reliable client-side redirect
            window.location.href = '/studio';
          });
      } else if (initialProjectId) {
        setPreparingInitialProject(true);
        loadProject(initialProjectId, 'studio')
          .then(() => {
            cleanupUrl(); // Clean up URL only after successful load
            setPreparingInitialProject(false);
          })
          .catch(() => {
            setPreparingInitialProject(false);
          });
      } else if (forClipId) {
        setPreparingInitialProject(true);
        getStudioModeStateForClip(clipsStore, forClipId)
          .then(async (state) => {
            const project = await createAndLoadNewStudioProject(state);
            if (project?.id) {
              logWebUserEvent({
                actionName: 'CreatedNewStudioProject',
                context: {
                  studioProjectId: project.id,
                  trigger: 'initial_load_from_clip',
                },
              });
            }
            cleanupUrl(); // Clean up URL only after successful load
            setPreparingInitialProject(false);
          })
          .catch(() => {
            setPreparingInitialProject(false);
          });
      } else if (storedProjectInfo) {
        // Load project from localStorage with ownership-aware behavior
        setPreparingInitialProject(true);

        if (storedProjectInfo.trackLatestVersion) {
          loadProject(storedProjectInfo.projectId, 'studio')
            .then(() => {
              setPreparingInitialProject(false);
            })
            .catch(() => {
              setPreparingInitialProject(false);
            });
        } else {
          // For non-owned projects, reload the specific version if available
          if (storedProjectInfo.sourceVersionId) {
            loadProjectByVersionId(storedProjectInfo.sourceVersionId, 'studio')
              .then(() => {
                setPreparingInitialProject(false);
              })
              .catch(() => {
                setPreparingInitialProject(false);
              });
          } else {
            // Fallback: load project normally but mark as non-owned
            loadProject(storedProjectInfo.projectId, 'studio')
              .then(() => {
                setPreparingInitialProject(false);
              })
              .catch(() => {
                setPreparingInitialProject(false);
              });
          }
        }
      } else {
        setPreparingInitialProject(true);
        createAndLoadNewStudioProject()
          .then((project) => {
            if (project?.id) {
              logWebUserEvent({
                actionName: 'CreatedNewStudioProject',
                context: {
                  studioProjectId: project.id,
                  trigger: 'initial_load_default',
                },
              });
            }
            setPreparingInitialProject(false);
          })
          .catch(() => {
            setPreparingInitialProject(false);
          });
      }
    }, [
      initialProjectId,
      projectVersionId,
      forClipId,
      loadedProject,
      storedProjectInfo,
      loadProject,
      loadProjectByVersionId,
      createAndLoadNewStudioProject,
      clipsStore,
    ]);

    if (!loadedProject || preparingInitialProject) {
      return null;
    }

    return (
      <>
        {showCloneModal && sharedProjectInfo && (
          <CloneProjectModal
            isOpen={showCloneModal}
            onClose={handleCloseCloneModal}
            onClone={handleCloneProject}
          />
        )}
        <StudioProjectManagementContext.Provider
          value={studioProjectManagement}
        >
          {children({ loadedProject })}
        </StudioProjectManagementContext.Provider>
      </>
    );
  }
);
