'use client'

import { FormEvent, useEffect, useMemo, useState } from 'react'
import { BlogPost, BlogPostSection, CATEGORY_LABELS, BlogCategory } from '@/types/blog'
import { resolveMediaUrl } from '@/lib/media'

function getCategoryLabel(category: string | null | undefined): string {
  if (!category) return 'None'

  // Try as slug first
  if (category in CATEGORY_LABELS) {
    return CATEGORY_LABELS[category as BlogCategory]
  }

  // Return as-is if it's already a display name
  return category
}

const MAX_SECTIONS = 5
const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:4005'

type SectionFormState = {
  id: string
  text: string
  imageFile: File | null
  existingImage?: string | null
  previewUrl?: string | null
}

type MainImageState = {
  file: File | null
  existing?: string | null
  previewUrl?: string | null
  removed: boolean
}

function createId(prefix: string = 'section') {
  if (typeof globalThis !== 'undefined' && globalThis.crypto && typeof globalThis.crypto.randomUUID === 'function') {
    return globalThis.crypto.randomUUID()
  }
  return `${prefix}-${Math.random().toString(36).slice(2, 11)}`
}

function createEmptySection(): SectionFormState {
  return {
    id: createId(),
    text: '',
    imageFile: null,
    existingImage: null,
    previewUrl: null
  }
}

function ensureSectionSlots(sections: SectionFormState[]): SectionFormState[] {
  const filled = [...sections]
  while (filled.length < MAX_SECTIONS) {
    filled.push(createEmptySection())
  }
  return filled.slice(0, MAX_SECTIONS)
}

function normaliseText(value: string) {
  return value.trim()
}

