import React, { useEffect, useMemo, useRef, useState } from 'react'
import { Head, Link, router, useForm } from '@inertiajs/react'
import AdminLayout from '../../../Layouts/AdminLayout'
import DateTimePicker from '../../../components/ui/DateTimePicker'
import NovaSelect from '../../../components/ui/NovaSelect'
import LessonEditor from './LessonEditor'

function normalizePayload(fields, data) {
  const payload = { ...data }

  fields.forEach((field) => {
    if (field.type === 'csv') {
      payload[field.name] = String(payload[field.name] || '')
        .split(/[,\n]/)
        .map((item) => item.trim())
        .filter(Boolean)
    }

    if (field.type === 'json') {
      try {
        payload[field.name] = payload[field.name] ? JSON.parse(payload[field.name]) : {}
      } catch {
        payload[field.name] = {}
      }
    }
  })

  return payload
}

function getField(fields, name) {
  return fields.find((field) => field.name === name) || null
}

function SectionCard({ eyebrow, title, description, children, className = '' }) {
  return (
    <section className={`w-full min-w-0 rounded-[32px] border border-white/10 bg-white/[0.04] p-6 shadow-[0_20px_80px_rgba(15,23,42,0.18)] ${className}`.trim()}>
      <div className="mb-5">
        {eyebrow ? <p className="text-[11px] font-semibold uppercase tracking-[0.24em] text-sky-200/80">{eyebrow}</p> : null}
        <h2 className="mt-2 text-xl font-semibold tracking-[-0.04em] text-white">{title}</h2>
        {description ? <p className="mt-2 text-sm leading-7 text-slate-400">{description}</p> : null}
      </div>
      <div className="grid gap-5">{children}</div>
    </section>
  )
}

function TextField({ label, value, onChange, error, ...rest }) {
  return (
    <label className="grid gap-2 text-sm text-slate-200">
      <span>{label}</span>
      <input value={value ?? ''} onChange={onChange} className="rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-white outline-none" {...rest} />
      {error ? <p className="text-xs text-rose-300">{error}</p> : null}
    </label>
  )
}

function TextAreaField({ label, value, onChange, error, rows = 6, hint }) {
  return (
    <label className="grid gap-2 text-sm text-slate-200">
      <span>{label}</span>
      <textarea value={value ?? ''} onChange={onChange} rows={rows} className="rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm leading-7 text-white outline-none" />
      {hint ? <span className="text-xs leading-5 text-slate-500">{hint}</span> : null}
      {error ? <p className="text-xs text-rose-300">{error}</p> : null}
    </label>
  )
}

function ToggleField({ label, checked, onChange, help, error }) {
  return (
    <label className="flex items-start gap-3 rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-slate-200">
      <input type="checkbox" checked={Boolean(checked)} onChange={onChange} className="mt-1" />
      <span>
        <span className="block font-semibold text-white">{label}</span>
        {help ? <span className="mt-1 block text-xs leading-5 text-slate-400">{help}</span> : null}
        {error ? <span className="mt-2 block text-xs text-rose-300">{error}</span> : null}
      </span>
    </label>
  )
}

