import React, { useState, useRef } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { Pencil, Trash2, Plus, Check, X, Upload, Download, Copy } from 'lucide-react'
import HelpTooltip from '../HelpTooltip'
import { toast } from 'sonner'
import {
  listRenderTemplates,
  createRenderTemplate,
  duplicateRenderTemplate,
  updateRenderTemplate,
  deleteRenderTemplate,
  reuploadBlendFile,
} from '../../api/renderTemplates'
import type { RenderTemplate } from '../../api/renderTemplates'
import { listOutputTypes } from '../../api/outputTypes'
import type { OutputType } from '../../api/outputTypes'

const ALL_CATEGORIES = [
  { key: 'TRB', label: 'TRB' },
  { key: 'Kugellager', label: 'Kugellager' },
  { key: 'CRB', label: 'CRB' },
  { key: 'Gleitlager', label: 'Gleitlager' },
  { key: 'SRB_TORB', label: 'SRB/TORB' },
  { key: 'Linear_schiene', label: 'Linear' },
  { key: 'Anschlagplatten', label: 'Anschlag' },
]

const EMPTY_FORM = {
  name: '',
  category_key: '' as string,
  output_type_id: '' as string,
  target_collection: 'Product',
  material_replace_enabled: false,
  lighting_only: false,
  shadow_catcher_enabled: false,
  camera_orbit: true,
}