export default function AdminPage() {
  const [posts, setPosts] = useState<BlogPost[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [saving, setSaving] = useState(false)
  const [editingPost, setEditingPost] = useState<BlogPost | null>(null)
  const [showForm, setShowForm] = useState(false)

  const [title, setTitle] = useState('')
  const [linkUrl, setLinkUrl] = useState('')
  const [footer, setFooter] = useState('')
  const [isEditorsPick, setIsEditorsPick] = useState(false)
  const [category, setCategory] = useState<string>('')
  const [mainImage, setMainImage] = useState<MainImageState>({
    file: null,
    existing: null,
    previewUrl: null,
    removed: false
  })
  const [sections, setSections] = useState<SectionFormState[]>(ensureSectionSlots([]))

  const editorsPickCount = useMemo(
    () => posts.filter(post => post.isEditorsPick).length,
    [posts]
  )

  useEffect(() => {
    loadPosts()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  async function loadPosts() {
    setLoading(true)
    setError(null)
    try {
      const response = await fetch(`${API_BASE_URL}/posts`)
      if (!response.ok) {
        throw new Error(`Failed to load posts (${response.status})`)
      }
      const payload = await response.json()
      setPosts(Array.isArray(payload.data) ? payload.data : [])
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load posts')
    } finally {
      setLoading(false)
    }
  }

  function resetForm() {
    setTitle('')
    setLinkUrl('')
    setFooter('')
    setIsEditorsPick(false)
    setCategory('')
    setMainImage({ file: null, existing: null, previewUrl: null, removed: false })
    setSections(ensureSectionSlots([]))
    setEditingPost(null)
    setShowForm(false)
  }

  function populateForm(post: BlogPost) {
    setTitle(post.title)
    setLinkUrl(post.linkUrl || '')
    setFooter(post.footer || '')
    setIsEditorsPick(post.isEditorsPick)

    // Convert old format to new format
    const categoryMap: Record<string, string> = {
      'Books & Magazine': 'books-magazine',
      'Clothing & Shoes': 'clothing-shoes',
      'Collectibles & Art': 'collectibles-art',
      'Toys & Hobbies': 'toys-hobbies'
    }
    const normalizedCategory = post.category ? (categoryMap[post.category] || post.category) : ''
    setCategory(normalizedCategory)
    setMainImage({
      file: null,
      existing: post.previewImage || null,
      previewUrl: resolveMediaUrl(post.previewImage) || null,
      removed: !post.previewImage
    })

    const filledSections = ensureSectionSlots(
      post.sections.map((section: BlogPostSection): SectionFormState => ({
        id: section.id || createId(),
        text: section.text || '',
        imageFile: null,
        existingImage: section.image || null,
        previewUrl: resolveMediaUrl(section.image) || null
      }))
    )
    setSections(filledSections)
  }

  function handleStartCreate() {
    resetForm()
    setShowForm(true)
  }

  function handleEdit(post: BlogPost) {
    setEditingPost(post)
    populateForm(post)
    setShowForm(true)
  }

  function handleMainImageChange(fileList: FileList | null) {
    if (!fileList || fileList.length === 0) {
      setMainImage(prev => ({ ...prev, file: null, previewUrl: resolveMediaUrl(prev.existing) || null, removed: false }))
      return
    }
    const nextFile = fileList[0]
    const previewUrl = URL.createObjectURL(nextFile)
    setMainImage(prev => {
      if (prev.previewUrl && prev.previewUrl.startsWith('blob:')) {
        URL.revokeObjectURL(prev.previewUrl)
      }
      return {
        file: nextFile,
        existing: prev.existing,
        previewUrl,
        removed: false
      }
    })
  }

  function handleRemoveMainImage() {
    setMainImage(prev => {
      if (prev.previewUrl && prev.previewUrl.startsWith('blob:')) {
        URL.revokeObjectURL(prev.previewUrl)
      }
      return {
        file: null,
        existing: null,
        previewUrl: null,
        removed: true
      }
    })
  }

  function updateSection(index: number, partial: Partial<SectionFormState>) {
    setSections(current => {
      const clone = [...current]
      const next = { ...clone[index], ...partial }
      clone[index] = next
      return ensureSectionSlots(clone)
    })
  }

  function handleSectionTextChange(index: number, value: string) {
    updateSection(index, { text: value })
  }

  function handleSectionImageChange(index: number, fileList: FileList | null) {
    setSections(current => {
      const clone = [...current]
      const target = { ...clone[index] }

      if (target.previewUrl && target.previewUrl.startsWith('blob:')) {
        URL.revokeObjectURL(target.previewUrl)
      }

      if (!fileList || fileList.length === 0) {
        target.imageFile = null
        target.previewUrl = resolveMediaUrl(target.existingImage) || null
      } else {
        const file = fileList[0]
        target.imageFile = file
        target.previewUrl = URL.createObjectURL(file)
      }

      clone[index] = target
      return ensureSectionSlots(clone)
    })
  }

  function handleRemoveSectionImage(index: number) {
    updateSection(index, {
      imageFile: null,
      existingImage: null,
      previewUrl: null
    })
  }

  async function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault()

    const trimmedTitle = normaliseText(title)
    if (!trimmedTitle) {
      setError('Title is required')
      return
    }

    setSaving(true)
    setError(null)

    try {
      const formData = new FormData()

      if (mainImage.file) {
        formData.append('mainImage', mainImage.file)
      }

      sections.forEach((section, index) => {
        if (section.imageFile) {
          formData.append(`section${index}Image`, section.imageFile)
        }
      })

      const payload = {
        title: trimmedTitle,
        linkUrl: normaliseText(linkUrl) || undefined,
        footer: normaliseText(footer) || undefined,
        isEditorsPick,
        category: category || undefined,
        existingMainImage: mainImage.file || mainImage.removed ? undefined : mainImage.existing,
        removeMainImage: mainImage.removed,
        sections: sections.map(section => ({
          id: section.id,
          text: normaliseText(section.text) || undefined,
          existingImage: section.imageFile ? undefined : section.existingImage || undefined
        }))
      }

      formData.append('payload', JSON.stringify(payload))

      const method = editingPost ? 'PUT' : 'POST'
      const endpoint = editingPost
        ? `${API_BASE_URL}/posts/${editingPost.id}`
        : `${API_BASE_URL}/posts`

      const response = await fetch(endpoint, {
        method,
        body: formData
      })

      const body = await response.json().catch(() => null)
      if (!response.ok) {
        const message = body?.error || 'Failed to save blog post'
        throw new Error(message)
      }

      await loadPosts()
      resetForm()
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Unable to save blog post')
    } finally {
      setSaving(false)
    }
  }

  async function handleDelete(postId: number) {
    if (!window.confirm('Delete this blog post?')) {
      return
    }
    setError(null)
    try {
      const response = await fetch(`${API_BASE_URL}/posts/${postId}`, {
        method: 'DELETE'
      })
      if (!response.ok) {
        const payload = await response.json().catch(() => null)
        throw new Error(payload?.error || 'Failed to delete post')
      }
      await loadPosts()
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Unable to delete blog post')
    }
  }

  async function handleToggleEditorsPick(post: BlogPost) {
    setError(null)
    try {
      const response = await fetch(`${API_BASE_URL}/posts/${post.id}/editors-pick`, {
        method: 'PATCH',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ isEditorsPick: !post.isEditorsPick })
      })
      const payload = await response.json().catch(() => null)
      if (!response.ok) {
        throw new Error(payload?.error || 'Failed to update editor pick')
      }
      await loadPosts()
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Unable to update editor pick')
    }
  }

  return (
    <div style={{ padding: '32px', maxWidth: '1200px', margin: '0 auto' }}>
      <header style={{ marginBottom: '32px' }}>
        <h1
          style={{
            fontFamily: 'Abril Fatface, serif',
            fontSize: '48px',
            marginBottom: '12px'
          }}
        >
          Admin - Blog Management
        </h1>
        <p
          style={{
            fontFamily: 'Spectral, serif',
            fontSize: '18px',
            lineHeight: 1.6,
            color: '#4A4A4A'
          }}
        >
          Create, edit, and curate your blog posts. You can select up to three Editor's Picks. The most recently published entry is automatically highlighted as the "Last Blog Post" on the homepage.
        </p>
      </header>

      {error && (
        <div
          style={{
            marginBottom: '24px',
            padding: '16px',
            border: '1px solid #c0392b',
            backgroundColor: '#fceaea',
            color: '#c0392b',
            fontFamily: 'Space Mono, monospace'
          }}
        >
          {error}
        </div>
      )}

      <section style={{ marginBottom: '40px' }}>
        <div
          style={{
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'center',
            marginBottom: '16px'
          }}
        >
          <h2 style={{ fontFamily: 'Space Mono, monospace', letterSpacing: '0.2em' }}>
            Posts Overview
          </h2>
          <button
            type="button"
            onClick={handleStartCreate}
            style={{
              padding: '10px 18px',
              border: '2px solid #8B7D6B',
              backgroundColor: '#1E1A17',
              color: '#F7F1E1',
              fontFamily: 'Space Mono, monospace',
              letterSpacing: '0.15em',
              textTransform: 'uppercase',
              cursor: 'pointer'
            }}
          >
            New Blog Post
          </button>
        </div>

        <div style={{ marginBottom: '12px', fontFamily: 'Space Mono, monospace', fontSize: '12px' }}>
          Editor's Picks selected: {editorsPickCount} / 3
        </div>

        {loading ? (
          <p style={{ fontFamily: 'Spectral, serif' }}>Loading posts...</p>
        ) : posts.length === 0 ? (
          <p style={{ fontFamily: 'Spectral, serif' }}>No posts yet. Create your first story.</p>
        ) : (
          <table
            style={{
              width: '100%',
              borderCollapse: 'collapse',
              backgroundColor: 'white',
              border: '1px solid #8B7D6B'
            }}
          >
            <thead style={{ backgroundColor: '#F7F1E1' }}>
              <tr>
                <th style={{ padding: '12px', borderBottom: '1px solid #8B7D6B', textAlign: 'left' }}>Title</th>
                <th style={{ padding: '12px', borderBottom: '1px solid #8B7D6B', textAlign: 'left' }}>Created</th>
                <th style={{ padding: '12px', borderBottom: '1px solid #8B7D6B' }}>Editor's Pick</th>
                <th style={{ padding: '12px', borderBottom: '1px solid #8B7D6B' }}>Actions</th>
              </tr>
            </thead>
            <tbody>
              {posts.map(post => (
                <tr key={post.id}>
                  <td style={{ padding: '12px', borderBottom: '1px solid #E0D7C6' }}>{post.title}</td>
                  <td style={{ padding: '12px', borderBottom: '1px solid #E0D7C6' }}>
                    {new Date(post.createdAt).toLocaleString()}
                  </td>
                  <td style={{ padding: '12px', borderBottom: '1px solid #E0D7C6', textAlign: 'center' }}>
                    <button
                      type="button"
                      onClick={() => handleToggleEditorsPick(post)}
                      style={{
                        padding: '6px 10px',
                        border: '1px solid #8B7D6B',
                        backgroundColor: post.isEditorsPick ? '#C89C2B' : 'transparent',
                        color: post.isEditorsPick ? '#F7F1E1' : '#1E1A17',
                        fontFamily: 'Space Mono, monospace',
                        fontSize: '11px',
                        letterSpacing: '0.1em',
                        textTransform: 'uppercase',
                        cursor: 'pointer'
                      }}
                    >
                      {post.isEditorsPick ? 'Selected' : 'Select'}
                    </button>
                  </td>
                  <td style={{ padding: '12px', borderBottom: '1px solid #E0D7C6', textAlign: 'center' }}>
                    <button
                      type="button"
                      onClick={() => handleEdit(post)}
                      style={{
                        marginRight: '8px',
                        padding: '6px 12px',
                        border: '1px solid #8B7D6B',
                        backgroundColor: '#F7F1E1',
                        cursor: 'pointer'
                      }}
                    >
                      Edit
                    </button>
                    <button
                      type="button"
                      onClick={() => handleDelete(post.id)}
                      style={{
                        padding: '6px 12px',
                        border: '1px solid #c0392b',
                        backgroundColor: '#c0392b',
                        color: '#fff',
                        cursor: 'pointer'
                      }}
                    >
                      Delete
                    </button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </section>

      {showForm && (
        <section
          style={{
            border: '2px solid #8B7D6B',
            padding: '24px',
            backgroundColor: '#F7F1E1',
            marginBottom: '40px'
          }}
        >
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <h2 style={{ fontFamily: 'Space Mono, monospace', letterSpacing: '0.2em' }}>
              {editingPost ? 'Edit Blog Post' : 'Create Blog Post'}
            </h2>
            <button
              type="button"
              onClick={resetForm}
              style={{
                border: 'none',
                background: 'transparent',
                fontSize: '20px',
                cursor: 'pointer'
              }}
              aria-label="Close form"
            >
              X
            </button>
          </div>

          <form onSubmit={handleSubmit}>
            <div style={{ display: 'grid', gap: '18px', marginTop: '24px' }}>
              <label style={{ display: 'grid', gap: '8px' }}>
                <span style={{ fontFamily: 'Space Mono, monospace', fontSize: '12px', letterSpacing: '0.15em' }}>
                  Title
                </span>
                <input
                  type="text"
                  value={title}
                  onChange={(event) => setTitle(event.target.value)}
                  required
                  style={{ padding: '12px', border: '1px solid #8B7D6B' }}
                />
              </label>

              <label style={{ display: 'grid', gap: '8px' }}>
                <span style={{ fontFamily: 'Space Mono, monospace', fontSize: '12px', letterSpacing: '0.15em' }}>
                  Main Picture (Preview Image)
                </span>
                <input
                  type="file"
                  accept="image/*"
                  onChange={(event) => handleMainImageChange(event.target.files)}
                />
                {(mainImage.previewUrl || mainImage.existing) && (
                  <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
                    {mainImage.previewUrl && (
                      <img
                        src={mainImage.previewUrl}
                        alt="Preview"
                        style={{ width: '120px', height: 'auto', border: '1px solid #8B7D6B' }}
                      />
                    )}
                    <button
                      type="button"
                      onClick={handleRemoveMainImage}
                      style={{
                        padding: '6px 10px',
                        border: '1px solid #8B7D6B',
                        background: 'transparent',
                        cursor: 'pointer'
                      }}
                    >
                      Remove image
                    </button>
                  </div>
                )}
              </label>

              <label style={{ display: 'grid', gap: '8px' }}>
                <span style={{ fontFamily: 'Space Mono, monospace', fontSize: '12px', letterSpacing: '0.15em' }}>
                  Product Link (optional)
                </span>
                <input
                  type="url"
                  value={linkUrl}
                  placeholder="https://"
                  onChange={(event) => setLinkUrl(event.target.value)}
                  style={{ padding: '12px', border: '1px solid #8B7D6B' }}
                />
              </label>

              {sections.map((section, index) => (
                <div
                  key={section.id}
                  style={{
                    borderTop: index === 0 ? 'none' : '1px dashed #8B7D6B',
                    paddingTop: index === 0 ? 0 : '18px'
                  }}
                >
                  <h3 style={{ fontFamily: 'Space Mono, monospace', letterSpacing: '0.15em', fontSize: '12px' }}>
                    Section {index + 1}
                  </h3>
                  <div style={{ display: 'grid', gap: '12px', marginTop: '12px' }}>
                    <textarea
                      value={section.text}
                      onChange={(event) => handleSectionTextChange(index, event.target.value)}
                      placeholder="Text"
                      rows={4}
                      style={{ padding: '12px', border: '1px solid #8B7D6B', resize: 'vertical' }}
                    />
                    <input
                      type="file"
                      accept="image/*"
                      onChange={(event) => handleSectionImageChange(index, event.target.files)}
                    />
                    {(section.previewUrl || section.existingImage) && (
                      <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
                        {section.previewUrl && (
                          <img
                            src={section.previewUrl}
                            alt="Section preview"
                            style={{ width: '120px', height: 'auto', border: '1px solid #8B7D6B' }}
                          />
                        )}
                        <button
                          type="button"
                          onClick={() => handleRemoveSectionImage(index)}
                          style={{
                            padding: '6px 10px',
                            border: '1px solid #8B7D6B',
                            background: 'transparent',
                            cursor: 'pointer'
                          }}
                        >
                          Remove image
                        </button>
                      </div>
                    )}
                  </div>
                </div>
              ))}

              <label style={{ display: 'grid', gap: '8px' }}>
                <span style={{ fontFamily: 'Space Mono, monospace', fontSize: '12px', letterSpacing: '0.15em' }}>
                  Possible Footer (optional)
                </span>
                <textarea
                  value={footer}
                  onChange={(event) => setFooter(event.target.value)}
                  rows={3}
                  style={{ padding: '12px', border: '1px solid #8B7D6B', resize: 'vertical' }}
                />
              </label>

              <label style={{ display: 'grid', gap: '8px' }}>
                <span style={{ fontFamily: 'Space Mono, monospace', fontSize: '12px', letterSpacing: '0.15em' }}>
                  Category (optional)
                </span>
                <select
                  value={category}
                  onChange={(event) => setCategory(event.target.value)}
                  style={{ padding: '12px', border: '1px solid #8B7D6B', backgroundColor: 'white' }}
                >
                  <option value="">-- Select Category --</option>
                  <option value="books-magazine">Books & Magazine</option>
                  <option value="clothing-shoes">Clothing & Shoes</option>
                  <option value="collectibles-art">Collectibles & Art</option>
                  <option value="toys-hobbies">Toys & Hobbies</option>
                </select>
              </label>

              <label style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
                <input
                  type="checkbox"
                  checked={isEditorsPick}
                  onChange={(event) => setIsEditorsPick(event.target.checked)}
                />
                <span style={{ fontFamily: 'Space Mono, monospace', fontSize: '12px', letterSpacing: '0.15em' }}>
                  Mark as Editor's Pick (max 3)
                </span>
              </label>

              <div style={{ display: 'flex', gap: '12px' }}>
                <button
                  type="submit"
                  disabled={saving}
                  style={{
                    padding: '12px 24px',
                    border: '2px solid #8B7D6B',
                    backgroundColor: '#1E1A17',
                    color: '#F7F1E1',
                    fontFamily: 'Space Mono, monospace',
                    letterSpacing: '0.2em',
                    textTransform: 'uppercase',
                    cursor: 'pointer',
                    opacity: saving ? 0.7 : 1
                  }}
                >
                  {saving ? 'Saving...' : editingPost ? 'Save Changes' : 'Publish Post'}
                </button>
                <button
                  type="button"
                  onClick={resetForm}
                  style={{
                    padding: '12px 24px',
                    border: '2px solid #8B7D6B',
                    backgroundColor: 'transparent',
                    fontFamily: 'Space Mono, monospace',
                    letterSpacing: '0.2em',
                    textTransform: 'uppercase',
                    cursor: 'pointer'
                  }}
                >
                  Cancel
                </button>
              </div>
            </div>
          </form>
        </section>
      )}
    </div>
  )
}