function Field({ field, form }) {
  const value = form.data[field.name]

  if (field.type === 'checkbox') {
    return (
      <label className="flex items-center gap-3 rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-slate-200">
        <input type="checkbox" checked={Boolean(value)} onChange={(event) => form.setData(field.name, event.target.checked)} />
        {field.label}
      </label>
    )
  }

  if (field.type === 'datetime-local') {
    return (
      <DateTimePicker
        label={field.label}
        value={value || ''}
        onChange={(nextValue) => form.setData(field.name, nextValue || '')}
        error={form.errors[field.name]}
        clearable
        className="bg-black/20"
      />
    )
  }

  if (field.type === 'textarea') {
    return (
      <label className="grid gap-2 text-sm text-slate-200">
        <span>{field.label}</span>
        <textarea
          value={value || ''}
          onChange={(event) => form.setData(field.name, event.target.value)}
          rows={field.rows || 6}
          className="rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm leading-7 text-white outline-none"
        />
        {form.errors[field.name] ? <p className="text-xs text-rose-300">{form.errors[field.name]}</p> : null}
      </label>
    )
  }

  if (field.type === 'select') {
    return (
      <NovaSelect
        label={field.label}
        value={value ?? ''}
        onChange={(nextValue) => form.setData(field.name, nextValue ?? '')}
        options={field.options || []}
        searchable={false}
        className="rounded-2xl bg-black/20"
        error={form.errors[field.name]}
      />
    )
  }

  if (field.type === 'multiselect') {
    return (
      <NovaSelect
        multi
        label={field.label}
        value={value || []}
        onChange={(nextValue) => form.setData(field.name, Array.isArray(nextValue) ? nextValue : [])}
        options={field.options || []}
        className="rounded-2xl bg-black/20"
        error={form.errors[field.name]}
      />
    )
  }

  return (
    <label className="grid gap-2 text-sm text-slate-200">
      <span>{field.label}</span>
      <input
        type={field.type || 'text'}
        value={value ?? ''}
        onChange={(event) => form.setData(field.name, event.target.value)}
        className="rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-white outline-none"
      />
      {form.errors[field.name] ? <p className="text-xs text-rose-300">{form.errors[field.name]}</p> : null}
    </label>
  )
}

