'use client'

import { useMemo, useState, Fragment } from 'react'
import { useAiConsent } from '@/components/legal/ai-consent-provider'
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from '@/components/ui/alert-dialog'
import type { Note } from '@/lib/types'
import type {
  ColumnFilter,
  ColumnSort,
  NotebookSchemaPayload,
  NotePropertyValues,
} from '@/lib/structured-views/types'
import {
  filterNotesWithProperties,
  sortNotesWithProperties,
} from '@/lib/structured-views/property-utils'
import { PropertyValueEditor } from './property-value-editor'
import { getNoteDisplayTitle } from '@/lib/note-preview'
import { useLanguage } from '@/lib/i18n'
import { formatAbsoluteDateLocalized } from '@/lib/utils/format-localized-date'
import { enUS, fr, faIR } from 'date-fns/locale'
import { ChevronDown, ChevronUp, Filter, Trash2, Sparkles, Brain, Loader2, ArrowUpRight, Link2, Sigma } from 'lucide-react'
import { cn } from '@/lib/utils'
import { openNotePeek } from '@/lib/note-peek-sync'

const localeMap: Record<string, any> = {
  en: enUS,
  fr,
  fa: faIR
}

function getDateLocale(lang: string) {
  return localeMap[lang] || enUS
}

const getBestFallbackKeyword = (title: string): string => {
  const STOP_WORDS = new Set([
    'dans', 'avec', 'pour', 'plus', 'tout', 'tous', 'cette', 'ceux', 'mais', 'sans', 
    'faire', 'fait', 'comme', 'sont', 'ont', 'etaient', 'etait', 'sujet', 'fiche', 'page', 
    'note', 'notes', 'guide', 'guides', 'projet', 'projets', 'test', 'tests', 'demo', 'base', 
    'bases', 'donnee', 'donnees', 'tableau', 'tableaux', 'quel', 'quels', 'quelle', 'quelles',
    'about', 'with', 'from', 'that', 'this', 'your', 'have', 'were', 'was', 'project', 
    'projects', 'test', 'tests', 'page', 'pages', 'file', 'files', 'some', 'more', 'their', 
    'them', 'they', 'what', 'which', 'where', 'when', 'how', 'who', 'why'
  ])

  const words = title
    .toLowerCase()
    .split(/[^\p{L}\d]+/u)
    .filter(w => w.length > 3 && !STOP_WORDS.has(w))

  if (words.length === 0) return ''
  words.sort((a, b) => b.length - a.length)
  return words[0]
}

type NotesStructuredTableProps = {
  notes: Note[]
  schema: NotebookSchemaPayload
  noteValues: Record<string, NotePropertyValues>
  onOpen: (note: Note) => void
  onPropertyChange: (noteId: string, propertyId: string, value: unknown) => void
  onDeleteProperty?: (propertyId: string) => Promise<void>
}

