'use client'

import React, { useCallback, useMemo, useRef, useState } from 'react'
import dynamic from 'next/dynamic'
import { BrainstormSession, BrainstormIdea } from '@/types/brainstorm'
import {
  useExpandIdea,
  useDismissIdea,
  useConvertIdea,
  useExportBrainstorm,
  brainstormQuotaMessageKey,
} from '@/hooks/use-brainstorm'
import { Sheet, SheetContent, SheetHeader, SheetTitle } from '@/components/ui/sheet'
import { Button } from '@/components/ui/button'
import { Sparkles, X, FileText, Download } from 'lucide-react'
import { toast } from 'sonner'
import { useLanguage } from '@/lib/i18n'

const ForceGraph2D = dynamic(() => import('react-force-graph-2d'), {
  ssr: false,
})

interface GraphNode {
  id: string
  name: string
  val: number
  color: string
  borderColor: string
  wave: number
  status: string
  idea: BrainstormIdea
  x?: number
  y?: number
  __bckgDimensions?: [number, number]
}

interface GraphLink {
  source: string | GraphNode
  target: string | GraphNode
  color: string
}

const WAVE_COLORS: Record<number, string> = {
  0: '#ffffff',
  1: '#f97316',
  2: '#3b82f6',
  3: '#a855f7',
}

const WAVE_BORDER: Record<number, string> = {
  0: '#e5e5e5',
  1: '#ea580c',
  2: '#2563eb',
  3: '#9333ea',
}

const STATUS_ALPHA: Record<string, number> = {
  active: 1,
  dismissed: 0.25,
  converted: 0.9,
}

interface BrainstormCanvasProps {
  session: BrainstormSession
}

