import React, { useState, useRef, useEffect } from 'react'
import { FaComment, FaPaperPlane, FaPlus, FaRobot, FaTrash } from 'react-icons/fa'
import { useStoreState } from '@/store'
import { Avatar, Button, Drawer, Dropdown, ScrollBar } from '@/components/ui'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { aiService } from '@/services/ai.service'
import { AiDto } from '@/proxy/ai/models'
import { Container } from '@/components/shared'
import { Helmet } from 'react-helmet'
import { APP_NAME } from '@/constants/app.constant'
import dayjs from 'dayjs'
import { AI_ASSISTANT } from '@/constants/permission.constant'

// Types
type ChatType = 'chat' | 'query' | 'analyze'

interface BaseContent {
  type: ChatType
  question: string
  sql: string | null
  answer: string | any[]
  chart?: string
  error?: string
}

type MessageContent = string | BaseContent

interface Message {
  role: 'user' | 'assistant'
  content: MessageContent
  createdAt?: string
}

interface Conversation {
  id: string
  title: string
  messages: Message[]
  createdAt: string
  updatedAt: string
}

const CONVERSATIONS_STORAGE_KEY = 'AiConversations'
const ACTIVE_CONVERSATION_STORAGE_KEY = 'AiActiveConversationId'

const getConversationTitle = (message: string) =>
  message.length > 42 ? `${message.slice(0, 42).trimEnd()}…` : message

const isContentObject = (content: MessageContent): content is BaseContent =>
  typeof content !== 'string' && 'type' in content

const renderInlineText = (text: string) =>
  text.split(/(\*\*[^*]+\*\*|"[^"\n]+")/g).map((part, index) => {
    if (part.startsWith('**') && part.endsWith('**')) {
      return <strong key={index}>{part.slice(2, -2)}</strong>
    }

    if (part.startsWith('"') && part.endsWith('"')) {
      return (
        <q
          key={index}
          className="rounded-md border border-blue-200 bg-blue-50 px-1.5 py-0.5 font-medium text-blue-800 dark:border-blue-800 dark:bg-blue-950/50 dark:text-blue-200"
        >
          {part.slice(1, -1)}
        </q>
      )
    }

    return <React.Fragment key={index}>{part}</React.Fragment>
  })

