import styled from '@emotion/styled';
import { observer } from 'mobx-react-lite';
import { useEffect, useRef, useState } from 'react';

import useUploadImageFile from '@/hooks/useUploadImageFile';
import { ImageIcon } from '@/icons';

import Button, {
  ButtonShape,
  ButtonSize,
  ButtonVariant,
} from '../button/Button';
import Modal from '../modal/Modal';
import SpinnerSVG from '../svg/SpinnerSVG';
import { toast } from '../toast/Toast';

const Content = styled.div`
  display: flex;
  flex-direction: column;
  gap: 8px;
  height: 100%;
  justify-content: space-between;
`;

const Title = styled.h3`
  font-size: 20px;
  font-weight: 500;
  color: var(--color-foreground-primary);
  margin: 0;
  padding: 0;
`;

const InputRow = styled.div`
  display: flex;
  gap: 16px;
`;

const InputField = styled.div`
  display: flex;
  flex-direction: column;
  padding: 16px;
  border-radius: 16px;
  background-color: var(--color-background-glass-thin);
  cursor: text;
  transition: background-color 0.2s ease-in-out;

  &:hover {
    background-color: var(--color-background-glass-thick);
  }

  &:focus-within {
    background-color: var(--color-background-glass-thick);
  }
`;

const InputLabel = styled.label`
  font-size: 12px;
  font-weight: 500;
  color: var(--color-foreground-primary);
  margin-bottom: 8px;
  cursor: text;
`;

const OptionalText = styled.span`
  color: var(--color-foreground-inactive);
`;

const ImagePreview = styled.div<{ $isUploading?: boolean }>`
  width: 92px;
  height: 92px;
  border-radius: 16px;
  background-color: var(--color-background-glass-thin);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: ${(props) => (props.$isUploading ? 'default' : 'pointer')};
  position: relative;
  overflow: hidden;
  flex-shrink: 0;
  transition: background-color 0.2s ease-in-out;
  opacity: ${(props) => (props.$isUploading ? 0.6 : 1)};

  &:hover {
    background-color: ${(props) =>
      props.$isUploading
        ? 'var(--color-background-glass-thin)'
        : 'var(--color-background-glass-thick)'};
  }
`;

const HiddenFileInput = styled.input`
  display: none;
`;

const ImagePreviewImage = styled.img`
  width: 100%;
  height: 100%;
  object-fit: cover;
`;

const ImagePlaceholder = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  color: var(--color-foreground-secondary);
  font-size: 12px;
`;

const TextInput = styled.input`
  border: none;
  background: none;
  color: var(--color-foreground-primary);
  font-size: 16px;
  outline: none;
  padding: 0;
  font-family: inherit;
  flex: 1;

  &::placeholder {
    color: var(--color-foreground-secondary);
  }
`;

const TextArea = styled.textarea`
  border: none;
  background: none;
  color: var(--color-foreground-primary);
  font-size: 16px;
  outline: none;
  padding: 0;
  resize: none;
  font-family: inherit;
  min-height: 80px;
  flex: 1;

  &::placeholder {
    color: var(--color-foreground-secondary);
  }