function PromptPreviewDropzone({ form, previewUrl }) {
  const inputRef = useRef(null)
  const [dragging, setDragging] = useState(false)
  const [localPreviewUrl, setLocalPreviewUrl] = useState('')
  const [selectedFileName, setSelectedFileName] = useState('')

  const previewSrc = localPreviewUrl || previewUrl || form.data.preview_image || ''

  useEffect(() => () => {
    if (localPreviewUrl.startsWith('blob:')) {
      URL.revokeObjectURL(localPreviewUrl)
    }
  }, [localPreviewUrl])

  const setSelectedFile = (file) => {
    if (localPreviewUrl.startsWith('blob:')) {
      URL.revokeObjectURL(localPreviewUrl)
    }

    if (!file) {
      setLocalPreviewUrl('')
      setSelectedFileName('')
      form.setData('preview_image_file', null)
      form.clearErrors('preview_image_file')
      return
    }

    const nextPreviewUrl = URL.createObjectURL(file)
    setLocalPreviewUrl(nextPreviewUrl)
    setSelectedFileName(file.name)
    form.setData('preview_image_file', file)
    form.clearErrors('preview_image_file')
  }

  const clearSelection = () => {
    if (localPreviewUrl.startsWith('blob:')) {
      URL.revokeObjectURL(localPreviewUrl)
    }

    setLocalPreviewUrl('')
    setSelectedFileName('')
    form.setData('preview_image_file', null)
    form.clearErrors('preview_image_file')

    if (inputRef.current) {
      inputRef.current.value = ''
    }
  }

  return (
    <SectionCard
      eyebrow="Visual preview"
      title="Preview image"
      description="Drag an image here or paste a URL. Uploaded files are converted to WebP and stored on Contabo automatically."
    >
      <div
        role="button"
        tabIndex={0}
        onClick={() => inputRef.current?.click()}
        onKeyDown={(event) => {
          if (event.key === 'Enter' || event.key === ' ') {
            event.preventDefault()
            inputRef.current?.click()
          }
        }}
        onDragOver={(event) => {
          event.preventDefault()
          setDragging(true)
        }}
        onDragEnter={(event) => {
          event.preventDefault()
          setDragging(true)
        }}
        onDragLeave={(event) => {
          event.preventDefault()
          setDragging(false)
        }}
        onDrop={(event) => {
          event.preventDefault()
          setDragging(false)
          setSelectedFile(event.dataTransfer?.files?.[0] || null)
        }}
        className={[
          'w-full min-w-0 rounded-[28px] border border-dashed p-5 outline-none transition',
          dragging ? 'border-sky-300/50 bg-sky-400/10' : 'border-white/10 bg-black/20 hover:border-white/20 hover:bg-white/[0.04]',
        ].join(' ')}
      >
        <div className="flex flex-col gap-4">
          <div className="flex min-w-0 items-start gap-4">
            <div className="flex h-12 w-12 shrink-0 items-center justify-center rounded-2xl border border-sky-300/20 bg-sky-400/10 text-sky-100">
              <i className="fa-solid fa-image" />
            </div>
            <div className="min-w-0 flex-1">
              <div className="text-sm font-semibold text-white">Drop a preview image or browse</div>
              <div className="mt-1 text-xs leading-5 text-slate-400">JPG, PNG, or WEBP. The server re-encodes the final asset to WebP before uploading it to the CDN.</div>
              <div className="mt-2 flex flex-wrap gap-2 text-[11px] text-slate-400">
                <span className="rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1">JPG</span>
                <span className="rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1">PNG</span>
                <span className="rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1">WEBP</span>
                <span className="rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1">Max 5 MB</span>
              </div>
            </div>
          </div>

          <div className="grid w-full max-w-full gap-3">
            <div className="overflow-hidden rounded-[20px] border border-white/10 bg-slate-950">
              {previewSrc ? (
                <img src={previewSrc} alt="Prompt preview" className="h-40 w-full object-cover" />
              ) : (
                <div className="flex h-40 items-center justify-center px-4 text-center text-sm text-slate-500">No preview image selected</div>
              )}
            </div>
            <div className="flex gap-2">
              <button type="button" onClick={() => inputRef.current?.click()} className="flex-1 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2.5 text-sm font-semibold text-white transition hover:bg-white/[0.08]">Browse</button>
              {selectedFileName || localPreviewUrl ? <button type="button" onClick={clearSelection} className="rounded-full border border-white/10 bg-transparent px-4 py-2.5 text-sm font-semibold text-slate-300 transition hover:bg-white/[0.04]">Clear</button> : null}
            </div>
          </div>
        </div>

        <input
          ref={inputRef}
          type="file"
          accept="image/jpeg,image/png,image/webp"
          className="hidden"
          onChange={(event) => {
            setSelectedFile(event.target.files?.[0] || null)
            event.target.value = ''
          }}
        />

        <div className="mt-4 grid min-w-0 gap-3 md:grid-cols-1 lg:grid-cols-[minmax(0,1fr)_minmax(0,220px)]">
          <TextField
            label="Preview image URL fallback"
            value={form.data.preview_image || ''}
            onChange={(event) => form.setData('preview_image', event.target.value)}
            error={form.errors.preview_image}
            placeholder="Paste a URL or leave empty if you upload a file"
          />

          <div className="min-w-0 rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-xs leading-6 text-slate-300">
            <div className="font-semibold text-white">Stored value</div>
            <div className="mt-1 break-all text-slate-400">{form.data.preview_image_file?.name || form.data.preview_image || previewUrl || 'None yet'}</div>
          </div>
        </div>

        {form.errors.preview_image_file ? <p className="mt-3 text-sm text-rose-300">{form.errors.preview_image_file}</p> : null}
      </div>
    </SectionCard>
  )
}