const renderFormattedText = (value: string) => {
  const text = value.replace(/\\"/g, '"').replace(/\\n/g, '\n').replace(/\r\n/g, '\n')

  return (
    <div className="space-y-2 whitespace-pre-wrap leading-6">
      {text.split('\n').map((line, index) => {
        if (!line.trim()) return <div key={index} className="h-2" />

        const listMarker = line.match(/^[-*+]\s+/)
        const isListItem = Boolean(listMarker)
        const content = isListItem ? line.slice(listMarker![0].length) : line

        return isListItem ? (
          <div key={index} className="flex gap-2">
            <span className="text-blue-500 dark:text-blue-300">•</span>
            <span>{renderInlineText(content)}</span>
          </div>
        ) : (
          <p key={index}>{renderInlineText(content)}</p>
        )
      })}
    </div>
  )
}

// Main Component
const Assistant = () => {
  // Hooks
  const [conversations, setConversations] = useState<Conversation[]>([])
  const [activeConversationId, setActiveConversationId] = useState<string | null>(null)
  const [isConversationsLoaded, setIsConversationsLoaded] = useState(false)
  const [isConversationDrawerOpen, setIsConversationDrawerOpen] = useState(false)
  const [, setMessages] = useState<Message[]>([])
  const aiPosts: Message[] = []
  const [input, setInput] = useState('')
  const [loading, setLoading] = useState(false)
  const [bot, setBot] = useState<AiDto[]>([])
  const [selectedBot, setSelectedBot] = useState<string | null>(null)

  const { avatar } = useStoreState((state) => state.auth.user)
  const inputRef = useRef<HTMLTextAreaElement | null>(null)
  const bottomRef = useRef<HTMLDivElement | null>(null)

  const { translate } = useLocalization()

  const createConversation = (): Conversation => {
    const now = new Date().toISOString()
    return {
      id: crypto.randomUUID(),
      title: translate('::App.Platform.NewChat'),
      messages: [],
      createdAt: now,
      updatedAt: now,
    }
  }

  useEffect(() => {
    if (messages.length === 0 && aiPosts.length > 0) {
      setMessages(aiPosts) // artık doğrudan Message[]
    }
  }, [aiPosts])

  useEffect(() => {
    try {
      const saved = localStorage.getItem(CONVERSATIONS_STORAGE_KEY)
      const parsed = saved ? JSON.parse(saved) : []
      const savedConversations = Array.isArray(parsed)
        ? parsed.filter(
            (conversation): conversation is Conversation =>
              conversation &&
              typeof conversation.id === 'string' &&
              Array.isArray(conversation.messages),
          )
        : []

      if (savedConversations.length > 0) {
        const savedActiveConversationId = localStorage.getItem(ACTIVE_CONVERSATION_STORAGE_KEY)
        setConversations(savedConversations)
        setActiveConversationId(
          savedConversations.some((conversation) => conversation.id === savedActiveConversationId)
            ? savedActiveConversationId
            : savedConversations[0].id,
        )
      } else {
        const legacyPosts = JSON.parse(localStorage.getItem('AiPosts') || '[]')
        const conversation = createConversation()
        if (Array.isArray(legacyPosts) && legacyPosts.length > 0) {
          conversation.messages = legacyPosts
          const firstQuestion = legacyPosts.find((message) => message.role === 'user')?.content
          conversation.title = firstQuestion
            ? getConversationTitle(String(firstQuestion))
            : conversation.title
        }
        setConversations([conversation])
        setActiveConversationId(conversation.id)
      }
    } catch (error) {
      console.warn('AI conversations localStorage parse error', error)
      const conversation = createConversation()
      setConversations([conversation])
      setActiveConversationId(conversation.id)
    }
    setIsConversationsLoaded(true)
  }, [])

  useEffect(() => {
    if (!isConversationsLoaded) return

    localStorage.setItem(CONVERSATIONS_STORAGE_KEY, JSON.stringify(conversations))
    if (activeConversationId) {
      localStorage.setItem(ACTIVE_CONVERSATION_STORAGE_KEY, activeConversationId)
    }
  }, [activeConversationId, conversations, isConversationsLoaded])

  const activeConversation = conversations.find(
    (conversation) => conversation.id === activeConversationId,
  )
  const messages = activeConversation?.messages || []

  const appendMessage = (conversationId: string, message: Message) => {
    setConversations((previous) => {
      const updatedConversations = previous.map((conversation) =>
        conversation.id === conversationId
          ? {
              ...conversation,
              title:
                conversation.messages.length === 0 && message.role === 'user'
                  ? getConversationTitle(String(message.content))
                  : conversation.title,
              messages: [...conversation.messages, message],
              updatedAt: message.createdAt || new Date().toISOString(),
            }
          : conversation,
      )

      return updatedConversations.sort(
        (first, second) => Date.parse(second.updatedAt) - Date.parse(first.updatedAt),
      )
    })
  }

  const handleNewConversation = () => {
    if (loading) return

    const emptyConversation = conversations.find(
      (conversation) => conversation.messages.length === 0,
    )
    if (emptyConversation) {
      setActiveConversationId(emptyConversation.id)
      setInput('')
      setIsConversationDrawerOpen(false)
      requestAnimationFrame(() => inputRef.current?.focus())
      return
    }

    const conversation = createConversation()
    setConversations((previous) => [conversation, ...previous])
    setActiveConversationId(conversation.id)
    setInput('')
    setIsConversationDrawerOpen(false)
    requestAnimationFrame(() => inputRef.current?.focus())
  }

  const handleSelectConversation = (conversationId: string) => {
    if (loading) return
    setActiveConversationId(conversationId)
    setIsConversationDrawerOpen(false)
    requestAnimationFrame(() => inputRef.current?.focus())
  }

  const handleDeleteConversation = (conversationId: string) => {
    if (loading) return

    const remainingConversations = conversations.filter(
      (conversation) => conversation.id !== conversationId,
    )
    const nextConversations = remainingConversations.length
      ? remainingConversations
      : [createConversation()]

    setConversations(nextConversations)

    if (conversationId === activeConversationId) {
      setActiveConversationId(nextConversations[0].id)
      setInput('')
    }
  }

  // Botları çek
  useEffect(() => {
    const fetchBots = async () => {
      try {
        const result = await aiService.getList({
          skipCount: 0,
          maxResultCount: 1000,
          sorting: 'name',
        })

        if (!result?.data?.items) {
          console.warn('Bot listesi boş veya hatalı formatta:', result)
          setBot([])
          return
        }

        setBot(result?.data?.items)
        const firstBotId = result?.data?.items?.find((item) => item.id)?.id ?? null
        setSelectedBot(firstBotId)
      } catch (error) {
        console.error('Bot listesi alınırken hata oluştu:', error)
      }
    }

    fetchBots()
  }, [])

  // Scroll to bottom
  useEffect(() => {
    bottomRef.current?.scrollIntoView({ behavior: 'smooth' })
  }, [messages])

  // Input focus after loading
  useEffect(() => {
    if (!loading) inputRef.current?.focus()
  }, [loading])

  // Bot seçim işlemi
  const onBotItemClick = (eventKey: string) => setSelectedBot(eventKey)

  // Gönderme işlemi
  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    if (!input.trim() || !activeConversation) return

    const userMessage = input.trim()
    const conversationId = activeConversation.id
    const userMessageCreatedAt = new Date().toISOString()
    setInput('')
    setLoading(true)

    // 1️⃣ Soruyu store'a ekle
    appendMessage(conversationId, {
      role: 'user',
      content: userMessage,
      createdAt: userMessageCreatedAt,
    })

    try {
      const selectedBotItem = bot.find((item) => item.id === selectedBot)
      const targetUrl = (selectedBotItem?.apiUrl || '').trim()

      if (!targetUrl) {
        throw new Error('AI bot URL bulunamadı.')
      }

      const response = await fetch(targetUrl, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          biletId: conversationId,
          question: userMessage,
          sessionId: conversationId,
        }),
      })

      const data = await response.json()
      const raw = Array.isArray(data) ? data[0] : data

      const mapped: BaseContent = {
        ...raw,
        result: raw.result || raw.answer || raw.error || 'Sonuç bulunamadı.',
      }

      // 2️⃣ Cevabı store'a ekle
      const assistantMessageCreatedAt = new Date().toISOString()

      appendMessage(conversationId, {
        role: 'assistant',
        content: mapped,
        createdAt: assistantMessageCreatedAt,
      })
    } catch {
      const errorMessage = 'Üzgünüm, bir hata oluştu. Lütfen tekrar deneyin.'
      const assistantMessageCreatedAt = new Date().toISOString()
      appendMessage(conversationId, {
        role: 'assistant',
        content: errorMessage,
        createdAt: assistantMessageCreatedAt,
      })
    }

    setLoading(false)
  }

  // Mesaj içeriği render
  const renderMessageContent = (message: Message) => {
    if (message.role === 'assistant' && isContentObject(message.content)) {
      const { type, sql, answer, chart, error } = message.content as BaseContent & {
        error?: string
      }

      const typeStyles: Record<string, string> = {
        chat: 'bg-blue-100 text-blue-700 dark:bg-blue-900/50 dark:text-blue-200',
        query: 'bg-green-100 text-green-700 dark:bg-green-900/50 dark:text-green-200',
        analyze: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/50 dark:text-yellow-200',
      }

      const typeLabels: Record<string, string> = {
        chat: '🗨️ ' + translate('::AI.SohbetAnswer'),
        query: '📊 ' + translate('::AI.DatabaseAnswer'),
        analyze: '📈 ' + translate('::AI.AnalizAnswer'),
      }

      const cleanedSql = (() => {
        try {
          const rawSql = decodeURIComponent(sql || '')
          return rawSql.replace(/^```sql\n?/, '').replace(/```$/, '')
        } catch {
          return sql
        }
      })()

      return (
        <div className="space-y-2 text-sm">
          <div
            className={`inline-block px-3 py-1 text-xs font-medium rounded-full mb-2 ${typeStyles[type] || 'bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-200'}`}
          >
            {typeLabels[type] || type}
          </div>

          {sql && (
            <div className="bg-gray-100 dark:bg-gray-800 p-3 rounded border border-gray-200 dark:border-gray-700 text-xs font-mono whitespace-pre-wrap">
              <pre>
                <code>{cleanedSql}</code>
              </pre>
            </div>
          )}

          {error ? (
            <div className="text-red-700 dark:text-red-200 bg-red-100 dark:bg-red-900/50 border border-red-300 dark:border-red-800 rounded p-2">
              ⚠️ <strong>Hata:</strong> {error}
            </div>
          ) : typeof answer === 'string' ? (
            renderFormattedText(answer)
          ) : Array.isArray(answer) ? (
            answer.length === 0 ? (
              <div className="text-gray-500 italic">Sonuç bulunamadı.</div>
            ) : (
              <div className="overflow-x-auto max-h-[400px] overflow-y-auto border border-gray-200 dark:border-gray-700 rounded">
                <table className="table-auto w-full text-sm">
                  <thead className="bg-gray-100 dark:bg-gray-800 sticky top-0">
                    <tr>
                      {Object.keys(answer[0]).map((col) => (
                        <th
                          key={col}
                          className="border border-gray-200 dark:border-gray-700 px-2 py-1 text-left"
                        >
                          {col}
                        </th>
                      ))}
                    </tr>
                  </thead>
                  <tbody>
                    {answer.map((row, rowIndex) => (
                      <tr key={rowIndex} className="hover:bg-gray-50 dark:hover:bg-gray-800">
                        {Object.keys(row).map((col, colIndex) => {
                          const val = row[col]
                          const display =
                            val === null || val === undefined
                              ? '—'
                              : typeof val === 'boolean'
                                ? val
                                  ? 'Evet'
                                  : 'Hayır'
                                : typeof val === 'string' && val.endsWith('T00:00:00.000Z')
                                  ? new Date(val).toLocaleDateString('tr-TR')
                                  : String(val)

                          return (
                            <td
                              key={colIndex}
                              className="border border-gray-200 dark:border-gray-700 px-2 py-1"
                            >
                              {display}
                            </td>
                          )
                        })}
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            )
          ) : typeof answer === 'object' && answer !== null && (answer as any).message ? (
            renderFormattedText(String((answer as any).message))
          ) : (
            <pre className="text-xs bg-gray-100 dark:bg-gray-800 p-2 rounded border border-gray-200 dark:border-gray-700">
              {JSON.stringify(answer, null, 2)}
            </pre>
          )}

          {chart && (
            <div className="mt-4">
              <img
                src={`data:image/png;base64,${chart}`}
                alt="Grafik"
                className="max-w-full rounded border border-gray-200 dark:border-gray-700"
              />
            </div>
          )}
        </div>
      )
    }

    return message.role === 'assistant' ? (
      <div className="text-sm">{renderFormattedText(String(message.content))}</div>
    ) : (
      <div className="whitespace-pre-wrap text-sm">{String(message.content)}</div>
    )
  }

  // Render
  return (
    <Container>
      <Helmet
        titleTemplate={`%s | ${APP_NAME}`}
        title={translate('::' + AI_ASSISTANT)}
        defaultTitle={APP_NAME}
      ></Helmet>

      <Drawer
        isOpen={isConversationDrawerOpen}
        onClose={() => setIsConversationDrawerOpen(false)}
        onRequestClose={() => setIsConversationDrawerOpen(false)}
        placement="left"
        title={translate('::App.Platform.Chats')}
        width={320}
        bodyClass="p-3"
      >
        <Button block icon={<FaPlus />} onClick={handleNewConversation} disabled={loading}>
          {translate('::App.Platform.NewChat')}
        </Button>
        <div className="mt-3 max-h-[calc(100vh-140px)] overflow-y-auto overscroll-contain">
          <div className="space-y-1">
            {conversations.map((conversation) => (
              <button
                key={conversation.id}
                type="button"
                onClick={() => handleSelectConversation(conversation.id)}
                className={`flex w-full items-center gap-2 rounded-lg px-3 py-3 text-left text-sm transition-colors ${
                  conversation.id === activeConversationId
                    ? 'bg-blue-50 text-blue-700 dark:bg-blue-900/40 dark:text-blue-200'
                    : 'text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-gray-700'
                }`}
              >
                <FaComment className="shrink-0" />
                <span className="truncate">{conversation.title}</span>
                <span
                  role="button"
                  tabIndex={0}
                  aria-label={`${conversation.title} sohbetini sil`}
                  onClick={(event) => {
                    event.stopPropagation()
                    handleDeleteConversation(conversation.id)
                  }}
                  className="ml-auto shrink-0 rounded p-1 text-gray-400 hover:bg-red-100 hover:text-red-600 dark:text-gray-500 dark:hover:bg-red-900/40 dark:hover:text-red-300"
                >
                  <FaTrash className="text-xs" />
                </span>
              </button>
            ))}
          </div>
        </div>
      </Drawer>

      <div className="h-[calc(100vh-140px)] pt-2 flex gap-4">
        <aside className="hidden w-64 shrink-0 flex-col rounded-xl border border-gray-200 bg-white p-3 dark:border-gray-700 dark:bg-gray-800 lg:flex">
          <Button block icon={<FaPlus />} onClick={handleNewConversation} disabled={loading}>
            {translate('::App.Platform.NewChat')}
          </Button>
          <ScrollBar autoHide className="mt-3 flex-1 min-h-0">
            <div className="space-y-1 pr-2">
              {conversations.map((conversation) => (
                <button
                  key={conversation.id}
                  type="button"
                  onClick={() => handleSelectConversation(conversation.id)}
                  className={`flex w-full items-center gap-2 rounded-lg px-3 py-2 text-left text-sm transition-colors ${
                    conversation.id === activeConversationId
                      ? 'bg-blue-50 text-blue-700 dark:bg-blue-900/40 dark:text-blue-200'
                      : 'text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-gray-700'
                  }`}
                >
                  <FaComment className="shrink-0" />
                  <span className="truncate">{conversation.title}</span>
                  <span
                    role="button"
                    tabIndex={0}
                    aria-label={`${conversation.title} sohbetini sil`}
                    title="Sohbeti sil"
                    onClick={(event) => {
                      event.stopPropagation()
                      handleDeleteConversation(conversation.id)
                    }}
                    onKeyDown={(event) => {
                      if (event.key === 'Enter' || event.key === ' ') {
                        event.preventDefault()
                        event.stopPropagation()
                        handleDeleteConversation(conversation.id)
                      }
                    }}
                    className="ml-auto shrink-0 rounded p-1 text-gray-400 hover:bg-red-100 hover:text-red-600 dark:text-gray-500 dark:hover:bg-red-900/40 dark:hover:text-red-300"
                  >
                    <FaTrash className="text-xs" />
                  </span>
                </button>
              ))}
            </div>
          </ScrollBar>
        </aside>

        <div className="min-w-0 flex flex-1 flex-col">
          <div className="mb-2 flex shrink-0 gap-2 lg:hidden">
            <Button
              className="flex-1"
              size="sm"
              icon={<FaPlus />}
              onClick={handleNewConversation}
              disabled={loading}
            >
              {translate('::App.Platform.NewChat')}
            </Button>
            <Button
              className="flex-1"
              size="sm"
              icon={<FaComment />}
              onClick={() => setIsConversationDrawerOpen(true)}
            >
              {translate('::App.Platform.Chats')}
            </Button>
          </div>
          <ScrollBar
            autoHide
            autoHideTimeout={700}
            autoHideDuration={200}
            hideTracksWhenNotNeeded
            className="flex-1 min-h-0 min-w-0"
            renderView={({ style, ...props }) => (
              <div {...props} style={{ ...style, overflowX: 'hidden' }} />
            )}
            renderThumbVertical={({ style, ...props }) => (
              <div
                {...props}
                className="rounded-full bg-gray-300/80 dark:bg-gray-600/80"
                style={{ ...style, width: 6, right: 3 }}
              />
            )}
          >
            <div className="p-4 space-y-4">
              {messages.length === 0 && (
                <div className="text-center text-gray-500 dark:text-gray-400 mt-8">
                  <FaRobot className="w-12 h-12 mx-auto mb-4 text-gray-400 dark:text-gray-500" />
                  <p className="mt-2">{translate('::AI.Welcome')}</p>
                  <p className="text-lg font-medium">{translate('::AI.Name')}</p>
                </div>
              )}

              {messages.map((msg, idx) => (
                <div
                  key={idx}
                  className={`flex items-start gap-2.5 ${msg.role === 'user' ? 'flex-row-reverse' : ''}`}
                >
                  <div
                    className={`w-8 h-8 rounded-full flex items-center justify-center ${msg.role === 'user' ? 'bg-blue-500' : 'bg-gray-600'}`}
                  >
                    {msg.role === 'user' ? (
                      <Avatar size={32} shape="circle" src={avatar} alt="avatar" />
                    ) : (
                      <FaRobot className="w-5 h-5 text-white" />
                    )}
                  </div>
                  <div
                    className={`max-w-[80%] min-w-0 rounded-lg p-2 ${msg.role === 'user' ? 'bg-blue-500 text-white' : 'bg-white text-gray-800 dark:bg-gray-800 dark:text-gray-100'}`}
                  >
                    <div className="flex flex-col gap-1">
                      {renderMessageContent(msg)}
                      {msg.createdAt && (
                        <div
                          className={`text-[11px] leading-none ${msg.role === 'user' ? 'text-white/80 text-right' : 'text-gray-500 dark:text-gray-400 text-right'}`}
                        >
                          {dayjs(msg.createdAt).format('DD.MM.YYYY HH:mm')}
                        </div>
                      )}
                    </div>
                  </div>
                </div>
              ))}

              {loading && (
                <div className="flex items-center justify-center gap-2 text-gray-500 dark:text-gray-400">
                  <div className="animate-spin rounded-full h-4 w-4 border-2 border-gray-500 dark:border-gray-400 border-t-transparent" />
                  {translate('::AI.WaitAnswer')}
                </div>
              )}

              <div ref={bottomRef}></div>
            </div>
          </ScrollBar>

          <form onSubmit={handleSubmit} className="relative w-full mx-auto px-4">
            <div className="relative w-full bg-[#2a2a2a] text-white rounded-3xl px-4 pt-4 pb-10 shadow-md">
              <textarea
                ref={inputRef}
                value={input}
                autoFocus
                onChange={(e) => setInput(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === 'Enter' && !e.shiftKey) {
                    e.preventDefault()
                    handleSubmit(e)
                  }
                }}
                placeholder={translate('::AI.Asking')}
                rows={2}
                className="w-full resize-none bg-transparent border-none outline-none text-base placeholder-gray-400"
              />

              <div className="absolute bottom-1 left-2 flex items-center gap-2 text-sm">
                <Dropdown
                  placement="top-start"
                  title={
                    bot.find((item) => item.id === selectedBot)?.name ||
                    translate('::AI.SelectModel')
                  }
                >
                  {bot
                    .filter((item) => !!item.id)
                    .map((item) => (
                      <Dropdown.Item key={item.id!} eventKey={item.id!} onSelect={onBotItemClick}>
                        {item.name}
                      </Dropdown.Item>
                    ))}
                </Dropdown>
              </div>

              <div className="absolute bottom-2 right-3 flex items-center gap-2">
                {/* <button
                type="button"
                aria-label="Mic"
                className="rounded-full h-8 w-8 flex items-center justify-center text-gray-400 hover:text-white"
              >
                🎤
              </button> */}
                <Button size="sm" variant="plain" type="submit" disabled={loading}>
                  <FaPaperPlane />
                </Button>
              </div>
            </div>
          </form>
        </div>
      </div>
    </Container>
  )
}

export default Assistant