`;

const ButtonRow = styled.div`
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
`;

interface StudioProjectDetailsModalProps {
  initialTitle?: string;
  initialImageUrl?: string;
  initialNotes?: string;
  onClose: () => void;
  onSave: (data: {
    title: string;
    imageUrl?: string;
    notes: string;
    imageS3Id?: string | null;
  }) => void;
}

export default observer(function StudioProjectDetailsModal({
  initialTitle = '',
  initialImageUrl,
  initialNotes = '',
  onClose,
  onSave,
}: StudioProjectDetailsModalProps) {
  const [title, setTitle] = useState(initialTitle);
  const [imageUrl, setImageUrl] = useState(initialImageUrl);
  const [imageS3Id, setImageS3Id] = useState<string | null>(null);
  const [notes, setNotes] = useState(initialNotes);
  const [isUploadingImage, setIsUploadingImage] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const objectUrlRef = useRef<string | null>(null);
  const uploadImageFile = useUploadImageFile();

  // Cleanup object URL on unmount only
  useEffect(() => {
    return () => {
      if (objectUrlRef.current) {
        URL.revokeObjectURL(objectUrlRef.current);
        objectUrlRef.current = null;
      }
    };
  }, []);

  const handleSave = () => {
    onSave({
      title,
      imageUrl,
      notes,
      imageS3Id,
    });
    onClose();
  };

  const handleImageClick = () => {
    if (!isUploadingImage) {
      fileInputRef.current?.click();
    }
  };

  const handleFileChange = async (
    event: React.ChangeEvent<HTMLInputElement>
  ) => {
    const file = event.target.files?.[0];
    if (!file) return;

    // Check file size (10MB limit)
    if (file.size > 10 * 1024 * 1024) {
      toast({
        title: 'Image too large',
        description: 'Image must be less than 10MB',
        status: 'error',
        duration: 3000,
        isClosable: true,
      });
      return;
    }

    // Check file type
    if (!file.type.startsWith('image/')) {
      toast({
        title: 'Invalid file type',
        description: 'File must be an image',
        status: 'error',
        duration: 3000,
        isClosable: true,
      });
      return;
    }

    try {
      setIsUploadingImage(true);

      // Upload the file to S3 (stays in raw_uploads bucket)
      // The backend will handle moderation and moving to final location when save is called
      const result = await uploadImageFile(file, 'file_upload');

      if (!result?.uploadId) {
        throw new Error('Failed to get upload ID');
      }

      const uploadId = result.uploadId;

      // Set the S3 ID - backend will moderate and transfer on save
      setImageS3Id(uploadId);

      // Clean up the previous object URL if it exists
      if (objectUrlRef.current) {
        URL.revokeObjectURL(objectUrlRef.current);
      }

      // Use a local preview URL for display in the modal
      // We can't use the CDN URL yet since the image is still in raw_uploads
      // and not accessible via CDN until the backend processes it
      const localPreviewUrl = URL.createObjectURL(file);
      objectUrlRef.current = localPreviewUrl;
      setImageUrl(localPreviewUrl);
    } catch (error) {
      console.error('Error uploading image:', error);
      const errorMessage =
        error instanceof Error ? error.message : 'Failed to upload image';
      toast({
        title: 'Upload failed',
        description: errorMessage,
        status: 'error',
        duration: 4000,
        isClosable: true,
      });
    } finally {
      setIsUploadingImage(false);
      // Reset the input so the same file can be selected again
      if (fileInputRef.current) {
        fileInputRef.current.value = '';
      }
    }
  };

  return (
    <Modal
      onClose={onClose}
      width={null}
      contentWrapperClasses='max-h-[90vh] max-w-[90vw] h-[420px] w-[480px] overflow-hidden border border-border-primary rounded-2xl'
      wrapperClasses='h-full w-full flex flex-col overflow-hidden'
      closeButtonClasses='absolute top-2 right-2 z-100 p-1'
    >
      <Content>
        <Title>Project Details</Title>

        <InputRow>
          <HiddenFileInput
            ref={fileInputRef}
            type='file'
            accept='image/*'
            onChange={handleFileChange}
          />
          <ImagePreview
            onClick={handleImageClick}
            $isUploading={isUploadingImage}
          >
            {isUploadingImage ? (
              <SpinnerSVG />
            ) : imageUrl ? (
              <ImagePreviewImage src={imageUrl} alt='Project thumbnail' />
            ) : (
              <ImagePlaceholder>
                <ImageIcon className='h-6 w-6' />
                <span>Add Image</span>
              </ImagePlaceholder>
            )}
          </ImagePreview>

          <InputField
            style={{ flex: 1 }}
            onClick={(e) => {
              const input = e.currentTarget.querySelector('input');
              input?.focus();
            }}
          >
            <InputLabel htmlFor='title-input'>Title</InputLabel>
            <TextInput
              id='title-input'
              placeholder='Enter project title'
              value={title}
              onChange={(e) => setTitle(e.target.value)}
            />
          </InputField>
        </InputRow>

        <InputField
          onClick={(e) => {
            const textarea = e.currentTarget.querySelector('textarea');
            textarea?.focus();
          }}
        >
          <InputLabel htmlFor='notes-input'>
            Notes <OptionalText>(optional)</OptionalText>
          </InputLabel>
          <TextArea
            id='notes-input'
            placeholder='Add notes about this project...'
            value={notes}
            onChange={(e) => setNotes(e.target.value)}
          />
        </InputField>

        <ButtonRow>
          <Button
            size={ButtonSize.Large}
            variant={ButtonVariant.Standard}
            shape={ButtonShape.Pill}
            onClick={onClose}
          >
            Cancel
          </Button>
          <Button
            size={ButtonSize.Large}
            variant={ButtonVariant.Primary}
            shape={ButtonShape.Pill}
            onClick={handleSave}
          >
            Save
          </Button>
        </ButtonRow>
      </Content>
    </Modal>
  );
});