function PromptEditor({ title, subtitle, fields, record, submitUrl, indexUrl, destroyUrl, method }) {
  const form = useForm({ ...record, preview_image_file: null })
  const categoryField = useMemo(() => getField(fields, 'category_id'), [fields])
  const difficultyField = useMemo(() => getField(fields, 'difficulty'), [fields])
  const accessField = useMemo(() => getField(fields, 'access_level'), [fields])
  const publishedAtField = useMemo(() => getField(fields, 'published_at'), [fields])
  const featuredField = useMemo(() => getField(fields, 'featured'), [fields])
  const promptOfWeekField = useMemo(() => getField(fields, 'prompt_of_week'), [fields])
  const activeField = useMemo(() => getField(fields, 'active'), [fields])
  const seoDescriptionField = useMemo(() => getField(fields, 'seo_description'), [fields])
  const previewUrl = form.data.preview_image_url || ''

  const submit = (event) => {
    event.preventDefault()
    const payload = normalizePayload(fields, form.data)
    form.transform(() => payload)

    if (method === 'patch') {
      form.patch(submitUrl)
      return
    }

    form.post(submitUrl)
  }

  const tagCount = String(form.data.tags || '')
    .split(/[,\n]/)
    .map((item) => item.trim())
    .filter(Boolean).length

  return (
    <AdminLayout title={title} subtitle={subtitle}>
      <Head title={`Admin · ${title}`} />

      <form onSubmit={submit} className="space-y-6">
        <div className="grid gap-6 xl:grid-cols-[minmax(0,1fr)_minmax(0,340px)]">
          <div className="min-w-0 space-y-6">
            <SectionCard
              eyebrow="Identity"
              title="Core prompt details"
              description="Set the catalog identity first so the prompt is easy to find, sort, and preview."
            >
              <div className="grid gap-4 md:grid-cols-2">
                {categoryField ? <NovaSelect label={categoryField.label} value={form.data.category_id ?? ''} onChange={(nextValue) => form.setData('category_id', nextValue ?? '')} options={categoryField.options || []} searchable={false} className="rounded-2xl bg-black/20" error={form.errors.category_id} /> : null}
                {difficultyField ? <NovaSelect label={difficultyField.label} value={form.data.difficulty ?? ''} onChange={(nextValue) => form.setData('difficulty', nextValue ?? '')} options={difficultyField.options || []} searchable={false} className="rounded-2xl bg-black/20" error={form.errors.difficulty} /> : null}
              </div>

              <div className="grid gap-4 md:grid-cols-2">
                {accessField ? <NovaSelect label={accessField.label} value={form.data.access_level ?? ''} onChange={(nextValue) => form.setData('access_level', nextValue ?? '')} options={accessField.options || []} searchable={false} className="rounded-2xl bg-black/20" error={form.errors.access_level} /> : null}
                <TextField label="Aspect ratio" value={form.data.aspect_ratio || ''} onChange={(event) => form.setData('aspect_ratio', event.target.value)} error={form.errors.aspect_ratio} placeholder="1:1, 16:9, 3:2" />
              </div>

              <div className="grid gap-4 md:grid-cols-2">
                <TextField label="Title" value={form.data.title || ''} onChange={(event) => form.setData('title', event.target.value)} error={form.errors.title} maxLength={180} />
                <TextField label="Slug" value={form.data.slug || ''} onChange={(event) => form.setData('slug', event.target.value)} error={form.errors.slug} maxLength={180} placeholder="prompt-template-slug" />
              </div>

              <TextAreaField label="Excerpt" value={form.data.excerpt || ''} onChange={(event) => form.setData('excerpt', event.target.value)} error={form.errors.excerpt} rows={4} hint="Short summary shown in the library and preview cards." />

              <TextField label="Tags" value={form.data.tags || ''} onChange={(event) => form.setData('tags', event.target.value)} error={form.errors.tags} placeholder="wallpaper, cinematic, neon, portrait" />
            </SectionCard>

            <SectionCard
              eyebrow="Prompt body"
              title="Prompt instructions"
              description="Write the instruction stack, guardrails, and production notes in a way that is easy to scan."
            >
              <TextAreaField label="Prompt" value={form.data.prompt || ''} onChange={(event) => form.setData('prompt', event.target.value)} error={form.errors.prompt} rows={10} hint="This is the main model instruction used by creators." />
              <TextAreaField label="Negative prompt" value={form.data.negative_prompt || ''} onChange={(event) => form.setData('negative_prompt', event.target.value)} error={form.errors.negative_prompt} rows={5} hint="Optional exclusions, artifacts, or anti-patterns to avoid." />
              <TextAreaField label="Usage notes" value={form.data.usage_notes || ''} onChange={(event) => form.setData('usage_notes', event.target.value)} error={form.errors.usage_notes} rows={5} hint="Explain how to apply the prompt in a practical workflow." />
              <TextAreaField label="Workflow notes" value={form.data.workflow_notes || ''} onChange={(event) => form.setData('workflow_notes', event.target.value)} error={form.errors.workflow_notes} rows={5} hint="Internal editorial notes, camera settings, or prompt variants." />
            </SectionCard>

            <SectionCard
              eyebrow="Publishing"
              title="Release controls"
              description="Choose when the prompt becomes visible and how it behaves in the academy."
            >
              <div className="grid gap-4 md:grid-cols-2">
                {publishedAtField ? <DateTimePicker label={publishedAtField.label} value={form.data.published_at || ''} onChange={(nextValue) => form.setData('published_at', nextValue || '')} error={form.errors.published_at} clearable className="bg-black/20" /> : null}
                <TextField label="SEO title" value={form.data.seo_title || ''} onChange={(event) => form.setData('seo_title', event.target.value)} error={form.errors.seo_title} maxLength={180} />
              </div>
              {seoDescriptionField ? <TextAreaField label={seoDescriptionField.label} value={form.data.seo_description || ''} onChange={(event) => form.setData('seo_description', event.target.value)} error={form.errors.seo_description} rows={4} /> : null}

              <div className="grid gap-3 md:grid-cols-3">
                {featuredField ? <ToggleField label={featuredField.label} checked={Boolean(form.data.featured)} onChange={(event) => form.setData('featured', event.target.checked)} help="Highlight this prompt in featured rails." error={form.errors.featured} /> : null}
                {promptOfWeekField ? <ToggleField label={promptOfWeekField.label} checked={Boolean(form.data.prompt_of_week)} onChange={(event) => form.setData('prompt_of_week', event.target.checked)} help="Promote this prompt as the current weekly pick." error={form.errors.prompt_of_week} /> : null}
                {activeField ? <ToggleField label={activeField.label} checked={Boolean(form.data.active)} onChange={(event) => form.setData('active', event.target.checked)} help="Keep draft prompts hidden until they are ready." error={form.errors.active} /> : null}
              </div>
            </SectionCard>
          </div>

          <div className="min-w-0 space-y-6 xl:sticky xl:top-6 xl:self-start">
            <SectionCard
              eyebrow="At a glance"
              title="Prompt preview"
              description="A compact summary of what editors and visitors will see."
            >
              <div className="overflow-hidden rounded-[24px] border border-white/10 bg-black/30">
                {previewUrl || form.data.preview_image ? (
                  <img src={previewUrl || form.data.preview_image} alt="Prompt preview" className="h-56 w-full object-cover" />
                ) : (
                  <div className="flex h-56 items-center justify-center px-6 text-center text-sm text-slate-500">No preview image selected yet.</div>
                )}
              </div>

              <div className="rounded-[24px] border border-white/10 bg-black/20 p-4">
                <p className="text-[11px] font-semibold uppercase tracking-[0.22em] text-slate-400">Prompt summary</p>
                <h3 className="mt-3 text-2xl font-semibold tracking-[-0.04em] text-white">{form.data.title || 'Untitled prompt'}</h3>
                <p className="mt-2 text-sm leading-7 text-slate-400">{form.data.excerpt || 'Add a concise excerpt to give the prompt some context in the library.'}</p>
                <dl className="mt-4 grid grid-cols-2 gap-3 text-xs text-slate-400">
                  <div className="rounded-2xl border border-white/10 bg-white/[0.03] px-3 py-2"><dt className="uppercase tracking-[0.16em] text-slate-500">Difficulty</dt><dd className="mt-1 text-sm text-white">{form.data.difficulty || '—'}</dd></div>
                  <div className="rounded-2xl border border-white/10 bg-white/[0.03] px-3 py-2"><dt className="uppercase tracking-[0.16em] text-slate-500">Access</dt><dd className="mt-1 text-sm text-white">{form.data.access_level || '—'}</dd></div>
                  <div className="rounded-2xl border border-white/10 bg-white/[0.03] px-3 py-2"><dt className="uppercase tracking-[0.16em] text-slate-500">Aspect</dt><dd className="mt-1 text-sm text-white">{form.data.aspect_ratio || '—'}</dd></div>
                  <div className="rounded-2xl border border-white/10 bg-white/[0.03] px-3 py-2"><dt className="uppercase tracking-[0.16em] text-slate-500">Tags</dt><dd className="mt-1 text-sm text-white">{tagCount}</dd></div>
                </dl>
                <p className="mt-4 text-xs leading-6 text-slate-500">Uploaded images are converted to WebP and stored on the Contabo S3-backed CDN before the record is saved.</p>
              </div>
            </SectionCard>

            <PromptPreviewDropzone form={form} previewUrl={previewUrl} />
          </div>
        </div>

        <div className="flex flex-wrap gap-3 rounded-[28px] border border-white/10 bg-white/[0.03] p-5">
          <button type="submit" disabled={form.processing} className="rounded-full border border-sky-300/25 bg-sky-300/12 px-5 py-3 text-sm font-semibold text-sky-100">{form.processing ? 'Saving...' : 'Save prompt'}</button>
          <Link href={indexUrl} className="rounded-full border border-white/10 bg-white/[0.04] px-5 py-3 text-sm font-semibold text-white">Back</Link>
          {destroyUrl ? <button type="button" onClick={() => { if (!window.confirm('Delete this record?')) return; router.delete(destroyUrl) }} className="rounded-full border border-rose-300/20 bg-rose-300/10 px-5 py-3 text-sm font-semibold text-rose-100">Delete</button> : null}
        </div>
      </form>
    </AdminLayout>
  )
}