export function BrainstormCanvas({ session }: BrainstormCanvasProps) {
  const { t } = useLanguage()
  const fgRef = useRef<any>(null)
  const [selectedIdea, setSelectedIdea] = useState<BrainstormIdea | null>(null)
  const [isSheetOpen, setIsSheetOpen] = useState(false)
  const expandIdea = useExpandIdea(session.id)
  const dismissIdea = useDismissIdea(session.id)
  const convertIdea = useConvertIdea(session.id)
  const exportBrainstorm = useExportBrainstorm(session.id)

  const { graphData } = useMemo(() => {
    const nodes: GraphNode[] = []
    const links: GraphLink[] = []

    nodes.push({
      id: 'seed',
      name: session.seedIdea.length > 30 ? session.seedIdea.slice(0, 30) + '...' : session.seedIdea,
      val: 25,
      color: WAVE_COLORS[0],
      borderColor: WAVE_BORDER[0],
      wave: 0,
      status: 'active',
      idea: {
        id: 'seed',
        sessionId: session.id,
        waveNumber: 0,
        title: session.seedIdea,
        description: t('brainstorm.originalSeedDescription'),
        connectionToSeed: null,
        noveltyScore: null,
        parentIdeaId: null,
        convertedToNoteId: null,
        relatedNoteIds: null,
        status: 'active',
        positionX: null,
        positionY: null,
        createdAt: session.createdAt,
      } as BrainstormIdea,
    })

    for (const idea of session.ideas) {
      const parentNode = idea.parentIdeaId
        ? idea.parentIdeaId
        : 'seed'

      nodes.push({
        id: idea.id,
        name: idea.title,
        val: idea.status === 'dismissed' ? 8 : 15,
        color: WAVE_COLORS[idea.waveNumber] || WAVE_COLORS[3],
        borderColor: idea.status === 'converted' ? '#22c55e' : (WAVE_BORDER[idea.waveNumber] || WAVE_BORDER[3]),
        wave: idea.waveNumber,
        status: idea.status,
        idea,
      })

      const linkColor = WAVE_COLORS[idea.waveNumber] || WAVE_COLORS[3]
      links.push({
        source: parentNode,
        target: idea.id,
        color: idea.status === 'dismissed' ? '#444444' : linkColor,
      })
    }

    return { graphData: { nodes, links } }
  }, [session, t])

  const handleNodeClick = useCallback((node: any) => {
    setSelectedIdea(node.idea)
    setIsSheetOpen(true)
  }, [])

  const handleExpand = useCallback(async () => {
    if (!selectedIdea || selectedIdea.id === 'seed') return
    try {
      await expandIdea.mutateAsync({ ideaId: selectedIdea.id })
      toast.success(t('brainstorm.toastExpandSuccess'))
    } catch (err: unknown) {
      const quotaKey = brainstormQuotaMessageKey(err)
      toast.error(quotaKey ? t(quotaKey) : (err instanceof Error ? err.message : t('brainstorm.toastExpandFailed')))
    }
  }, [selectedIdea, expandIdea, t])

  const handleDismiss = useCallback(async () => {
    if (!selectedIdea || selectedIdea.id === 'seed') return
    try {
      await dismissIdea.mutateAsync(selectedIdea.id)
      setIsSheetOpen(false)
      setSelectedIdea(null)
      toast.success(t('brainstorm.toastDismissSuccess'))
    } catch (err: any) {
      toast.error(err.message || t('brainstorm.toastDismissFailed'))
    }
  }, [selectedIdea, dismissIdea, t])

  const handleConvert = useCallback(async () => {
    if (!selectedIdea || selectedIdea.id === 'seed') return
    try {
      await convertIdea.mutateAsync(selectedIdea.id)
      toast.success(t('brainstorm.toastConvertSuccess'))
    } catch (err: any) {
      toast.error(err.message || t('brainstorm.toastConvertFailed'))
    }
  }, [selectedIdea, convertIdea, t])

  const handleExport = useCallback(async () => {
    try {
      const note = await exportBrainstorm.mutateAsync()
      toast.success(t('brainstorm.toastExportNoteSuccess'))
    } catch (err: any) {
      toast.error(err.message || t('brainstorm.toastExportFailed'))
    }
  }, [exportBrainstorm, t])

  const paintNode = useCallback((node: any, ctx: CanvasRenderingContext2D, globalScale: number) => {
    const label = node.name
    const fontSize = Math.max(12 / globalScale, 4)
    ctx.font = `${fontSize}px Sans-Serif`
    const textWidth = ctx.measureText(label).width
    const nodeSize = node.val

    const bgDimensions: [number, number] = [textWidth + nodeSize * 0.8, nodeSize * 1.2]
    node.__bckgDimensions = bgDimensions

    const alpha = STATUS_ALPHA[node.status] || 1
    ctx.globalAlpha = alpha

    ctx.fillStyle = node.color
    ctx.strokeStyle = node.borderColor
    ctx.lineWidth = node.status === 'converted' ? 3 / globalScale : 1.5 / globalScale

    ctx.beginPath()
    ctx.roundRect(
      node.x! - bgDimensions[0] / 2,
      node.y! - bgDimensions[1] / 2,
      bgDimensions[0],
      bgDimensions[1],
      nodeSize * 0.3
    )
    ctx.fill()
    ctx.stroke()

    ctx.fillStyle = node.wave === 0 ? '#000000' : '#ffffff'
    ctx.textAlign = 'center'
    ctx.textBaseline = 'middle'
    ctx.fillText(label, node.x!, node.y!)

    if (node.status === 'converted') {
      ctx.fillStyle = '#22c55e'
      ctx.font = `${fontSize * 1.2}px Sans-Serif`
      ctx.fillText('✓', node.x! + bgDimensions[0] / 2 - fontSize * 0.5, node.y! - bgDimensions[1] / 2 + fontSize * 0.5)
    }

    ctx.globalAlpha = 1
  }, [])

  const waveLegend = useMemo(
    () => [
      { label: t('brainstorm.legendSeed'), color: WAVE_COLORS[0] },
      { label: t('brainstorm.legendVariations'), color: WAVE_COLORS[1] },
      { label: t('brainstorm.legendAnalogies'), color: WAVE_COLORS[2] },
      { label: t('brainstorm.legendDisruptions'), color: WAVE_COLORS[3] },
    ],
    [t]
  )

  return (
    <div className="relative w-full h-full bg-zinc-950 rounded-xl overflow-hidden">
      <ForceGraph2D
        ref={fgRef}
        graphData={graphData}
        nodeCanvasObject={paintNode}
        nodePointerAreaPaint={(node: any, color: string, ctx: CanvasRenderingContext2D) => {
          const dims = node.__bckgDimensions
          if (!dims) return
          ctx.fillStyle = color
          ctx.beginPath()
          ctx.roundRect(node.x! - dims[0] / 2, node.y! - dims[1] / 2, dims[0], dims[1], (node.val || 10) * 0.3)
          ctx.fill()
        }}
        onNodeClick={handleNodeClick}
        linkColor={(link: any) => link.color}
        linkWidth={1}
        linkDirectionalArrowLength={3}
        linkDirectionalArrowRelPos={1}
        backgroundColor="#09090b"
        nodeVal={(node: any) => node.val}
        cooldownTicks={100}
        enableNodeDrag={true}
        enableZoomInteraction={true}
        enablePanInteraction={true}
        warmupTicks={50}
      />

      <div className="absolute top-4 left-4 flex flex-col gap-1.5">
        {waveLegend.map(w => (
          <div key={w.label} className="flex items-center gap-2 text-xs text-zinc-400">
            <div className="w-3 h-3 rounded-sm border border-zinc-600" style={{ backgroundColor: w.color }} />
            <span>{w.label}</span>
          </div>
        ))}
      </div>

      <div className="absolute top-4 right-4">
        <Button
          size="sm"
          variant="outline"
          className="bg-zinc-800 border-zinc-700 text-zinc-300 hover:bg-zinc-700 hover:text-white"
          onClick={handleExport}
          disabled={exportBrainstorm.isPending}
        >
          <Download size={14} className="mr-1" />
          {exportBrainstorm.isPending ? t('brainstorm.exporting') : t('brainstorm.export')}
        </Button>
      </div>

      <Sheet open={isSheetOpen} onOpenChange={setIsSheetOpen}>
        <SheetContent className="bg-zinc-900 border-zinc-800 text-white w-96">
          {selectedIdea && (
            <>
              <SheetHeader>
                <SheetTitle className="text-white text-left">
                  {selectedIdea.id === 'seed' ? session.seedIdea : selectedIdea.title}
                </SheetTitle>
              </SheetHeader>
              <div className="mt-6 space-y-4">
                {selectedIdea.description && selectedIdea.id !== 'seed' && (
                  <div>
                    <p className="text-xs text-zinc-500 uppercase tracking-wider mb-1">{t('brainstorm.ideaDetailDescription')}</p>
                    <p className="text-sm text-zinc-300">{selectedIdea.description}</p>
                  </div>
                )}

                {selectedIdea.connectionToSeed && (
                  <div>
                    <p className="text-xs text-zinc-500 uppercase tracking-wider mb-1">{t('brainstorm.ideaDetailConnection')}</p>
                    <p className="text-sm text-zinc-300">{selectedIdea.connectionToSeed}</p>
                  </div>
                )}

                {(selectedIdea.noveltyScore != null && selectedIdea.noveltyScore > 0) && (
                  <div>
                    <p className="text-xs text-zinc-500 uppercase tracking-wider mb-1">{t('brainstorm.ideaDetailNovelty')}</p>
                    <div className="flex items-center gap-2">
                      <div className="flex-1 h-2 bg-zinc-800 rounded-full overflow-hidden">
                        <div
                          className="h-full bg-gradient-to-r from-orange-500 via-brand-accent to-purple-500 rounded-full"
                          style={{ width: `${Math.min(100, Math.max(0, selectedIdea.noveltyScore * 10))}%` }}
                        />
                      </div>
                      <span className="text-sm text-zinc-400">{selectedIdea.noveltyScore}/10</span>
                    </div>
                  </div>
                )}

                {selectedIdea.waveNumber > 0 && (
                  <div>
                    <p className="text-xs text-zinc-500 uppercase tracking-wider mb-1">{t('brainstorm.ideaDetailWave')}</p>
                    <span
                      className="inline-block px-2 py-0.5 rounded text-xs font-medium"
                      style={{
                        backgroundColor: WAVE_COLORS[selectedIdea.waveNumber] + '30',
                        color: WAVE_COLORS[selectedIdea.waveNumber],
                      }}
                    >
                      {selectedIdea.waveNumber === 1
                        ? t('brainstorm.waveFlavorVariation')
                        : selectedIdea.waveNumber === 2
                          ? t('brainstorm.waveFlavorAnalogy')
                          : t('brainstorm.waveFlavorDisruption')}
                    </span>
                  </div>
                )}

                {selectedIdea.status === 'converted' && (
                  <div className="p-3 bg-green-500/10 border border-green-500/20 rounded-lg">
                    <p className="text-xs text-green-400 flex items-center gap-1">
                      <FileText size={12} />
                      {t('brainstorm.convertedToNoteStatus')}
                    </p>
                  </div>
                )}

                {selectedIdea.id !== 'seed' && selectedIdea.status === 'active' && (
                  <div className="flex flex-col gap-2 pt-4 border-t border-zinc-800">
                    <Button
                      onClick={handleExpand}
                      disabled={expandIdea.isPending}
                      className="w-full bg-orange-600 hover:bg-orange-700 text-white"
                    >
                      <Sparkles size={14} className="mr-1" />
                      {expandIdea.isPending ? t('brainstorm.deepening') : t('brainstorm.deepen')}
                    </Button>
                    <Button
                      onClick={handleConvert}
                      disabled={convertIdea.isPending}
                      className="w-full bg-brand-accent hover:bg-blue-700 text-white"
                    >
                      <FileText size={14} className="mr-1" />
                      {convertIdea.isPending ? t('brainstorm.converting') : t('brainstorm.extract')}
                    </Button>
                    <Button
                      onClick={handleDismiss}
                      disabled={dismissIdea.isPending}
                      variant="outline"
                      className="w-full border-zinc-700 text-zinc-400 hover:text-white hover:bg-zinc-800"
                    >
                      <X size={14} className="mr-1" />
                      {t('brainstorm.dismiss')}
                    </Button>
                  </div>
                )}
              </div>
            </>
          )}
        </SheetContent>
      </Sheet>
    </div>
  )
}
