'use client';

import { useEffect, useRef, useState } from 'react';

import { AudioInput } from '@/app/(marketing)/home/components/AudioInput';
import { LyricsSection } from '@/app/(marketing)/home/components/LyricsSection';
import { TagInput } from '@/app/(marketing)/home/components/TagInput';
import Button, {
  ButtonShape,
  ButtonSize,
  ButtonVariant,
} from '@/components/button/Button';
import { toast } from '@/components/toast/Toast';
import { ChevronLeftIcon, CreateIcon, StemsIcon } from '@/icons';
import { useApiClient } from '@/lib/apiClient';
import logWebUserEvent from '@/logging/logWebUserEvent';
import { CLOUDFLARE_TURNSTILE_SITE_KEY } from '@/utils/constants';
import {
  MusicianCreateState,
  useMusicianCreateStorage,
} from '@/utils/musicianCreateStorage';

import { HomePageScreens } from '../HomePageClient';

interface MusicianCreateProps {
  setCurrentPage: (page: HomePageScreens) => void;
  handleCreateRedirect: () => void;
  enableLyricsGeneration: boolean;
}

const MusicianCreate = ({
  setCurrentPage,
  handleCreateRedirect,
  enableLyricsGeneration,
}: MusicianCreateProps) => {
  // Initialize with default values that will be overridden if storage exists
  const initialState: Omit<MusicianCreateState, 'savedAt'> = {
    activeLyricsMode: 'auto',
    activeLyrics: '',
    activeLyricsSubject: '',
    activeLyricsModeTab: 'auto',
    activeStyles: '',
    isStylesCollapsed: true,
    shouldGenerate: false,
  };

  const turnstileMounted = useRef(false);

  const [state, updateState] = useMusicianCreateStorage(initialState);
  const [turnstileToken, setTurnstileToken] = useState<string | null>(null);
  const [turnstileLoaded, setTurnstileLoaded] = useState(false);
  const [showTurnstile, setShowTurnstile] = useState(false);
  const [generatingLyrics, setGeneratingLyrics] = useState(false);
  const turnstileRetries = useRef(0);

  // Function to update individual fields and save to storage
  const updateField = <K extends keyof MusicianCreateState>(
    field: K,
    value: MusicianCreateState[K]
  ) => {
    updateState({ [field]: value } as Partial<MusicianCreateState>);
  };

  useEffect(() => {
    updateField('savedAt', Date.now());
    logWebUserEvent({
      actionName: 'HomePageSectionViewed',
      context: {
        sectionName: 'AdvancedCreate',
      },
    });
  }, []);

  // Function to handle Turnstile callback
  const onTurnstileSuccess = (token: string, triggerGenerate: boolean) => {
    setTurnstileToken(token);
    if (triggerGenerate) {
      generateAnonymousLyrics(state.activeLyricsSubject, token)
        .then(() => {
          setGeneratingLyrics(false);
        })
        .catch((error) => {
          console.error('Failed to generate lyrics:', error);
          setGeneratingLyrics(false);
          toast({
            title: "Couldn't generate that",
            status: 'error',
            duration: 5000,
            isClosable: true,
          });
        });
    } else {
      setGeneratingLyrics(false);
    }
  };

  const onTurnstileError = (error: any) => {
    console.error('Turnstile error:', error);
    setGeneratingLyrics(false);
    toast({
      title: "Couldn't generate that",
      status: 'error',
      duration: 5000,
      isClosable: true,
    });
    logWebUserEvent({
      actionName: 'HomePageGenerateLyricsFailed',
      context: {
        error: error,
        reason: 'captcha_failed',
      },
    });
    if ((window as any).turnstile) {
      (window as any).turnstile.remove();
    }
  };

  const renderTurnstile = (triggerGenerate: boolean = false) => {
    if (!turnstileLoaded) return null;
    const turnstileContainer = document.getElementById('cf-turnstile');

    if ((window as any).turnstile && turnstileContainer) {
      (window as any).turnstile.render('#cf-turnstile', {
        sitekey: CLOUDFLARE_TURNSTILE_SITE_KEY,
        callback: function (token: any) {
          onTurnstileSuccess(token, triggerGenerate);
        },
        errorCallback: function (error: any) {
          console.error('Turnstile error:', error);
          setGeneratingLyrics(false);
          logWebUserEvent({
            actionName: 'HomePageGenerateLyricsFailed',
            context: {
              error: 'captcha_failed',
              reason: 'captcha_failed',
            },
          });
        },
      });
    } else {
      turnstileRetries.current++;
      if (turnstileRetries.current < 3) {
        setTimeout(() => {
          renderTurnstile();
        }, 100);
      } else {
        setGeneratingLyrics(false);
        logWebUserEvent({
          actionName: 'HomePageGenerateLyricsFailed',
          context: {
            error: 'captcha_failed',
            reason: 'captcha_failed_to_load',
          },
        });
        toast({
          title: "Couldn't generate that",
          status: 'error',
          duration: 5000,
          isClosable: true,
        });
      }
    }
  };

  const onloadTurnstileCallback = () => {
    setTurnstileLoaded(true);
  };

  const apiClient = useApiClient();
  const generateAnonymousLyrics = async (
    prompt: string,
    turnstileToken: string
  ) => {
    try {
      // Make the API call to the anonymous lyrics generation endpoint
      const response = await apiClient.POST(
        '/api/v2/external/generate/lyrics',
        {
          body: {
            prompt,
            token: turnstileToken,
          },
        }
      );

      if (response.error) {
        console.error('Error generating anonymous lyrics.');
        toast({
          title: "Couldn't generate that",
          status: 'error',
          duration: 5000,
          isClosable: true,
        });
      }
      const data = response.data;

      if (data?.lyrics) {
        updateField('activeLyrics', data.lyrics);
        updateField('activeLyricsMode', 'custom');
        updateField('activeLyricsModeTab', 'custom');
        logWebUserEvent({
          actionName: 'HomePageGenerateLyricsSuccess',
          context: {
            prompt: prompt,
          },
        });
      }
    } catch (error) {
      console.error('Error generating anonymous lyrics:', error);
      logWebUserEvent({
        actionName: 'HomePageGenerateLyricsFailed',
        context: {
          error: 'api call failed to send',
          reason: 'api_call_failed',
        },
      });
      throw error;
    } finally {
      setGeneratingLyrics(false);
      setTurnstileToken(null);
      if ((window as any).turnstile) {
        (window as any).turnstile.remove();
      }
      //   setIsLoading(false);
    }
  };

  useEffect(() => {
    if (turnstileMounted.current) return;
    if (typeof window !== 'undefined') {
      // Make TypeScript happy with window type
      (window as any).onTurnstileSuccess = onTurnstileSuccess;
      (window as any).onTurnstileError = onTurnstileError;
      (window as any).onloadTurnstileCallback = onloadTurnstileCallback;
      // Load the Turnstile script
      const script = document.createElement('script');
      script.src =
        'https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onloadTurnstileCallback&render=explicit';
      script.async = true;
      script.defer = true;
      document.head.appendChild(script);
      turnstileMounted.current = true;
    }
  }, [window]);

  const addPadding = typeof window !== 'undefined' && window.innerHeight < 1050;

  return (
    <div className='relative flex min-h-screen flex-col items-center justify-center pb-[100px]'>
      <div
        className={`mt-0 md:mt-[50px] ${addPadding ? '' : 'md:pt-0'} mx-auto w-full max-w-[600px] px-[10px] pt-[75px]`}
      >
        <div className='flex flex-col gap-[20px]'>
          <div>
            <div className='flex flex-row gap-[11px]'>
              <div>
                <Button
                  variant={ButtonVariant.Primary}
                  size={ButtonSize.Small}
                  shape={ButtonShape.Pill}
                  icon={<ChevronLeftIcon className='h-4 w-4' />}
                  onClick={() => {
                    logWebUserEvent({
                      actionName: 'HomePageAdvancedBackButtonClicked',
                    });
                    setCurrentPage(HomePageScreens.HOME);
                  }}
                  className='flex h-[40px] w-[40px] items-center justify-center bg-primary/10'
                />
              </div>
              <div>
                <div className='font-serif text-[32px] leading-[36px] font-light tracking-[-0.8px] md:text-[40px] md:leading-[48px]'>
                  Turn any idea into a song
                </div>
                <div className='text-base leading-6 font-normal'>
                  Beat, lyrics, or both
                </div>
              </div>
            </div>
          </div>

          <LyricsSection
            onGenerateLyrics={() => {
              setShowTurnstile(true);
              setGeneratingLyrics(true);
              if (turnstileToken) {
                generateAnonymousLyrics(
                  state.activeLyricsSubject,
                  turnstileToken
                );
              } else {
                renderTurnstile(true);
              }
              logWebUserEvent({
                actionName: 'HomePageGenerateLyricsButtonClicked',
                context: {
                  prompt: state.activeLyricsSubject,
                },
              });
              return '';
            }}
            setHasPromptedLyrics={() => {}}
            setIsEditingLyrics={() => {}}
            initialHeight={0}
            onHeightChange={(height: number) => {
              console.log('height', height);
            }}
            activeLyricsMode={state.activeLyricsMode}
            setActiveLyricsMode={(mode) => {
              updateField('activeLyricsMode', mode);
              logWebUserEvent({
                actionName: 'HomePageAdvancedCreateLyricsModeChanged',
                context: {
                  mode: mode,
                },
              });
            }}
            activeLyrics={state.activeLyrics}
            generatingLyrics={generatingLyrics}
            enableLyricsGeneration={enableLyricsGeneration}
            setActiveLyrics={(lyrics) => updateField('activeLyrics', lyrics)}
            activeLyricsSubject={state.activeLyricsSubject}
            setActiveLyricsSubject={(subject) =>
              updateField('activeLyricsSubject', subject)
            }
            activeLyricsModeTab={state.activeLyricsModeTab}
            setActiveLyricsModeTab={(tab) =>
              updateField('activeLyricsModeTab', tab)
            }
          />
          <TagInput
            title={'Styles'}
            icon={CreateIcon}
            placeholder={'Enter style tags'}
            collapsibleFooterTitle={'Suggestions'}
            collapsibleFooterIcon={undefined}
            isCollapsibleInput={true}
            onCollapse={() => {}}
            value={state.activeStyles}
            onChange={(val: string) => {
              updateField('activeStyles', val);
            }}
            onShowHide={() => {}}
            onClear={() => {
              updateField('activeStyles', '');
            }}
            isShown={true}
            initialHeight={50}
            onUpsample={() => {}}
            isUpsampleLoading={false}
            isUpsampled={false}
            isStylesCollapsed={state.isStylesCollapsed}
            setIsStylesCollapsed={(collapsed) =>
              updateField('isStylesCollapsed', collapsed)
            }
          />
          <AudioInput
            title={'Audio'}
            icon={StemsIcon}
            placeholder={'Enter style tags'}
            isCollapsibleInput={true}
            onCollapse={() => {}}
            handleCreateRedirect={handleCreateRedirect}
            onUpsample={() => {}}
            isUpsampleLoading={false}
            isUpsampled={false}
          />
          <Button
            variant={ButtonVariant.Aura}
            size={ButtonSize.Large}
            shape={ButtonShape.Pill}
            className='w-full'
            onClick={() => {
              updateField('shouldGenerate', true);
              logWebUserEvent({
                actionName: 'HomePageAdvancedCreateButtonClicked',
              });
              setTimeout(() => {
                setCurrentPage(HomePageScreens.GENERATE);
              }, 1);
            }}
          >
            Create
          </Button>
          <div
            className={`mx-auto transition-opacity duration-300 ease-in-out ${
              showTurnstile ? 'opacity-100' : 'opacity-0'
            }`}
            id='cf-turnstile'
            data-sitekey={CLOUDFLARE_TURNSTILE_SITE_KEY}
            data-callback='onTurnstileSuccess'
            data-error-callback='onTurnstileError'
            data-theme='dark'
          ></div>
        </div>
      </div>
    </div>
  );
};

export default MusicianCreate;