function GenericEditor({ title, subtitle, fields, record, submitUrl, indexUrl, destroyUrl, method }) {
  const form = useForm(record)

  const submit = (event) => {
    event.preventDefault()
    const payload = normalizePayload(fields, form.data)
    form.transform(() => payload)

    if (method === 'patch') {
      form.patch(submitUrl)
      return
    }

    form.post(submitUrl)
  }

  return (
    <AdminLayout title={title} subtitle={subtitle}>
      <Head title={`Admin · ${title}`} />

      <form onSubmit={submit} className="space-y-5 rounded-[30px] border border-white/[0.08] bg-white/[0.03] p-6">
        <div className="grid gap-5">
          {fields.map((field) => (
            <Field key={field.name} field={field} form={form} />
          ))}
        </div>

        <div className="flex flex-wrap gap-3">
          <button type="submit" disabled={form.processing} className="rounded-full border border-sky-300/25 bg-sky-300/12 px-5 py-3 text-sm font-semibold text-sky-100">{form.processing ? 'Saving...' : 'Save'}</button>
          <Link href={indexUrl} className="rounded-full border border-white/10 bg-white/[0.04] px-5 py-3 text-sm font-semibold text-white">Back</Link>
          {destroyUrl ? <button type="button" onClick={() => { if (!window.confirm('Delete this record?')) return; router.delete(destroyUrl) }} className="rounded-full border border-rose-300/20 bg-rose-300/10 px-5 py-3 text-sm font-semibold text-rose-100">Delete</button> : null}
        </div>
      </form>
    </AdminLayout>
  )
}

export default function AcademyCrudForm({ resource, title, subtitle, fields, record, submitUrl, indexUrl, destroyUrl, method, editorContext }) {
  if (resource === 'lessons') {
    return (
      <LessonEditor
        title={title}
        subtitle={subtitle}
        fields={fields}
        record={record}
        submitUrl={submitUrl}
        indexUrl={indexUrl}
        destroyUrl={destroyUrl}
        method={method}
        editorContext={editorContext}
      />
    )
  }

  if (resource === 'prompts') {
    return (
      <PromptEditor
        title={title}
        subtitle={subtitle}
        fields={fields}
        record={record}
        submitUrl={submitUrl}
        indexUrl={indexUrl}
        destroyUrl={destroyUrl}
        method={method}
      />
    )
  }

  return (
    <GenericEditor
      title={title}
      subtitle={subtitle}
      fields={fields}
      record={record}
      submitUrl={submitUrl}
      indexUrl={indexUrl}
      destroyUrl={destroyUrl}
      method={method}
    />
  )
}