export default function RenderTemplateTable() {
  const qc = useQueryClient()
  const [showAdd, setShowAdd] = useState(false)
  const [form, setForm] = useState(EMPTY_FORM)
  const [addFile, setAddFile] = useState<File | null>(null)
  const [cloneBlendFrom, setCloneBlendFrom] = useState<string>('')
  const [editingId, setEditingId] = useState<string | null>(null)
  const [editDraft, setEditDraft] = useState<Partial<RenderTemplate>>({})
  const fileInputRef = useRef<HTMLInputElement>(null)
  const reuploadRef = useRef<HTMLInputElement>(null)
  const [reuploadId, setReuploadId] = useState<string | null>(null)

  const { data: templates, isLoading } = useQuery({
    queryKey: ['render-templates'],
    queryFn: listRenderTemplates,
  })

  const { data: outputTypes } = useQuery({
    queryKey: ['output-types-admin'],
    queryFn: () => listOutputTypes(true),
  })

  const createMut = useMutation({
    mutationFn: () => {
      if (!addFile && !cloneBlendFrom) throw new Error('Please select a .blend file or choose an existing one')
      const fd = new FormData()
      fd.append('name', form.name.trim())
      if (addFile) {
        fd.append('file', addFile)
      } else if (cloneBlendFrom) {
        fd.append('clone_blend_from', cloneBlendFrom)
      }
      fd.append('category_key', form.category_key || '')
      fd.append('output_type_id', form.output_type_id || '')
      fd.append('target_collection', form.target_collection || 'Product')
      fd.append('material_replace_enabled', String(form.material_replace_enabled))
      fd.append('lighting_only', String(form.lighting_only))
      fd.append('shadow_catcher_enabled', String(form.shadow_catcher_enabled))
      fd.append('camera_orbit', String(form.camera_orbit))
      return createRenderTemplate(fd)
    },
    onSuccess: () => {
      toast.success('Render template created')
      qc.invalidateQueries({ queryKey: ['render-templates'] })
      setForm(EMPTY_FORM)
      setAddFile(null)
      setCloneBlendFrom('')
      setShowAdd(false)
    },
    onError: (e: any) => toast.error(e.response?.data?.detail || 'Failed to create template'),
  })

  const updateMut = useMutation({
    mutationFn: ({ id, data }: { id: string; data: Record<string, unknown> }) =>
      updateRenderTemplate(id, data as any),
    onSuccess: () => {
      toast.success('Template updated')
      qc.invalidateQueries({ queryKey: ['render-templates'] })
      setEditingId(null)
    },
    onError: (e: any) => toast.error(e.response?.data?.detail || 'Failed to update'),
  })

  const deleteMut = useMutation({
    mutationFn: deleteRenderTemplate,
    onSuccess: () => {
      toast.success('Template deleted')
      qc.invalidateQueries({ queryKey: ['render-templates'] })
    },
    onError: (e: any) => toast.error(e.response?.data?.detail || 'Failed to delete'),
  })

  const reuploadMut = useMutation({
    mutationFn: ({ id, file }: { id: string; file: File }) => reuploadBlendFile(id, file),
    onSuccess: () => {
      toast.success('.blend file updated')
      qc.invalidateQueries({ queryKey: ['render-templates'] })
      setReuploadId(null)
    },
    onError: (e: any) => toast.error(e.response?.data?.detail || 'Failed to upload'),
  })

  const duplicateMut = useMutation({
    mutationFn: (t: RenderTemplate) => duplicateRenderTemplate(t.id, {
      name: `${t.name} (copy)`,
      category_key: t.category_key,
      target_collection: t.target_collection,
      material_replace_enabled: t.material_replace_enabled,
      lighting_only: t.lighting_only,
      shadow_catcher_enabled: t.shadow_catcher_enabled,
      camera_orbit: t.camera_orbit,
      output_type_ids: t.output_type_ids ?? [],
    }),
    onSuccess: () => {
      toast.success('Template duplicated')
      qc.invalidateQueries({ queryKey: ['render-templates'] })
    },
    onError: (e: any) => toast.error(e.response?.data?.detail || 'Failed to duplicate'),
  })

  function startEdit(t: RenderTemplate) {
    setEditingId(t.id)
    setEditDraft({
      name: t.name,
      category_key: t.category_key,
      output_type_ids: t.output_type_ids ?? [],
      target_collection: t.target_collection,
      material_replace_enabled: t.material_replace_enabled,
      lighting_only: t.lighting_only,
      shadow_catcher_enabled: t.shadow_catcher_enabled,
      camera_orbit: t.camera_orbit,
      is_active: t.is_active,
    })
  }

  function saveEdit() {
    if (!editingId) return
    updateMut.mutate({ id: editingId, data: editDraft as Record<string, unknown> })
  }

  // Render the edit form grid (shared between edit-row and add-row)
  function renderEditFormGrid(
    mode: 'edit' | 'add',
    t: RenderTemplate | null,
  ) {
    const isEdit = mode === 'edit' && t !== null

    // Value getters
    const val = (field: keyof typeof EMPTY_FORM | 'is_active' | 'output_type_ids') => {
      if (isEdit) {
        if (field === 'name') return editDraft.name ?? t!.name
        if (field === 'category_key') return editDraft.category_key ?? t!.category_key ?? ''
        if (field === 'output_type_ids') return editDraft.output_type_ids ?? t!.output_type_ids ?? []
        if (field === 'target_collection') return editDraft.target_collection ?? t!.target_collection
        if (field === 'material_replace_enabled') return editDraft.material_replace_enabled ?? t!.material_replace_enabled
        if (field === 'lighting_only') return editDraft.lighting_only ?? t!.lighting_only
        if (field === 'shadow_catcher_enabled') return editDraft.shadow_catcher_enabled ?? t!.shadow_catcher_enabled
        if (field === 'camera_orbit') return editDraft.camera_orbit ?? t!.camera_orbit
        if (field === 'is_active') return editDraft.is_active ?? t!.is_active
        return (editDraft as any)[field] ?? (t as any)[field]
      }
      return (form as any)[field]
    }

    const set = (field: string, value: any) => {
      if (isEdit) {
        setEditDraft({ ...editDraft, [field]: value } as any)
      } else {
        setForm({ ...form, [field]: value })
      }
    }

    return (
      <>
        {/* Row 1: Name | Category | Output Types */}
        <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
          <div>
            <label className="block text-xs font-medium text-content-muted mb-1">Name</label>
            <input
              className="input-sm w-full"
              placeholder="Template name"
              value={val('name') as string}
              onChange={(e) => set('name', e.target.value)}
            />
          </div>
          <div>
            <label className="block text-xs font-medium text-content-muted mb-1">Category</label>
            <select
              className="input-sm w-full"
              value={val('category_key') as string}
              onChange={(e) => set('category_key', e.target.value || (isEdit ? null : ''))}
            >
              <option value="">Any (default)</option>
              {ALL_CATEGORIES.map((c) => (
                <option key={c.key} value={c.key}>{c.label}</option>
              ))}
            </select>
          </div>
          <div>
            <label className="block text-xs font-medium text-content-muted mb-1">Output Types</label>
            {isEdit ? (
              <div className="flex flex-wrap gap-1.5 max-h-24 overflow-y-auto p-1.5 border border-border-default rounded bg-surface">
                {outputTypes?.map((ot: OutputType) => {
                  const ids = val('output_type_ids') as string[]
                  const checked = ids.includes(ot.id)
                  return (
                    <label key={ot.id} className="flex items-center gap-1 text-xs cursor-pointer whitespace-nowrap">
                      <input
                        type="checkbox"
                        checked={checked}
                        onChange={() => {
                          const next = checked
                            ? ids.filter((id: string) => id !== ot.id)
                            : [...ids, ot.id]
                          set('output_type_ids', next)
                        }}
                      />
                      {ot.name}
                    </label>
                  )
                })}
              </div>
            ) : (
              <select
                className="input-sm w-full"
                value={(form as any).output_type_id ?? ''}
                onChange={(e) => setForm({ ...form, output_type_id: e.target.value })}
              >
                <option value="">Any (default)</option>
                {outputTypes?.map((ot: OutputType) => (
                  <option key={ot.id} value={ot.id}>{ot.name}</option>
                ))}
              </select>
            )}
          </div>
        </div>

        {/* Row 2: Collection | Checkboxes */}
        <div className="grid grid-cols-2 md:grid-cols-5 gap-4 mt-4">
          <div>
            <label className="block text-xs font-medium text-content-muted mb-1">Collection Name</label>
            <input
              className="input-sm w-full"
              value={val('target_collection') as string}
              onChange={(e) => set('target_collection', e.target.value)}
            />
          </div>
          <div>
            <label className="block text-xs font-medium text-content-muted mb-1">
              <span className="inline-flex items-center gap-1">
                Mat. Replace
                <HelpTooltip helpKey="template.material_replace_enabled" position="bottom" size={12} />
              </span>
            </label>
            <label className="flex items-center gap-2 mt-1">
              <input
                type="checkbox"
                checked={val('material_replace_enabled') as boolean}
                onChange={(e) => set('material_replace_enabled', e.target.checked)}
              />
              <span className="text-sm text-content-secondary">Enabled</span>
            </label>
          </div>
          <div>
            <label className="block text-xs font-medium text-content-muted mb-1">
              <span className="inline-flex items-center gap-1">
                Lighting Only
                <HelpTooltip helpKey="template.lighting_only" position="bottom" size={12} />
              </span>
            </label>
            <label className="flex items-center gap-2 mt-1">
              <input
                type="checkbox"
                checked={val('lighting_only') as boolean}
                onChange={(e) => set('lighting_only', e.target.checked)}
              />
              <span className="text-sm text-content-secondary">HDR only</span>
            </label>
          </div>
          <div>
            <label className="block text-xs font-medium text-content-muted mb-1">
              <span className="inline-flex items-center gap-1">
                Shadow Catcher
                <HelpTooltip helpKey="template.shadow_catcher" position="bottom" size={12} />
              </span>
            </label>
            <label className="flex items-center gap-2 mt-1">
              <input
                type="checkbox"
                checked={val('shadow_catcher_enabled') as boolean}
                title="Enable Shadowcatcher collection (Cycles only)"
                onChange={(e) => set('shadow_catcher_enabled', e.target.checked)}
              />
              <span className="text-sm text-content-secondary">Enabled</span>
            </label>
          </div>
          <div>
            <label className="block text-xs font-medium text-content-muted mb-1">Camera Orbit</label>
            <label className="flex items-center gap-2 mt-1">
              <input
                type="checkbox"
                checked={val('camera_orbit') as boolean}
                title="Rotate camera around product (better GPU performance)"
                onChange={(e) => set('camera_orbit', e.target.checked)}
              />
              <span className="text-sm text-content-secondary">Cam orbit</span>
            </label>
          </div>
        </div>

        {/* Row 3: .blend File */}
        <div className="mt-4">
          <label className="block text-xs font-medium text-content-muted mb-1">.blend File</label>
          {isEdit ? (
            <div className="flex items-center gap-3">
              <span className="text-sm text-content-secondary truncate max-w-xs" title={t!.original_filename}>
                {t!.original_filename}
              </span>
              {templates && templates.filter((o) => o.blend_file_path === t!.blend_file_path).length > 1 && (
                <span className="text-xs text-blue-500" title="Shared .blend file">&#8727; shared</span>
              )}
              <button
                onClick={() => { setReuploadId(t!.id); reuploadRef.current?.click() }}
                className="flex items-center gap-1 text-xs px-2 py-1 text-accent hover:bg-surface-hover rounded border border-border-default"
                title="Re-upload .blend"
              >
                <Upload size={12} /> Re-upload
              </button>
              <a
                href={`/api/render-templates/${t!.id}/download`}
                className="flex items-center gap-1 text-xs px-2 py-1 text-accent hover:bg-surface-hover rounded border border-border-default"
                title="Download .blend"
              >
                <Download size={12} /> Download
              </a>
            </div>
          ) : (
            <div className="flex items-center gap-3">
              <label className="flex items-center gap-1.5 text-sm cursor-pointer text-accent hover:text-accent-hover px-2 py-1 border border-border-default rounded">
                <Upload size={14} />
                {addFile ? addFile.name : 'Upload .blend'}
                <input
                  ref={fileInputRef}
                  type="file"
                  accept=".blend"
                  className="hidden"
                  onChange={(e) => { setAddFile(e.target.files?.[0] || null); setCloneBlendFrom('') }}
                />
              </label>
              {!addFile && (
                <select
                  className="input-sm text-xs"
                  value={cloneBlendFrom}
                  onChange={(e) => { setCloneBlendFrom(e.target.value); setAddFile(null) }}
                >
                  <option value="">or re-use existing...</option>
                  {templates?.map((tmpl) => (
                    <option key={tmpl.id} value={tmpl.id}>{tmpl.original_filename} ({tmpl.name})</option>
                  ))}
                </select>
              )}
            </div>
          )}
        </div>

        {/* Row 4: Active + Save/Cancel */}
        <div className="flex items-center justify-between mt-4 pt-3 border-t border-border-light">
          {isEdit ? (
            <label className="flex items-center gap-2">
              <input
                type="checkbox"
                checked={val('is_active') as boolean}
                onChange={(e) => set('is_active', e.target.checked)}
              />
              <span className="text-sm text-content-secondary">Active (visible in wizard)</span>
            </label>
          ) : (
            <span className="text-sm text-content-muted">Will be active by default</span>
          )}
          <div className="flex gap-2">
            <button
              className="btn-secondary text-sm"
              onClick={() => {
                if (isEdit) {
                  setEditingId(null)
                } else {
                  setShowAdd(false)
                  setForm(EMPTY_FORM)
                  setAddFile(null)
                  setCloneBlendFrom('')
                }
              }}
            >
              Cancel
            </button>
            <button
              className="btn-primary text-sm"
              disabled={isEdit ? updateMut.isPending : (!form.name.trim() || (!addFile && !cloneBlendFrom) || createMut.isPending)}
              onClick={() => {
                if (isEdit) {
                  saveEdit()
                } else {
                  createMut.mutate()
                }
              }}
            >
              {isEdit ? (updateMut.isPending ? 'Saving...' : 'Save') : (createMut.isPending ? 'Creating...' : 'Create')}
            </button>
          </div>
        </div>
      </>
    )
  }

  return (
    <div>
      <div className="flex items-center justify-between mb-3">
        <h3 className="text-lg font-semibold text-content">Render Templates</h3>
        <button
          onClick={() => setShowAdd(!showAdd)}
          className="flex items-center gap-1 text-sm px-3 py-1.5 bg-blue-600 text-white rounded hover:bg-blue-700"
        >
          <Plus size={14} /> Add Template
        </button>
      </div>

      {/* Hidden file inputs */}
      <input
        ref={reuploadRef}
        type="file"
        accept=".blend"
        className="hidden"
        onChange={(e) => {
          const file = e.target.files?.[0]
          if (file && reuploadId) reuploadMut.mutate({ id: reuploadId, file })
          e.target.value = ''
        }}
      />

      <div className="overflow-x-auto">
        <table className="w-full text-sm border-collapse">
          <thead>
            <tr className="bg-surface-alt border-b text-left">
              <th className="px-3 py-2 font-medium">Name</th>
              <th className="px-3 py-2 font-medium">Category</th>
              <th className="px-3 py-2 font-medium">Output Types</th>
              <th className="px-3 py-2 font-medium">Collection</th>
              <th className="px-3 py-2 font-medium">Flags</th>
              <th className="px-3 py-2 font-medium">.blend File</th>
              <th className="px-3 py-2 font-medium">Active</th>
              <th className="px-3 py-2 font-medium w-24">Actions</th>
            </tr>
          </thead>
          <tbody>
            {isLoading && (
              <tr>
                <td colSpan={8} className="px-3 py-4 text-center text-content-muted">Loading...</td>
              </tr>
            )}

            {/* Add new — expandable form */}
            {showAdd && (
              <tr className="border-b border-border-light bg-status-success-bg">
                <td colSpan={8} className="px-6 py-5 border-l-4 border-status-success-text">
                  <div className="text-sm font-medium text-content-secondary mb-3">New Render Template</div>
                  {renderEditFormGrid('add', null)}
                </td>
              </tr>
            )}

            {/* Template rows */}
            {templates?.map((t) => (
              <React.Fragment key={t.id}>
                {/* Display row — always visible */}
                <tr className={`border-b border-border-light hover:bg-surface-hover/50 ${editingId === t.id ? 'bg-surface-hover' : ''}`}>
                  <td className="px-3 py-2">
                    <span className="font-medium">{t.name}</span>
                  </td>
                  <td className="px-3 py-2">
                    {t.category_key || <span className="text-content-muted">Any</span>}
                  </td>
                  <td className="px-3 py-2">
                    {t.output_type_names && t.output_type_names.length > 0 ? (
                      <div className="flex flex-wrap gap-1">
                        {t.output_type_names.map((name, i) => (
                          <span key={i} className="inline-block text-xs px-1.5 py-0.5 bg-blue-100 text-blue-800 rounded">
                            {name}
                          </span>
                        ))}
                      </div>
                    ) : (
                      <span className="text-content-muted">Any</span>
                    )}
                  </td>
                  <td className="px-3 py-2">
                    <code className="text-xs bg-surface-muted px-1 rounded">{t.target_collection}</code>
                  </td>
                  <td className="px-3 py-2">
                    <div className="flex flex-wrap gap-1">
                      {t.material_replace_enabled && (
                        <span className="text-status-success-text text-xs font-medium" title="Material Replace">Mat</span>
                      )}
                      {t.lighting_only && (
                        <span className="text-status-warning-text text-xs font-medium" title="Lighting Only (HDR)">HDR</span>
                      )}
                      {t.shadow_catcher_enabled && (
                        <span className="text-violet-600 text-xs font-medium" title="Shadow Catcher">Shd</span>
                      )}
                      <span className={`text-xs font-medium ${t.camera_orbit ? 'text-teal-600' : 'text-content-muted'}`} title={t.camera_orbit ? 'Camera Orbit' : 'Object Rotation'}>
                        {t.camera_orbit ? 'Cam' : 'Obj'}
                      </span>
                    </div>
                  </td>
                  <td className="px-3 py-2">
                    <div className="flex items-center gap-1">
                      {templates && templates.filter((o) => o.blend_file_path === t.blend_file_path).length > 1 && (
                        <span className="text-xs text-blue-500" title="Shared .blend file">&#8727;</span>
                      )}
                      <span className="text-xs text-content-secondary truncate max-w-[120px]" title={t.original_filename}>
                        {t.original_filename}
                      </span>
                    </div>
                  </td>
                  <td className="px-3 py-2 text-center">
                    {t.is_active ? (
                      <span className="inline-block w-2 h-2 rounded-full bg-green-500" title="Active" />
                    ) : (
                      <span className="inline-block w-2 h-2 rounded-full bg-surface-muted" title="Inactive" />
                    )}
                  </td>
                  <td className="px-3 py-2">
                    <div className="flex gap-1">
                      <button onClick={() => startEdit(t)} className="p-1 text-accent hover:bg-surface-hover rounded" title="Edit">
                        <Pencil size={14} />
                      </button>
                      <button onClick={() => duplicateMut.mutate(t)} disabled={duplicateMut.isPending} className="p-1 text-blue-500 hover:bg-blue-50 rounded" title="Duplicate">
                        <Copy size={14} />
                      </button>
                      <button
                        onClick={() => {
                          if (confirm(`Delete template "${t.name}"?`)) deleteMut.mutate(t.id)
                        }}
                        className="p-1 text-red-500 hover:bg-red-50 rounded"
                        title="Delete"
                      >
                        <Trash2 size={14} />
                      </button>
                    </div>
                  </td>
                </tr>

                {/* Expandable edit form row */}
                {editingId === t.id && (
                  <tr>
                    <td colSpan={8} className="px-6 py-5 bg-surface-alt border-l-4 border-accent border-b-2 border-b-border-light">
                      {renderEditFormGrid('edit', t)}
                    </td>
                  </tr>
                )}
              </React.Fragment>
            ))}

            {!isLoading && (!templates || templates.length === 0) && !showAdd && (
              <tr>
                <td colSpan={8} className="px-3 py-6 text-center text-content-muted">
                  No render templates configured. Click "Add Template" to create one.
                </td>
              </tr>
            )}
          </tbody>
        </table>
      </div>
      <p className="mt-2 text-xs text-content-muted">
        Templates define pre-designed .blend studio setups. When rendering, the system matches templates by Category + Output Type with fallback cascade.
      </p>
    </div>
  )
}
