import { useState, useEffect } from 'react'
import { api } from '../lib/api'
import { useAuth } from '../hooks/useAuth'
import { solveAltcha } from '../lib/altcha'
import { IconFingerprint } from '@tabler/icons-react'
import Dropdown from './Dropdown'
import MarkdownEditor from './MarkdownEditor'
import FileUpload from './FileUpload'

interface SimilarPost {
  id: string
  title: string
  status: string
  voteCount: number
  similarity: number
}

interface TemplateField {
  key: string
  label: string
  type: 'text' | 'textarea' | 'select'
  required: boolean
  placeholder?: string
  options?: string[]
}

interface Template {
  id: string
  name: string
  fields: TemplateField[]
  isDefault: boolean
}

interface Props {
  boardSlug: string
  boardId?: string
  onSubmit?: () => void
  onCancel?: () => void
}

type PostType = 'FEATURE_REQUEST' | 'BUG_REPORT'

interface FieldErrors {
  [key: string]: string
}

export default function PostForm({ boardSlug, boardId, onSubmit, onCancel }: Props) {
  const auth = useAuth()
  const [type, setType] = useState<PostType>('FEATURE_REQUEST')
  const [title, setTitle] = useState('')
  const [category, setCategory] = useState('')
  const [submitting, setSubmitting] = useState(false)
  const [error, setError] = useState('')
  const [fieldErrors, setFieldErrors] = useState<FieldErrors>({})
  const [categories, setCategories] = useState<{ id: string; name: string; slug: string }[]>([])
  const [similar, setSimilar] = useState<SimilarPost[]>([])

  // templates
  const [templates, setTemplates] = useState<Template[]>([])
  const [selectedTemplateId, setSelectedTemplateId] = useState('')
  const [templateValues, setTemplateValues] = useState<Record<string, string>>({})

  useEffect(() => {
    api.get<{ id: string; name: string; slug: string }[]>('/categories')
      .then(setCategories)
      .catch(() => {})
  }, [])

  // fetch templates for this board
  useEffect(() => {
    if (!boardSlug) return
    api.get<{ templates: Template[] }>(`/boards/${boardSlug}/templates`)
      .then((r) => {
        setTemplates(r.templates)
        const def = r.templates.find((t) => t.isDefault)
        if (def) setSelectedTemplateId(def.id)
      })
      .catch(() => {})
  }, [boardSlug])

  // debounced duplicate detection
  useEffect(() => {
    if (!boardId || title.trim().length < 5) { setSimilar([]); return }
    const t = setTimeout(() => {
      api.get<{ posts: SimilarPost[] }>(`/similar?title=${encodeURIComponent(title)}&boardId=${encodeURIComponent(boardId)}`)
        .then((r) => setSimilar(r.posts))
        .catch(() => setSimilar([]))
    }, 400)
    return () => clearTimeout(t)
  }, [title, boardId])

  // bug report fields
  const [steps, setSteps] = useState('')
  const [expected, setExpected] = useState('')
  const [actual, setActual] = useState('')
  const [environment, setEnvironment] = useState('')
  const [bugContext, setBugContext] = useState('')

  const [attachmentIds, setAttachmentIds] = useState<string[]>([])

  // feature request fields
  const [useCase, setUseCase] = useState('')
  const [proposedSolution, setProposedSolution] = useState('')
  const [alternatives, setAlternatives] = useState('')
  const [featureContext, setFeatureContext] = useState('')

  const selectedTemplate = templates.find((t) => t.id === selectedTemplateId) || null

  const reset = () => {
    setTitle('')
    setCategory('')
    setSteps('')
    setExpected('')
    setActual('')
    setEnvironment('')
    setBugContext('')
    setUseCase('')
    setProposedSolution('')
    setAlternatives('')
    setFeatureContext('')
    setAttachmentIds([])
    setTemplateValues({})
    setError('')
    setFieldErrors({})
  }

  const validate = (): boolean => {
    const errors: FieldErrors = {}

    if (title.trim().length < 5) {
      errors.title = 'Title must be at least 5 characters'
    }

    if (selectedTemplate) {
      for (const f of selectedTemplate.fields) {
        if (f.required && !templateValues[f.key]?.trim()) {
          errors[f.key] = `${f.label} is required`
        }
      }
    } else if (type === 'BUG_REPORT') {
      if (!steps.trim()) errors.steps = 'Steps to reproduce are required'
      if (!expected.trim()) errors.expected = 'Expected behavior is required'
      if (!actual.trim()) errors.actual = 'Actual behavior is required'
    } else {
      if (!useCase.trim()) errors.useCase = 'Use case is required'
    }

    setFieldErrors(errors)
    return Object.keys(errors).length === 0
  }

  const submit = async () => {
    if (!validate()) return

    setSubmitting(true)
    setError('')

    let altcha: string
    try {
      altcha = await solveAltcha()
    } catch {
      setError('Verification failed. Please try again.')
      setSubmitting(false)
      return
    }

    let description: Record<string, string>
    if (selectedTemplate) {
      description = {}
      for (const f of selectedTemplate.fields) {
        description[f.key] = templateValues[f.key] || ''
      }
    } else if (type === 'BUG_REPORT') {
      description = {
        stepsToReproduce: steps,
        expectedBehavior: expected,
        actualBehavior: actual,
        environment: environment || '',
        additionalContext: bugContext || '',
      }
    } else {
      description = {
        useCase,
        proposedSolution: proposedSolution || '',
        alternativesConsidered: alternatives || '',
        additionalContext: featureContext || '',
      }
    }

    try {
      await api.post(`/boards/${boardSlug}/posts`, {
        title,
        type,
        description,
        category: category || undefined,
        templateId: selectedTemplate ? selectedTemplate.id : undefined,
        attachmentIds: attachmentIds.length ? attachmentIds : undefined,
        altcha,
      })
      reset()
      onSubmit?.()
    } catch {
      setError('Failed to submit. Please try again.')
    } finally {
      setSubmitting(false)
    }
  }

  const fieldError = (key: string) =>
    fieldErrors[key] ? (
      <span id={`err-${key}`} role="alert" className="mt-0.5 block" style={{ color: 'var(--error)', fontSize: 'var(--text-xs)' }}>{fieldErrors[key]}</span>
    ) : null

  const label = (text: string, required?: boolean, htmlFor?: string) => (
    <label htmlFor={htmlFor} className="block font-medium mb-1 uppercase tracking-wider" style={{ color: 'var(--text-tertiary)', fontSize: 'var(--text-xs)' }}>
      {text}{required && <span style={{ color: 'var(--error)' }}> *</span>}
    </label>
  )

  const handleTemplateChange = (id: string) => {
    setSelectedTemplateId(id)
    setTemplateValues({})
    setFieldErrors({})
  }

  const renderTemplateFields = () => {
    if (!selectedTemplate) return null

    return selectedTemplate.fields.map((f) => (
      <div key={f.key} className="mb-3">
        {label(f.label, f.required)}
        {f.type === 'text' && (
          <input
            className="input w-full"
            placeholder={f.placeholder || ''}
            value={templateValues[f.key] || ''}
            onChange={(e) => setTemplateValues((prev) => ({ ...prev, [f.key]: e.target.value }))}
            aria-required={f.required || undefined}
            aria-invalid={!!fieldErrors[f.key]}
            aria-describedby={fieldErrors[f.key] ? `err-${f.key}` : undefined}
          />
        )}
        {f.type === 'textarea' && (
          <MarkdownEditor
            value={templateValues[f.key] || ''}
            onChange={(val) => setTemplateValues((prev) => ({ ...prev, [f.key]: val }))}
            placeholder={f.placeholder || ''}
            rows={3}
            ariaRequired={f.required}
            ariaLabel={f.label}
          />
        )}
        {f.type === 'select' && f.options && (
          <Dropdown
            value={templateValues[f.key] || ''}
            onChange={(val) => setTemplateValues((prev) => ({ ...prev, [f.key]: val }))}
            placeholder={f.placeholder || 'Select...'}
            options={[
              { value: '', label: f.placeholder || 'Select...' },
              ...f.options.map((o) => ({ value: o, label: o })),
            ]}
          />
        )}
        {fieldError(f.key)}
      </div>
    ))
  }

  return (
    <div
      className="card card-static p-5"
      style={{ animation: 'slideUp var(--duration-normal) var(--ease-out)' }}
    >
      <div className="flex items-center justify-between mb-4">
        <h2
          className="font-bold"
          style={{ fontFamily: 'var(--font-heading)', color: 'var(--text)', fontSize: 'var(--text-base)' }}
        >
          Share feedback
        </h2>
        {onCancel && (
          <button
            onClick={() => { reset(); onCancel() }}
            className="btn btn-ghost"
            style={{ fontSize: 'var(--text-xs)' }}
          >
            Cancel
          </button>
        )}
      </div>

      {/* Template selector */}
      {templates.length > 0 && (
        <div className="mb-4">
          {label('Template')}
          <div className="flex gap-2 flex-wrap">
            <button
              onClick={() => handleTemplateChange('')}
              className="px-3 py-1.5 font-medium"
              style={{
                background: !selectedTemplateId ? 'var(--accent-subtle)' : 'transparent',
                color: !selectedTemplateId ? 'var(--accent)' : 'var(--text-tertiary)',
                border: `1px solid ${!selectedTemplateId ? 'var(--accent)' : 'var(--border)'}`,
                borderRadius: 'var(--radius-md)',
                fontSize: 'var(--text-xs)',
                transition: 'all var(--duration-fast) ease-out',
              }}
            >
              Default
            </button>
            {templates.map((t) => (
              <button
                key={t.id}
                onClick={() => handleTemplateChange(t.id)}
                className="px-3 py-1.5 font-medium"
                style={{
                  background: selectedTemplateId === t.id ? 'var(--accent-subtle)' : 'transparent',
                  color: selectedTemplateId === t.id ? 'var(--accent)' : 'var(--text-tertiary)',
                  border: `1px solid ${selectedTemplateId === t.id ? 'var(--accent)' : 'var(--border)'}`,
                  borderRadius: 'var(--radius-md)',
                  fontSize: 'var(--text-xs)',
                  transition: 'all var(--duration-fast) ease-out',
                }}
              >
                {t.name}
              </button>
            ))}
          </div>
        </div>
      )}

      {/* Type selector - only when not using a template */}
      {!selectedTemplate && (
        <div className="flex gap-2 mb-4">
          {([
            ['FEATURE_REQUEST', 'Feature Request'],
            ['BUG_REPORT', 'Bug Report'],
          ] as const).map(([value, lbl]) => (
            <button
              key={value}
              onClick={() => setType(value)}
              className="px-3 py-1.5 font-medium"
              style={{
                background: type === value ? 'var(--accent-subtle)' : 'transparent',
                color: type === value ? 'var(--accent)' : 'var(--text-tertiary)',
                border: `1px solid ${type === value ? 'var(--accent)' : 'var(--border)'}`,
                borderRadius: 'var(--radius-md)',
                fontSize: 'var(--text-xs)',
                transition: 'all var(--duration-fast) ease-out',
              }}
            >
              {lbl}
            </button>
          ))}
        </div>
      )}

      {/* Title */}
      <div className="mb-3">
        {label('Title', true, 'post-title')}
        <input
          id="post-title"
          className="input w-full"
          placeholder="Brief summary"
          value={title}
          onChange={(e) => setTitle(e.target.value)}
          maxLength={200}
          aria-required="true"
          aria-invalid={!!fieldErrors.title}
          aria-describedby={fieldErrors.title ? 'err-title' : undefined}
        />
        {fieldError('title')}
        {similar.length > 0 && (
          <div
            className="mt-2 rounded-lg overflow-hidden"
            style={{ border: '1px solid var(--border-accent)', background: 'var(--surface)' }}
          >
            <div className="px-3 py-1.5" style={{ background: 'var(--accent-subtle)', color: 'var(--accent)', fontSize: 'var(--text-xs)', fontWeight: 500 }}>
              Similar posts already exist - vote instead?
            </div>
            {similar.map((p) => (
              <a
                key={p.id}
                href={`/b/${boardSlug}/post/${p.id}`}
                className="flex items-center justify-between px-3 py-2"
                style={{ borderTop: '1px solid var(--border)', fontSize: 'var(--text-xs)', color: 'var(--text)' }}
              >
                <span className="truncate mr-2">{p.title}</span>
                <span className="shrink-0 flex items-center gap-2" style={{ color: 'var(--text-tertiary)' }}>
                  <span style={{ color: 'var(--accent)' }}>{p.voteCount} votes</span>
                  <span>{p.similarity}% match</span>
                </span>
              </a>
            ))}
          </div>
        )}
      </div>

      {/* Category */}
      {categories.length > 0 && (
        <div className="mb-3">
          {label('Category')}
          <Dropdown
            value={category}
            onChange={setCategory}
            placeholder="No category"
            options={[
              { value: '', label: 'No category' },
              ...categories.map((c) => ({ value: c.slug, label: c.name })),
            ]}
          />
        </div>
      )}

      {/* Template fields or default fields */}
      {selectedTemplate ? (
        renderTemplateFields()
      ) : type === 'BUG_REPORT' ? (
        <>
          <div className="mb-3">
            {label('Steps to reproduce', true)}
            <MarkdownEditor
              value={steps}
              onChange={setSteps}
              placeholder="1. Go to...  2. Click on...  3. See error"
              rows={3}
              ariaRequired
              ariaLabel="Steps to reproduce"
            />
            {fieldError('steps')}
          </div>
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-3 mb-3">
            <div>
              {label('Expected behavior', true)}
              <MarkdownEditor value={expected} onChange={setExpected} placeholder="What should happen?" rows={2} ariaRequired ariaLabel="Expected behavior" />
              {fieldError('expected')}
            </div>
            <div>
              {label('Actual behavior', true)}
              <MarkdownEditor value={actual} onChange={setActual} placeholder="What actually happens?" rows={2} ariaRequired ariaLabel="Actual behavior" />
              {fieldError('actual')}
            </div>
          </div>
          <div className="mb-3">
            {label('Environment / version')}
            <input
              className="input w-full"
              placeholder="OS, browser, app version..."
              value={environment}
              onChange={(e) => setEnvironment(e.target.value)}
            />
          </div>
          <div className="mb-3">
            {label('Additional context')}
            <MarkdownEditor value={bugContext} onChange={setBugContext} placeholder="Screenshots, logs, anything else..." rows={2} />
          </div>
        </>
      ) : (
        <>
          <div className="mb-3">
            {label('Use case / problem statement', true)}
            <MarkdownEditor value={useCase} onChange={setUseCase} placeholder="What are you trying to accomplish?" rows={3} ariaRequired ariaLabel="Use case" />
            {fieldError('useCase')}
          </div>
          <div className="mb-3">
            {label('Proposed solution')}
            <MarkdownEditor value={proposedSolution} onChange={setProposedSolution} placeholder="How do you think this should work?" rows={2} />
          </div>
          <div className="mb-3">
            {label('Alternatives considered')}
            <MarkdownEditor value={alternatives} onChange={setAlternatives} placeholder="Have you tried any workarounds?" rows={2} />
          </div>
          <div className="mb-3">
            {label('Additional context')}
            <MarkdownEditor value={featureContext} onChange={setFeatureContext} placeholder="Anything else to add?" rows={2} />
          </div>
        </>
      )}

      <div className="mb-3">
        {label('Attachments')}
        <FileUpload attachmentIds={attachmentIds} onChange={setAttachmentIds} />
      </div>

      {error && (
        <div role="alert" className="text-xs mb-3" style={{ color: 'var(--error)' }}>{error}</div>
      )}

      <div className="flex items-center justify-between">
        <span style={{ color: 'var(--text-tertiary)', fontSize: 'var(--text-xs)' }}>
          Your ability to edit this post depends on your browser cookie.
        </span>
        <button
          onClick={submit}
          disabled={submitting}
          className="btn btn-primary"
          style={{ opacity: submitting ? 0.6 : 1 }}
        >
          {submitting ? 'Submitting...' : 'Submit'}
        </button>
      </div>
      {!auth.isPasskeyUser && (
        <div className="mt-3 pt-3" style={{ borderTop: '1px solid var(--border)' }}>
          <a
            href="/settings"
            className="flex items-center gap-2"
            style={{ color: 'var(--accent)', fontSize: 'var(--text-xs)' }}
          >
            <IconFingerprint size={14} stroke={2} />
            Save my identity to keep your posts across devices
          </a>
        </div>
      )}
    </div>
  )
}
