'use client';

import { Input, ModalBody } from '@chakra-ui/react';
import { observer } from 'mobx-react-lite';

import { useStores } from '@/app/(root)/AppProviders';
import Button, { ButtonVariant } from '@/components/button/Button';
import ImageUploader from '@/components/image/ImageUploader';
import {
  DISPLAY_HEIGHT,
  DISPLAY_WIDTH,
} from '@/components/modal/editClipMetadata/constants';
import ModalHeader from '@/components/modal/publishSong/ModalHeader';
import PublishModalFooter from '@/components/modal/publishSong/PublishModalFooter';
import SpinnerSVG from '@/components/svg/SpinnerSVG';
import useUploadImageFile from '@/hooks/useUploadImageFile';
import logWebUserEvent from '@/logging/logWebUserEvent';
import { PlanFeature } from '@/state/sessionStore';
import { PageEventType, eventLogger } from '@/utils/event-logger';
import { isFeatureEnabledForPlan } from '@/utils/session';

export const AddImageModalContent = observer(
  (props: {
    initialImageURL: string | null;
    addingImageDataURL: string | null;
    setAddingImageDataURL: (url: string | null) => void;
    setAddingImageChanged: (isChanged: boolean) => void;
    editedImagePrompt: string;
    setEditedImagePrompt: (prompt: string) => void;
    setInitialImageURL: (url: string) => void;
    isGenerating: boolean;
    addingImageChanged: boolean;
    setIsGenerating: (isGenerating: boolean) => void;
    setIsAddingImage: (isAdding: boolean) => void;
    addedImages: (string | null)[];
    setAddedImages: (images: (string | null)[]) => void;
    setCurrentImage: (image: string | null) => void;
    setS3Id: (s3Id: string | null) => void;
    showBackButton?: boolean;
    onClose?: () => void;
  }) => {
    const {
      initialImageURL,
      setAddingImageDataURL,
      addingImageDataURL,
      addingImageChanged,
      setAddingImageChanged,
      editedImagePrompt,
      setEditedImagePrompt,
      setInitialImageURL,
      isGenerating,
      setIsGenerating,
      setIsAddingImage,
      setAddedImages,
      setCurrentImage,
      setS3Id,
      addedImages,
      showBackButton = false,
      onClose,
    } = props;

    const { session, library } = useStores();

    const uploadImageFile = useUploadImageFile();

    const clipId = library.activeClip?.id || '';

    return (
      <div className='flex h-full w-full flex-col justify-between'>
        <ModalHeader
          title='Add Image'
          onBack={showBackButton ? () => setIsAddingImage(false) : undefined}
          onClose={onClose}
        />
        <ModalBody overflowY='auto'>
          <div className='flex shrink-0 flex-col gap-4'>
            <div className='flex flex-col items-start gap-4 md:flex-row'>
              <div className='mx-auto shrink-0'>
                <ImageUploader
                  className='w-full'
                  width={Math.max(DISPLAY_WIDTH, DISPLAY_HEIGHT)}
                  height={Math.max(DISPLAY_WIDTH, DISPLAY_HEIGHT)}
                  style={{
                    width: DISPLAY_WIDTH,
                    height: DISPLAY_HEIGHT,
                  }}
                  initialImageURL={initialImageURL || undefined}
                  onImageChanged={(imageData: string | null) => {
                    setAddingImageDataURL(imageData);
                    setAddingImageChanged(true);
                    logWebUserEvent({
                      actionName: 'SongEditCoverArtUploadClicked',
                      principalObjectType: 'song',
                      principalObjectValue: clipId,
                      context: {
                        clipId,
                        mediaType: 'image',
                      },
                    });
                  }}
                />
              </div>
              <div className='w-full font-sans text-base leading-relaxed font-normal'>
                <h4 className='font-semibold'>Upload a photo</h4>
                <ul className='list-disc pl-4'>
                  <li>
                    Images that do not follow{' '}
                    <a
                      className='text-gray-900 underline'
                      href='https://suno.com/legal/terms'
                      target='_blank'
                    >
                      our policies
                    </a>{' '}
                    will be removed
                  </li>
                </ul>
                <h4 className='font-semibold'>File requirements</h4>
                <ul className='list-disc pl-4'>
                  {/* <li>9x16 aspect ratio</li> */}
                  <li>at least 720px tall</li>
                  <li>JPG, PNG, WEBP files</li>
                </ul>
              </div>
            </div>

            {isFeatureEnabledForPlan(
              session,
              PlanFeature.GenerateSongImage
            ) && (
              <>
                <div className='flex gap-2'>
                  <Input
                    fontFamily={'Neue Montreal'}
                    placeholder={'Prompt for an AI-generated image...'}
                    value={editedImagePrompt}
                    maxLength={200}
                    onChange={(event) =>
                      setEditedImagePrompt(event.target.value)
                    }
                    _focus={{
                      border: 'solid',
                      borderWidth: '0.5px',
                      borderColor: '#FAF7F5',
                      boxShadow: '0 0 0 0.5px #FAF7F5',
                    }}
                  />
                  <Button
                    variant={ButtonVariant.Secondary}
                    className='px-6'
                    onClick={async () => {
                      setIsGenerating(true);
                      logWebUserEvent({
                        actionName: 'SongEditCoverArtPromptClicked',
                        principalObjectType: 'song',
                        principalObjectValue: clipId,
                        context: {
                          clipId,
                          mediaType: 'image',
                          prompt: editedImagePrompt,
                        },
                      });
                      const { data } = await library.apiClient.POST(
                        '/api/gen/prompt_image/',
                        {
                          body: {
                            prompt: editedImagePrompt,
                          },
                        }
                      );
                      setIsGenerating(false);
                      if (data) {
                        setInitialImageURL((data as any).image_url);
                      }
                    }}
                    disabled={isGenerating || editedImagePrompt === ''}
                  >
                    Generate
                  </Button>
                </div>
                {isGenerating && (
                  <div className='flex flex-row'>
                    <SpinnerSVG className='mr-2' />
                    <span>Generating AI image...</span>
                  </div>
                )}
              </>
            )}
          </div>
        </ModalBody>

        <PublishModalFooter>
          <Button
            variant={ButtonVariant.Secondary}
            onClick={() => setIsAddingImage(false)}
          >
            Cancel
          </Button>
          <Button
            variant={ButtonVariant.Primary}
            disabled={!addingImageChanged}
            onClick={async () => {
              setAddedImages([
                ...addedImages,
                ...(addingImageDataURL ? [addingImageDataURL] : []),
              ]);
              const uploadImage = async (addingImageDataURL: string | null) => {
                if (!addingImageDataURL) {
                  return;
                }

                const [header, base64Data] = addingImageDataURL.split(',');
                const mimeType =
                  header.match(/data:([^;]+)/)?.[1] || 'image/jpeg';
                const binaryString = atob(base64Data);
                const bytes = new Uint8Array(binaryString.length);
                for (let i = 0; i < binaryString.length; i++) {
                  bytes[i] = binaryString.charCodeAt(i);
                }
                const blob = new Blob([bytes], { type: mimeType });

                // Generate a proper filename based on the MIME type
                const fileExtension = mimeType.split('/')[1] || 'jpeg';
                const filename = `image_${Date.now()}.${fileExtension}`;

                const uploadImageResult = await uploadImageFile(
                  blob,
                  'file_upload',
                  filename
                );
                if (uploadImageResult?.uploadId) {
                  setS3Id(uploadImageResult.uploadId);
                }
              };
              await uploadImage(addingImageDataURL);
              setCurrentImage(addingImageDataURL);
              setIsAddingImage(false);
              eventLogger.logWebPageEvent({
                userId: session.userId || '',
                eventType: PageEventType.CLICK,
                element: 'edit_song_details_modal',
                secondaryElement: 'add_image_button',
                pageUrl: window.location.pathname,
              });
              logWebUserEvent({
                actionName: 'SongEditCoverArtSaveClicked',
                principalObjectType: 'song',
                principalObjectValue: clipId,
                context: {
                  clipId,
                  mediaType: 'image',
                },
              });
            }}
            className='px-6'
          >
            Confirm
          </Button>
        </PublishModalFooter>
      </div>
    );
  }
);

export default AddImageModalContent;
