'use client';

import { useState, useEffect } from 'react';
import { useParams, useRouter } from 'next/navigation';
import AppLayout from '../../../../components/layout/AppLayout';
import { Input, Textarea } from '../../../../components/ui/Input';
import Button from '../../../../components/ui/Button';
import TagInput from '../../../../components/stories/TagInput';
import TagSuggestions from '../../../../components/tags/TagSuggestions';
import SlateEditor from '../../../../components/stories/SlateEditor';
import ImageUpload from '../../../../components/ui/ImageUpload';
import AuthorSelector from '../../../../components/stories/AuthorSelector';
import SeriesSelector from '../../../../components/stories/SeriesSelector';
import LoadingSpinner from '../../../../components/ui/LoadingSpinner';
import ConfirmDialog from '../../../../components/ui/ConfirmDialog';
import { storyApi } from '../../../../lib/api';
import { Story } from '../../../../types/api';

export default function EditStoryPage() {
  const params = useParams();
  const router = useRouter();
  const storyId = params.id as string;
  
  const [story, setStory] = useState<Story | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [processingImages, setProcessingImages] = useState(false);
  const [resetingPosition, setResetingPosition] = useState(false);
  const [errors, setErrors] = useState<Record<string, string>>({});
  const [confirmDialog, setConfirmDialog] = useState<{ type: 'delete' | 'reset' } | null>(null);
  
  const [formData, setFormData] = useState({
    title: '',
    summary: '',
    authorName: '',
    authorId: undefined as string | undefined,
    contentHtml: '',
    sourceUrl: '',
    tags: [] as string[],
    seriesName: '',
    seriesId: undefined as string | undefined,
    volume: '',
  });
  
  const [coverImage, setCoverImage] = useState<File | null>(null);

  // Helper function to detect external images in HTML content
  const hasExternalImages = (htmlContent: string): boolean => {
    if (!htmlContent) return false;

    // Create a temporary DOM element to parse HTML
    const tempDiv = document.createElement('div');
    tempDiv.innerHTML = htmlContent;

    const images = tempDiv.querySelectorAll('img');
    for (let i = 0; i < images.length; i++) {
      const img = images[i];
      const src = img.getAttribute('src');
      if (src && (src.startsWith('http://') || src.startsWith('https://'))) {
        return true;
      }
    }
    return false;
  };

  useEffect(() => {
    const loadStory = async () => {
      try {
        setLoading(true);
        const storyData = await storyApi.getStory(storyId);
        setStory(storyData);
        
        // Initialize form with story data
        setFormData({
          title: storyData.title,
          summary: storyData.summary || '',
          authorName: storyData.authorName,
          authorId: storyData.authorId,
          contentHtml: storyData.contentHtml,
          sourceUrl: storyData.sourceUrl || '',
          tags: storyData.tags?.map(tag => tag.name) || [],
          seriesName: storyData.seriesName || '',
          seriesId: storyData.seriesId,
          volume: storyData.volume?.toString() || '',
        });
      } catch (error) {
        console.error('Failed to load story:', error);
        router.push('/library');
      } finally {
        setLoading(false);
      }
    };

    if (storyId) {
      loadStory();
    }
  }, [storyId, router]);

  const handleInputChange = (field: string) => (
    e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
  ) => {
    setFormData(prev => ({
      ...prev,
      [field]: e.target.value
    }));
    
    // Clear error when user starts typing
    if (errors[field]) {
      setErrors(prev => ({ ...prev, [field]: '' }));
    }
  };

  const handleContentChange = (html: string) => {
    setFormData(prev => ({ ...prev, contentHtml: html }));
    if (errors.contentHtml) {
      setErrors(prev => ({ ...prev, contentHtml: '' }));
    }
  };

  const handleTagsChange = (tags: string[]) => {
    setFormData(prev => ({ ...prev, tags }));
  };

  const handleAddSuggestedTag = (tagName: string) => {
    if (!formData.tags.includes(tagName.toLowerCase())) {
      setFormData(prev => ({ 
        ...prev, 
        tags: [...prev.tags, tagName.toLowerCase()] 
      }));
    }
  };

  const handleAuthorChange = (authorName: string, authorId?: string) => {
    setFormData(prev => ({ 
      ...prev, 
      authorName,
      authorId: authorId // This will be undefined if creating new author, which clears the existing ID
    }));
    
    // Clear error when user changes author
    if (errors.authorName) {
      setErrors(prev => ({ ...prev, authorName: '' }));
    }
  };

  const handleSeriesChange = (seriesName: string, seriesId?: string) => {
    setFormData(prev => ({ 
      ...prev, 
      seriesName,
      seriesId: seriesId // This will be undefined if creating new series, which clears the existing ID
    }));
    
    // Clear error when user changes series
    if (errors.seriesName) {
      setErrors(prev => ({ ...prev, seriesName: '' }));
    }
  };

  const validateForm = () => {
    const newErrors: Record<string, string> = {};

    if (!formData.title.trim()) {
      newErrors.title = 'Title is required';
    }
    
    if (!formData.authorName.trim()) {
      newErrors.authorName = 'Author name is required';
    }
    
    if (!formData.contentHtml.trim()) {
      newErrors.contentHtml = 'Story content is required';
    }

    if (formData.seriesName && !formData.volume) {
      newErrors.volume = 'Volume number is required when series is specified';
    }
    
    if (formData.volume && !formData.seriesName.trim()) {
      newErrors.seriesName = 'Series name is required when volume is specified';
    }

    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();

    if (!validateForm() || !story) {
      return;
    }

    setSaving(true);

    try {
      // Update the story with JSON data
      const updateData = {
        title: formData.title,
        summary: formData.summary || undefined,
        contentHtml: formData.contentHtml,
        sourceUrl: formData.sourceUrl || undefined,
        volume: formData.seriesName && formData.volume ? parseFloat(formData.volume) : undefined,
        // Send seriesId if we have it (existing series), otherwise send seriesName (new/changed series)
        ...(formData.seriesId ? { seriesId: formData.seriesId } : { seriesName: formData.seriesName }),
        // Send authorId if we have it (existing author), otherwise send authorName (new/changed author)
        ...(formData.authorId ? { authorId: formData.authorId } : { authorName: formData.authorName }),
        tagNames: formData.tags,
      };

      await storyApi.updateStory(storyId, updateData);

      // Process external images if present (download and replace URLs)
      if (hasExternalImages(formData.contentHtml)) {
        try {
          setProcessingImages(true);
          const imageResult = await storyApi.processContentImages(storyId, formData.contentHtml);

          // If images were processed and content was updated, save the updated content
          if (imageResult.processedContent !== formData.contentHtml) {
            await storyApi.updateStory(storyId, {
              title: formData.title,
              summary: formData.summary || undefined,
              contentHtml: imageResult.processedContent,
              sourceUrl: formData.sourceUrl || undefined,
              volume: formData.seriesName && formData.volume ? parseFloat(formData.volume) : undefined,
              ...(formData.seriesId ? { seriesId: formData.seriesId } : { seriesName: formData.seriesName }),
              ...(formData.authorId ? { authorId: formData.authorId } : { authorName: formData.authorName }),
              tagNames: formData.tags,
            });
            // Keep editor state in sync with local URLs so subsequent saves don't re-download
            setFormData(prev => ({ ...prev, contentHtml: imageResult.processedContent }));
          }
        } catch (imageError) {
          console.warn('Failed to process images, continuing with original content:', imageError);
          // Don't fail the entire save if image processing fails
        } finally {
          setProcessingImages(false);
        }
      }

      // If there's a new cover image, upload it separately
      if (coverImage) {
        await storyApi.uploadCover(storyId, coverImage);
      }

      router.push(`/stories/${storyId}/detail`);
    } catch (error: any) {
      console.error('Failed to update story:', error);
      const errorMessage = error.response?.data?.message || 'Failed to update story';
      setErrors({ submit: errorMessage });
    } finally {
      setSaving(false);
      setProcessingImages(false);
    }
  };

  const handleResetReadingPosition = () => {
    if (!story || !story.readingPosition || story.readingPosition === 0) return;
    setConfirmDialog({ type: 'reset' });
  };

  const confirmResetReadingPosition = async () => {
    setConfirmDialog(null);
    try {
      setResetingPosition(true);
      await storyApi.updateReadingProgress(storyId, 0);
      setStory(prev => prev ? { ...prev, readingPosition: 0 } : null);
      setErrors({ resetSuccess: 'Reading position reset! The story will start from the beginning next time you read it.' });
      setTimeout(() => {
        setErrors(prev => {
          const { resetSuccess, ...rest } = prev;
          return rest;
        });
      }, 4000);
    } catch (error) {
      console.error('Failed to reset reading position:', error);
      setErrors({ submit: 'Failed to reset reading position' });
    } finally {
      setResetingPosition(false);
    }
  };

  const handleDelete = () => {
    if (!story) return;
    setConfirmDialog({ type: 'delete' });
  };

  const confirmDelete = async () => {
    setConfirmDialog(null);
    try {
      setSaving(true);
      await storyApi.deleteStory(storyId);
      router.push('/library');
    } catch (error) {
      console.error('Failed to delete story:', error);
      setErrors({ submit: 'Failed to delete story' });
    } finally {
      setSaving(false);
    }
  };

  if (loading) {
    return (
      <AppLayout>
        <div className="flex items-center justify-center py-20">
          <LoadingSpinner size="lg" />
        </div>
      </AppLayout>
    );
  }

  if (!story) {
    return (
      <AppLayout>
        <div className="text-center py-20">
          <h1 className="text-2xl font-bold theme-header mb-4">Story Not Found</h1>
          <Button href="/library">Back to Library</Button>
        </div>
      </AppLayout>
    );
  }

  return (
    <AppLayout>
      <div className="max-w-4xl mx-auto">
        <div className="mb-8">
          <h1 className="text-3xl font-bold theme-header">Edit Story</h1>
          <p className="theme-text mt-2">
            Make changes to &quot;{story.title}&quot;
          </p>
        </div>

        <form onSubmit={handleSubmit} className="space-y-6">
          {/* Title */}
          <Input
            label="Title *"
            value={formData.title}
            onChange={handleInputChange('title')}
            placeholder="Enter the story title"
            error={errors.title}
            required
          />

          {/* Author Selector */}
          <AuthorSelector
            label="Author *"
            value={formData.authorName}
            onChange={handleAuthorChange}
            placeholder="Select or enter author name"
            error={errors.authorName}
            required
          />

          {/* Summary */}
          <div>
            <label className="block text-sm font-medium theme-header mb-2">
              Summary
            </label>
            <Textarea
              value={formData.summary}
              onChange={handleInputChange('summary')}
              placeholder="Brief summary or description of the story..."
              rows={3}
            />
            <p className="text-sm theme-text mt-1">
              Optional summary that will be displayed on the story detail page
            </p>
          </div>

          {/* Cover Image Upload */}
          <div>
            <label className="block text-sm font-medium theme-header mb-2">
              Cover Image
            </label>
            <ImageUpload
              onImageSelect={setCoverImage}
              accept="image/jpeg,image/png"
              maxSizeMB={5}
              aspectRatio="3:4"
              placeholder="Drop a new cover image here or click to select"
            />
            {story.coverPath && !coverImage && (
              <p className="text-sm theme-text mt-2">
                Current cover will be kept unless you upload a new one.
              </p>
            )}
          </div>

          {/* Content */}
          <div>
            <label className="block text-sm font-medium theme-header mb-2">
              Story Content *
            </label>
            <SlateEditor
              value={formData.contentHtml}
              onChange={handleContentChange}
              placeholder="Edit your story content here..."
              error={errors.contentHtml}
              storyId={storyId}
              enableImageProcessing={true}
            />
          </div>

          {/* Tags */}
          <div>
            <label className="block text-sm font-medium theme-header mb-2">
              Tags
            </label>
            <TagInput
              tags={formData.tags}
              onChange={handleTagsChange}
              placeholder="Edit tags to categorize your story..."
            />
            
            {/* Tag Suggestions */}
            <TagSuggestions
              title={formData.title}
              content={formData.contentHtml}
              summary={formData.summary}
              currentTags={formData.tags}
              onAddTag={handleAddSuggestedTag}
              disabled={saving}
            />
          </div>

          {/* Series and Volume */}
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div>
              <SeriesSelector
                label="Series (optional)"
                value={formData.seriesName}
                onChange={handleSeriesChange}
                placeholder="Select or enter series name if part of a series"
                error={errors.seriesName}
                authorId={formData.authorId}
              />
            </div>
            
            <Input
              label="Volume/Part (optional)"
              type="number"
              min="0.1"
              step="any"
              value={formData.volume}
              onChange={handleInputChange('volume')}
              placeholder="Enter volume/part number"
              error={errors.volume}
              disabled={!formData.seriesName}
            />
          </div>

          {/* Source URL */}
          <Input
            label="Source URL (optional)"
            type="url"
            value={formData.sourceUrl}
            onChange={handleInputChange('sourceUrl')}
            placeholder="https://example.com/original-story-url"
          />

          {/* Reading Position Reset Section */}
          <div className="theme-card p-4 rounded-lg border theme-border">
            <div className="flex items-center justify-between">
              <div>
                <h3 className="text-sm font-medium theme-header">Reading Position</h3>
                <p className="text-sm theme-text mt-1">
                  {story?.readingPosition && story.readingPosition > 0
                    ? `Currently saved at position ${story.readingPosition.toLocaleString()}`
                    : 'No reading position saved (story will start from the beginning)'
                  }
                </p>
              </div>
              <Button
                type="button"
                variant="ghost"
                onClick={handleResetReadingPosition}
                loading={resetingPosition}
                disabled={saving || !story?.readingPosition || story.readingPosition === 0}
                className="text-orange-600 hover:text-orange-700 dark:text-orange-400 dark:hover:text-orange-300"
              >
                Reset to Beginning
              </Button>
            </div>
          </div>

          {/* Success Message */}
          {errors.resetSuccess && (
            <div className="p-4 bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg">
              <p className="text-green-800 dark:text-green-200">{errors.resetSuccess}</p>
            </div>
          )}

          {/* Submit Error */}
          {errors.submit && (
            <div className="p-4 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg">
              <p className="text-red-800 dark:text-red-200">{errors.submit}</p>
            </div>
          )}

          {/* Actions */}
          <div className="flex justify-between pt-6">
            <Button
              type="button"
              variant="ghost"
              onClick={handleDelete}
              disabled={saving || processingImages}
              className="text-red-600 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300"
            >
              Delete Story
            </Button>

            <div className="flex gap-4">
              <Button
                type="button"
                variant="ghost"
                onClick={() => router.push(`/stories/${storyId}`)}
                disabled={saving || processingImages}
              >
                Cancel
              </Button>

              <Button
                type="submit"
                loading={saving || processingImages}
                disabled={!formData.title || !formData.authorName || !formData.contentHtml}
              >
                {processingImages ? 'Processing images...' : 'Save Changes'}
              </Button>
            </div>
          </div>
        </form>
      </div>

      <ConfirmDialog
        isOpen={confirmDialog?.type === 'reset'}
        title="Reset Reading Position"
        message="Are you sure you want to reset the reading position to the beginning? This will remove your current place in the story."
        confirmLabel="Reset"
        onConfirm={confirmResetReadingPosition}
        onCancel={() => setConfirmDialog(null)}
      />

      <ConfirmDialog
        isOpen={confirmDialog?.type === 'delete'}
        title="Delete Story"
        message="Are you sure you want to delete this story? This action cannot be undone."
        confirmLabel="Delete"
        danger
        onConfirm={confirmDelete}
        onCancel={() => setConfirmDialog(null)}
      />
    </AppLayout>
  );
}