import { useEffect, useState } from 'react'
import { Link, useParams, useNavigate } from 'react-router-dom'
import { SearchableSelect } from '../components/SearchableSelect'
import { ImageCropper } from '../components/ImageCropper'
import { TagInput } from '../components/TagInput'
import { RichTextEditor } from '../components/RichTextEditor'
import { Breadcrumbs } from '../components/Breadcrumbs'
import { useToast } from '../context/ToastContext'
import { useT } from '../i18n/useT'
import { ApiError } from '../lib/api'
import {
  listBlogCategories,
  mapBlogCategoryToUi,
} from '../services/blogCategoryService'
import {
  resolveDataUrlToMediaId,
  resolveHtmlEmbeddedDataUrls,
} from '../services/mediaService'
import {
  createBlog,
  getBlog,
  mapBlogApiToFormState,
  updateBlog,
} from '../services/blogService'
import type { Category } from '../types/category'
import type { BlogPostType } from '../types/blog'
import { BLOG_TYPE_OPTIONS } from '../types/blog'
import { flattenCategories } from '../utils/categories'
import pageStyles from '../components/PageContent.module.css'
import styles from './AddNewProductPage.module.css'

export function AddNewBlogPage() {
  const { id } = useParams()
  const navigate = useNavigate()
  const { showToast } = useToast()
  const t = useT()
  const isEdit = Boolean(id)

  const [categories, setCategories] = useState<Category[]>([])
  const [type, setType] = useState<BlogPostType>('blog')
  const [categoryId, setCategoryId] = useState('')
  const [title, setTitle] = useState('')
  const [abstract, setAbstract] = useState('')
  const [mainTextHtml, setMainTextHtml] = useState('')
  const [titleImage, setTitleImage] = useState<string | null>(null)
  const [tags, setTags] = useState<string[]>([])
  const [featuredMediaId, setFeaturedMediaId] = useState<string | null>(null)
  const [loaded, setLoaded] = useState(!isEdit)
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [error, setError] = useState('')

  const categoryOptions = flattenCategories(categories)

  useEffect(() => {
    const controller = new AbortController()

    async function loadCategories() {
      try {
        const items = await listBlogCategories(controller.signal)
        setCategories(items.map(mapBlogCategoryToUi))
      } catch (err) {
        if (err instanceof DOMException && err.name === 'AbortError') return
        if (err instanceof ApiError) {
          setError(err.message)
        } else {
          setError(t('blog.categories.errorLoad'))
        }
      }
    }

    void loadCategories()
    return () => controller.abort()
  }, [])

  useEffect(() => {
    if (!isEdit || !id) return

    const controller = new AbortController()

    async function loadBlog() {
      setError('')
      try {
        const blog = await getBlog(id!, controller.signal)
        const form = mapBlogApiToFormState(blog)
        setType(form.type)
        setCategoryId(form.categoryId)
        setTitle(form.title)
        setAbstract(form.abstract)
        setMainTextHtml(form.mainTextHtml)
        setTitleImage(form.titleImage)
        setTags(form.tags)
        setFeaturedMediaId(form.featuredMediaId)
        setLoaded(true)
      } catch (err) {
        if (err instanceof DOMException && err.name === 'AbortError') return
        navigate('/blog/list', { replace: true })
      }
    }

    void loadBlog()
    return () => controller.abort()
  }, [isEdit, id, navigate])

  if (!loaded) return null

  async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault()
    setIsSubmitting(true)
    setError('')

    try {
      const nextFeaturedMediaId = await resolveDataUrlToMediaId(
        titleImage,
        'blog-title-image.jpg',
        featuredMediaId,
      )
      const resolvedMainTextHtml = await resolveHtmlEmbeddedDataUrls(mainTextHtml)

      const payload = {
        title: title.trim(),
        type,
        abstract: abstract.trim(),
        mainTextHtml: resolvedMainTextHtml,
        categoryId: categoryId || undefined,
        featuredMediaId: nextFeaturedMediaId ?? undefined,
        tags,
        status: 'published' as const,
      }

      if (isEdit && id) {
        await updateBlog(id, {
          ...payload,
          categoryId: categoryId || null,
          featuredMediaId: nextFeaturedMediaId,
        })
        showToast(t('blog.form.toast.updated'), 'success')
      } else {
        await createBlog(payload)
        showToast(t('blog.form.toast.created'), 'success')
      }

      navigate('/blog/list')
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message)
      } else if (err instanceof Error) {
        setError(err.message)
      } else {
        setError(t('blog.form.errorSave'))
      }
    } finally {
      setIsSubmitting(false)
    }
  }

  return (
    <main className={pageStyles.content}>
      <Breadcrumbs
        items={
          isEdit
            ? [
                { label: 'Dashboard', href: '/' },
                { label: 'Blog', href: '/blog' },
                { label: 'My Blogs', href: '/blog/list' },
                { label: 'Edit Blog' },
              ]
            : [
                { label: 'Dashboard', href: '/' },
                { label: 'Blog', href: '/blog' },
                { label: 'Add New Blog' },
              ]
        }
      />
      <div className={pageStyles.pageHeader}>
        <div>
          <h2 className={pageStyles.pageTitle}>
            {isEdit ? t('title.editBlog') : t('title.addBlog')}
          </h2>
          <p className={pageStyles.pageSubtitle}>
            {isEdit ? t('blog.form.edit.subtitle') : t('blog.form.add.subtitle')}
          </p>
        </div>
      </div>

      {error && (
        <div className={styles.error} role="alert">
          {error}
        </div>
      )}

      <form className={styles.form} onSubmit={handleSubmit}>
        <div className={styles.formGrid}>
          <div className={`${styles.field} ${styles.col3} ${styles.rowSpan3}`}>
            <label>{t('blog.form.titleImage')}</label>
            <ImageCropper
              value={titleImage}
              onChange={setTitleImage}
              aspect={3 / 2}
              uploadLabel={t('blog.form.uploadTitleImage')}
              hint={t('blog.form.cropHint')}
              changeLabel={t('blog.form.changeTitleImage')}
            />
          </div>

          <div className={`${styles.field} ${styles.col3}`}>
            <label htmlFor="blog-type">{t('blog.form.type')}</label>
            <select
              id="blog-type"
              value={type}
              onChange={(e) => setType(e.target.value as BlogPostType)}
              disabled={isSubmitting}
            >
              {BLOG_TYPE_OPTIONS.map((option) => (
                <option key={option.value} value={option.value}>
                  {t(
                    option.value === 'news'
                      ? 'blog.form.type.news'
                      : option.value === 'article'
                        ? 'blog.form.type.article'
                        : 'blog.form.type.blog',
                  )}
                </option>
              ))}
            </select>
          </div>

          <div className={`${styles.field} ${styles.col6Span}`}>
            <label>{t('blog.form.category')}</label>
            <SearchableSelect
              options={categoryOptions}
              value={categoryId}
              onChange={setCategoryId}
              placeholder={t('blog.form.categoryPlaceholder')}
            />
          </div>

          <div className={`${styles.field} ${styles.col9}`}>
            <label htmlFor="blog-title">{t('blog.form.title')}</label>
            <input
              id="blog-title"
              name="title"
              type="text"
              placeholder={t('blog.form.titlePlaceholder')}
              value={title}
              onChange={(e) => setTitle(e.target.value)}
              required
              disabled={isSubmitting}
            />
          </div>

          <div className={`${styles.field} ${styles.col9}`}>
            <label htmlFor="blog-abstract">{t('blog.form.abstract')}</label>
            <textarea
              id="blog-abstract"
              name="abstract"
              rows={4}
              placeholder={t('blog.form.abstractPlaceholder')}
              value={abstract}
              onChange={(e) => setAbstract(e.target.value)}
              required
              disabled={isSubmitting}
            />
          </div>

          <div className={`${styles.field} ${styles.col12}`}>
            <label>{t('blog.form.mainText')}</label>
            <RichTextEditor
              value={mainTextHtml}
              onChange={setMainTextHtml}
              placeholder={t('blog.form.mainTextPlaceholder')}
              allowImages
              editorMinHeight={320}
            />
          </div>

          <div className={`${styles.field} ${styles.col12}`}>
            <label>{t('blog.form.tags')}</label>
            <TagInput tags={tags} onChange={setTags} />
          </div>
        </div>

        <div className={styles.actions}>
          <Link to="/blog/list" className={styles.cancelBtn}>
            {t('blog.form.cancel')}
          </Link>
          <button type="submit" className={styles.submitBtn} disabled={isSubmitting}>
            {isSubmitting
              ? t('blog.form.saving')
              : isEdit
                ? t('blog.form.update')
                : t('blog.form.save')}
          </button>
        </div>
      </form>
    </main>
  )
}