export function NotesStructuredTable({
  notes,
  schema,
  noteValues,
  onOpen,
  onPropertyChange,
  onDeleteProperty,
}: NotesStructuredTableProps) {
  const { t, language } = useLanguage()
  const untitled = t('notes.untitled')
  const [sort, setSort] = useState<ColumnSort>({ propertyId: 'updatedAt', direction: 'desc' })
  const [filterPropId, setFilterPropId] = useState<string | null>(null)
  const [filterOp, setFilterOp] = useState<ColumnFilter['operator']>('contains')
  const [filterValue, setFilterValue] = useState('')
  const [propertyToDelete, setPropertyToDelete] = useState<{ id: string; name: string } | null>(null)
  const [deletingProperty, setDeletingProperty] = useState(false)
  const [calcTypes, setCalcTypes] = useState<Record<string, 'none' | 'sum' | 'avg' | 'min' | 'max' | 'count'>>({})

  // Memory Echo states
  const { requestAiConsent } = useAiConsent()
  const [activeEchoNoteId, setActiveEchoNoteId] = useState<string | null>(null)
  const [echoLoading, setEchoLoading] = useState(false)
  const [echoError, setEchoError] = useState<string | null>(null)
  const [echoConnections, setEchoConnections] = useState<Array<{ noteId: string; title: string; similarity: number; isTextMatch?: boolean }>>([])

  const handleFetchRealEcho = async (noteId: string) => {
    if (activeEchoNoteId === noteId) {
      setActiveEchoNoteId(null)
      setEchoConnections([])
      setEchoError(null)
      return
    }
    setActiveEchoNoteId(noteId)
    setEchoLoading(true)
    setEchoConnections([])
    setEchoError(null)

    try {
      // 1. GDPR AI Consent check
      const consented = await requestAiConsent()
      if (!consented) {
        setEchoError("Le consentement pour le traitement par IA est requis pour utiliser la résonance sémantique.")
        setEchoLoading(false)
        return
      }

      // 2. Fetch connections
      const res = await fetch(`/api/ai/echo/connections?noteId=${noteId}&limit=5`)
      
      if (res.status === 403) {
        setEchoError("Le consentement pour le traitement par IA est requis pour utiliser la résonance sémantique.")
        setEchoLoading(false)
        return
      }

      const json = await res.json()
      
      if (json.connections && Array.isArray(json.connections) && json.connections.length > 0) {
        setEchoConnections(json.connections)
      } else {
        // 3. Fallback: Si aucune connexion pré-calculée en DB, on fait une recherche textuelle en direct
        const targetNote = notes.find(n => n.id === noteId)
        const q = (targetNote?.title || '').trim()
        
        if (!q) {
          setEchoError("Cette note n'a pas encore de titre ou de contenu suffisant pour trouver des résonances sémantiques.")
          setEchoLoading(false)
          return
        }

        const fallbackRes = await fetch(`/api/notes?search=${encodeURIComponent(q)}&limit=5`)
        const fallbackJson = await fallbackRes.json()
        
        let filteredNotes = (fallbackJson.success && Array.isArray(fallbackJson.data))
          ? fallbackJson.data.filter((n: any) => n.id !== noteId)
          : []
          
        if (filteredNotes.length === 0) {
          // Fallback to searching significant words if full title matches nothing else
          const fallbackWord = getBestFallbackKeyword(q)
          if (fallbackWord) {
            const resFallback = await fetch(`/api/notes?search=${encodeURIComponent(fallbackWord)}&limit=5`)
            const jsonFallback = await resFallback.json()
            if (jsonFallback.success && Array.isArray(jsonFallback.data)) {
              filteredNotes = jsonFallback.data.filter((n: any) => n.id !== noteId)
            }
          }
        }

        if (filteredNotes.length === 0) {
          setEchoError(`Aucune note similaire à "${q}" n'a été détectée dans votre espace de travail.`)
        } else {
          setEchoConnections(filteredNotes.map((n: any, idx: number) => ({
            noteId: n.id,
            title: n.title || 'Sans titre',
            similarity: 0.82 - idx * 0.04,
            isTextMatch: true
          })))
        }
      }
    } catch (e) {
      console.error(e)
      setEchoError("Une erreur est survenue lors de la recherche.")
    } finally {
      setEchoLoading(false)
    }
  }

  const filters: ColumnFilter[] = useMemo(() => {
    if (!filterPropId) return []
    return [{ propertyId: filterPropId, operator: filterOp, value: filterValue }]
  }, [filterPropId, filterOp, filterValue])

  const displayed = useMemo(() => {
    const filtered = filterNotesWithProperties(notes, noteValues, filters, schema.properties)
    return sortNotesWithProperties(filtered, noteValues, sort, schema.properties)
  }, [notes, noteValues, filters, sort, schema.properties])

  const numberProperties = schema.properties.filter(p => p.type === 'number')

  const calculations = useMemo(() => {
    const result: Record<string, { value: string | null; type: string }> = {}
    for (const prop of schema.properties) {
      const calcType = calcTypes[prop.id] || (prop.type === 'number' ? 'sum' : 'count')
      if (calcType === 'none') { result[prop.id] = { value: null, type: 'none' }; continue }

      const values = displayed
        .map(n => noteValues[n.id]?.[prop.id])
        .filter(v => v !== null && v !== undefined && v !== '')

      if (prop.type === 'number') {
        const nums = values.map(v => parseFloat(String(v))).filter(n => !isNaN(n))
        if (nums.length === 0) { result[prop.id] = { value: null, type: calcType }; continue }
        if (calcType === 'sum') result[prop.id] = { value: formatNum(nums.reduce((a, b) => a + b, 0)), type: 'sum' }
        else if (calcType === 'avg') result[prop.id] = { value: formatNum(nums.reduce((a, b) => a + b, 0) / nums.length), type: 'avg' }
        else if (calcType === 'min') result[prop.id] = { value: formatNum(Math.min(...nums)), type: 'min' }
        else if (calcType === 'max') result[prop.id] = { value: formatNum(Math.max(...nums)), type: 'max' }
        else if (calcType === 'count') result[prop.id] = { value: String(nums.length), type: 'count' }
      } else {
        result[prop.id] = { value: calcType === 'count' ? String(values.length) : null, type: calcType }
      }
    }
    return result
  }, [displayed, noteValues, schema.properties, calcTypes])

  function formatNum(n: number): string {
    return Number.isInteger(n) ? String(n) : n.toFixed(2)
  }

  function cycleCalcType(propId: string, propType: string) {
    const current = calcTypes[propId] || (propType === 'number' ? 'sum' : 'count')
    const numberCycle: Array<typeof current> = ['sum', 'avg', 'min', 'max', 'count', 'none']
    const otherCycle: Array<typeof current> = ['count', 'none']
    const cycle = propType === 'number' ? numberCycle : otherCycle
    const nextIdx = (cycle.indexOf(current) + 1) % cycle.length
    setCalcTypes(prev => ({ ...prev, [propId]: cycle[nextIdx] }))
  }

  const calcLabel = (type: string): string => {
    const labels: Record<string, string> = {
      sum: 'Σ', avg: 'x̄', min: 'min', max: 'max', count: '#', none: ''
    }
    return labels[type] || ''
  }

  const toggleSort = (propertyId: ColumnSort['propertyId']) => {
    setSort((prev) =>
      prev.propertyId === propertyId
        ? { propertyId, direction: prev.direction === 'asc' ? 'desc' : 'asc' }
        : { propertyId, direction: 'asc' },
    )
  }

  const SortIcon = ({ field }: { field: ColumnSort['propertyId'] }) =>
    sort.propertyId !== field ? null : sort.direction === 'asc' ? (
      <ChevronUp size={12} />
    ) : (
      <ChevronDown size={12} />
    )

  return (
    <div className="max-w-6xl mx-auto space-y-3">
      <div className="flex flex-wrap items-center gap-2 text-[11px]">
        <Filter size={14} className="text-muted-foreground" />
        <select
          value={filterPropId ?? ''}
          onChange={(e) => setFilterPropId(e.target.value || null)}
          className="rounded-lg border border-border bg-background px-2 py-1"
        >
          <option value="">{t('structuredViews.noFilter')}</option>
          <option value="title">{t('notes.tableTitle')}</option>
          {schema.properties.map((p) => (
            <option key={p.id} value={p.id}>{p.name}</option>
          ))}
        </select>
        {filterPropId && (
          <>
            <select
              value={filterOp}
              onChange={(e) => setFilterOp(e.target.value as ColumnFilter['operator'])}
              className="rounded-lg border border-border bg-background px-2 py-1"
            >
              <option value="contains">{t('structuredViews.filterContains')}</option>
              <option value="equals">{t('structuredViews.filterEquals')}</option>
              <option value="empty">{t('structuredViews.filterEmpty')}</option>
            </select>
            {filterOp !== 'empty' && (
              <input
                value={filterValue}
                onChange={(e) => setFilterValue(e.target.value)}
                className="rounded-lg border border-border bg-background px-2 py-1 min-w-[120px]"
                placeholder={t('structuredViews.filterValue')}
              />
            )}
          </>
        )}
      </div>

      <div className="overflow-x-auto border border-border/40 rounded-2xl bg-card/30 shadow-sm">
        <table className="w-full text-left border-collapse min-w-[800px]">
          <thead>
            <tr className="border-b border-border/30">
              <th
                className="px-4 py-3 text-[10px] uppercase tracking-widest font-black text-muted-foreground cursor-pointer hover:text-foreground w-[22%]"
                onClick={() => toggleSort('title')}
              >
                <span className="inline-flex items-center gap-1">
                  {t('notes.tableTitle')} <SortIcon field="title" />
                </span>
              </th>
              {schema.properties.map((p) => (
                <th
                  key={p.id}
                  className="px-4 py-3 text-[10px] uppercase tracking-widest font-black text-muted-foreground group/col"
                >
                  <span className="inline-flex items-center gap-1">
                    <button
                      type="button"
                      onClick={() => toggleSort(p.id)}
                      className="inline-flex items-center gap-1 hover:text-foreground transition-colors"
                    >
                      {p.name} <SortIcon field={p.id} />
                    </button>
                    {onDeleteProperty && (
                      <button
                        type="button"
                        onClick={(e) => {
                          e.stopPropagation()
                          setPropertyToDelete({ id: p.id, name: p.name })
                        }}
                        className="opacity-40 group-hover/col:opacity-100 p-0.5 rounded hover:text-red-500 hover:bg-red-500/10 transition-all shrink-0"
                        title={t('structuredViews.deleteProperty')}
                        aria-label={t('structuredViews.deleteProperty')}
                      >
                        <Trash2 size={11} />
                      </button>
                    )}
                  </span>
                </th>
              ))}
              <th
                className="px-4 py-3 text-[10px] uppercase tracking-widest font-black text-muted-foreground cursor-pointer hover:text-foreground w-[12%]"
                onClick={() => toggleSort('updatedAt')}
              >
                <span className="inline-flex items-center gap-1">
                  {t('notes.tableModified')} <SortIcon field="updatedAt" />
                </span>
              </th>
            </tr>
          </thead>
          <tbody className="divide-y divide-foreground/[0.03]">
            {displayed.map((note) => {
              const vals = noteValues[note.id] ?? {}
              return (
                <Fragment key={note.id}>
                  <tr key={note.id} className="hover:bg-foreground/[0.015] transition-colors group">
                    <td className="px-4 py-2 align-middle">
                      <div className="flex items-center gap-2">
                        <button
                          type="button"
                          onClick={() => onOpen(note)}
                          className="font-memento-serif text-[13px] font-medium text-left truncate max-w-[200px] group-hover:text-brand-accent transition-colors shrink-0"
                        >
                          {getNoteDisplayTitle(note, untitled)}
                        </button>
                        
                        <button
                          type="button"
                          onClick={() => handleFetchRealEcho(note.id)}
                          className={cn(
                            "opacity-0 group-hover:opacity-100 p-1 rounded transition-all shrink-0",
                            activeEchoNoteId === note.id
                              ? "text-purple-400 bg-purple-500/10 opacity-100"
                              : "text-muted-foreground hover:text-purple-400 hover:bg-purple-500/10"
                          )}
                          title="Résonances sémantiques"
                        >
                          <Sparkles size={11} className={activeEchoNoteId === note.id ? "animate-pulse" : ""} />
                        </button>
                      </div>
                    </td>
                    {schema.properties.map((p) => (
                      <td
                        key={p.id}
                        className="px-4 py-2 align-top"
                        onClick={(e) => e.stopPropagation()}
                      >
                        <div className="min-w-[100px] max-w-[180px]">
                          <PropertyValueEditor
                            property={p}
                            value={vals[p.id]}
                            compact
                            onChange={(v) => onPropertyChange(note.id, p.id, v)}
                          />
                        </div>
                      </td>
                    ))}
                    <td className="px-4 py-2 text-[11px] text-muted-foreground whitespace-nowrap align-middle">
                      {formatAbsoluteDateLocalized(new Date(note.updatedAt), language, 'MMM d, yyyy', getDateLocale(language))}
                    </td>
                  </tr>

                  {/* Memory Echo collapsible details */}
                  {activeEchoNoteId === note.id && (
                    <tr className="bg-purple-500/[0.015]">
                      <td colSpan={schema.properties.length + 3} className="px-5 py-3.5 border-t border-b border-purple-500/10">
                        <div className="space-y-3 animate-in slide-in-from-top-1 duration-200">
                          <div className="flex items-center justify-between text-[11px] font-bold text-foreground/80">
                            <span className="flex items-center gap-1.5 text-purple-400">
                              <Brain className="w-3.5 h-3.5 animate-pulse" />
                              {t('structuredViewBlock.echoPopoverTitle') || 'Résonance Sémantique 🔮'}
                            </span>
                            <button
                              onClick={() => { setActiveEchoNoteId(null); setEchoConnections([]); }}
                              className="text-[10px] text-muted-foreground hover:text-foreground hover:underline transition-colors"
                            >
                              Fermer
                            </button>
                          </div>

                          {echoLoading ? (
                            <div className="flex items-center gap-2 text-[11px] text-muted-foreground py-2">
                              <Loader2 className="w-3.5 h-3.5 animate-spin text-purple-400" />
                              <span>{t('structuredViewBlock.echoLoading') || 'Recherche de connexions sémantiques...'}</span>
                            </div>
                          ) : echoError ? (
                            <p className="text-[11px] text-muted-foreground/90 font-medium py-1">
                              {echoError}
                            </p>
                          ) : echoConnections.length === 0 ? (
                            <p className="text-[11px] text-muted-foreground italic py-1">
                              {t('structuredViewBlock.noEchoFound') || 'Aucune résonance sémantique détectée.'}
                            </p>
                          ) : (
                            <div className="space-y-2">
                              <div className="grid grid-cols-1 sm:grid-cols-2 gap-2 max-w-2xl">
                                {echoConnections.map((conn) => (
                                  <div
                                    key={conn.noteId}
                                    className="flex items-center justify-between p-2.5 rounded-xl bg-card border border-border/50 hover:border-purple-500/40 hover:bg-purple-500/[0.02] text-left text-[11px] transition-all group shadow-sm gap-2"
                                  >
                                    <button
                                      type="button"
                                      onClick={() => openNotePeek({ noteId: conn.noteId })}
                                      className="flex-1 text-left truncate font-semibold text-foreground/80 hover:text-purple-400 transition-colors"
                                    >
                                      {conn.title}
                                    </button>
                                    
                                    <div className="flex items-center gap-1.5 shrink-0">
                                      <button
                                        type="button"
                                        onClick={(e) => {
                                          e.stopPropagation()
                                          window.dispatchEvent(new CustomEvent('memento-insert-citation', {
                                            detail: {
                                              noteId: conn.noteId,
                                              noteTitle: conn.title || 'Sans titre',
                                              excerpt: '',
                                              atEnd: false
                                            }
                                          }))
                                        }}
                                        className="p-1 text-muted-foreground hover:text-purple-400 hover:bg-purple-500/10 rounded transition-colors"
                                        title="Insérer le lien dans l'éditeur"
                                      >
                                        <Link2 className="w-3.5 h-3.5" />
                                      </button>
                                      <span className="text-[9px] text-purple-400 font-bold bg-purple-500/10 px-2 py-0.5 rounded-full flex items-center gap-0.5 border border-purple-500/20">
                                        {conn.isTextMatch ? 'Mot-clé' : `${Math.round((conn.similarity || 0) * 100)}%`}
                                      </span>
                                    </div>
                                  </div>
                                ))}
                              </div>
                            </div>
                          )}
                        </div>
                      </td>
                    </tr>
                  )}
                </Fragment>
              )
            })}
          </tbody>
          {numberProperties.length > 0 && (
            <tfoot>
              <tr className="border-t-2 border-border/40 bg-muted/20">
                <td className="px-4 py-2 text-[10px] uppercase tracking-widest font-bold text-muted-foreground">
                  <span className="flex items-center gap-1">
                    <Sigma size={12} />
                    {t('structuredViews.calculations')}
                  </span>
                </td>
                {schema.properties.map((p) => {
                  const calc = calculations[p.id]
                  if (!calc || calc.value === null) {
                    return <td key={p.id} className="px-4 py-2 text-[11px] text-muted-foreground/40">—</td>
                  }
                  return (
                    <td key={p.id} className="px-4 py-2">
                      <button
                        type="button"
                        onClick={() => cycleCalcType(p.id, p.type)}
                        className="text-[11px] font-semibold tabular-nums hover:text-primary transition-colors"
                        title={t('structuredViews.calcClickToChange')}
                      >
                        <span className="text-muted-foreground mr-1">{calcLabel(calc.type)}</span>
                        {calc.value}
                      </button>
                    </td>
                  )
                })}
                <td />
              </tr>
            </tfoot>
          )}
        </table>
        {displayed.length === 0 && (
          <p className="text-center py-8 text-muted-foreground text-sm">{t('structuredViews.noMatchingNotes')}</p>
        )}
      </div>

      <AlertDialog
        open={Boolean(propertyToDelete)}
        onOpenChange={(open) => {
          if (!open) setPropertyToDelete(null)
        }}
      >
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>{t('structuredViews.deletePropertyTitle')}</AlertDialogTitle>
            <AlertDialogDescription>
              {t('structuredViews.deletePropertyConfirm', { name: propertyToDelete?.name ?? '' })}
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel disabled={deletingProperty}>{t('general.cancel')}</AlertDialogCancel>
            <AlertDialogAction
              disabled={deletingProperty || !propertyToDelete}
              className="bg-red-600 hover:bg-red-700"
              onClick={async (e) => {
                e.preventDefault()
                if (!propertyToDelete || !onDeleteProperty) return
                setDeletingProperty(true)
                try {
                  await onDeleteProperty(propertyToDelete.id)
                  if (filterPropId === propertyToDelete.id) setFilterPropId(null)
                  setPropertyToDelete(null)
                } finally {
                  setDeletingProperty(false)
                }
              }}
            >
              {t('structuredViews.deleteProperty')}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  )
}