/*
 *  Sidebar.tsx
 *  Zyquo Cloud Web
 *
 *  Author: Simon-Pierre Boucher
 *  Mail: contact@spboucher.ai
 *
 *  Conversation sidebar: wordmark, search (⌘F), New Chat, grouped rows
 *  (Pinned / Today / Yesterday / Previous 7 Days / Older), footer with
 *  Settings + usage summary. Collapses to a drawer on phones.
 */

import { useMemo, useRef } from 'react'
import { useStore } from '../state/store'
import { matchesSearch } from '../storage/conversations'
import type { Conversation } from '../types'
import ZyquoGlyph from './ZyquoGlyph'
import { IconGear, IconPin, IconPlus, IconSearch, IconTrash } from './icons'

const GROUP_ORDER = ['Pinned', 'Today', 'Yesterday', 'Previous 7 Days', 'Older'] as const

function groupFor(conversation: Conversation, now: Date): (typeof GROUP_ORDER)[number] {
  if (conversation.pinned) return 'Pinned'
  const updated = new Date(conversation.updatedAt)
  const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime()
  if (updated.getTime() >= startOfToday) return 'Today'
  if (updated.getTime() >= startOfToday - 86_400_000) return 'Yesterday'
  if (updated.getTime() >= startOfToday - 7 * 86_400_000) return 'Previous 7 Days'
  return 'Older'
}

function relativeTime(timestamp: number): string {
  const delta = Date.now() - timestamp
  const minutes = Math.floor(delta / 60_000)
  if (minutes < 1) return 'now'
  if (minutes < 60) return `${minutes}m`
  const hours = Math.floor(minutes / 60)
  if (hours < 24) return `${hours}h`
  const days = Math.floor(hours / 24)
  if (days < 7) return `${days}d`
  return new Date(timestamp).toLocaleDateString()
}

export default function Sidebar() {
  const conversations = useStore((s) => s.conversations)
  const selectedID = useStore((s) => s.selectedID)
  const searchText = useStore((s) => s.searchText)
  const setSearchText = useStore((s) => s.setSearchText)
  const select = useStore((s) => s.select)
  const newConversation = useStore((s) => s.newConversation)
  const removeConversation = useStore((s) => s.removeConversation)
  const updateConversation = useStore((s) => s.updateConversation)
  const openSettings = useStore((s) => s.openSettings)
  const sidebarOpen = useStore((s) => s.sidebarOpen)
  const searchRef = useRef<HTMLInputElement>(null)

  const groups = useMemo(() => {
    const now = new Date()
    const filtered = conversations.filter((c) => matchesSearch(c, searchText))
    const byGroup = new Map<string, Conversation[]>()
    for (const conversation of filtered) {
      const group = groupFor(conversation, now)
      const list = byGroup.get(group) ?? []
      list.push(conversation)
      byGroup.set(group, list)
    }
    return GROUP_ORDER.filter((g) => byGroup.has(g)).map((g) => ({
      name: g,
      items: byGroup.get(g) ?? [],
    }))
  }, [conversations, searchText])

  const usage = useMemo(() => {
    let tokens = 0
    let cost = 0
    for (const conversation of conversations) {
      for (const message of conversation.messages) {
        tokens += (message.usage?.inputTokens ?? 0) + (message.usage?.outputTokens ?? 0)
        cost += message.estimatedCost ?? 0
      }
    }
    return { tokens, cost }
  }, [conversations])

  return (
    <aside className={`sidebar${sidebarOpen ? ' open' : ''}`}>
      <div className="sidebar-wordmark">
        <ZyquoGlyph size={20} />
        <span>Zyquo Cloud</span>
      </div>
      <div className="sidebar-search">
        <IconSearch />
        <input
          ref={searchRef}
          data-search-input
          placeholder="Search"
          value={searchText}
          onChange={(e) => setSearchText(e.target.value)}
        />
      </div>
      <button className="new-chat-button" onClick={() => newConversation()}>
        <IconPlus size={12} /> New Chat
      </button>
      <div className="conversation-list">
        {groups.map((group) => (
          <div key={group.name}>
            <div className="conversation-group-header">{group.name}</div>
            {group.items.map((conversation) => (
              <div
                key={conversation.id}
                role="button"
                tabIndex={0}
                className={`conversation-row${conversation.id === selectedID ? ' selected' : ''}`}
                onClick={() => select(conversation.id)}
                onKeyDown={(e) => e.key === 'Enter' && select(conversation.id)}
              >
                <div className="conversation-row-main">
                  <div className="conversation-row-title">{conversation.title}</div>
                  <div className="conversation-row-sub">
                    {conversation.modelID} · {relativeTime(conversation.updatedAt)}
                  </div>
                </div>
                {conversation.pinned && (
                  <span className="pin-indicator">
                    <IconPin size={9} />
                  </span>
                )}
                <span className="conversation-row-actions">
                  <button
                    className="icon-button"
                    title={conversation.pinned ? 'Unpin' : 'Pin'}
                    onClick={(e) => {
                      e.stopPropagation()
                      updateConversation(conversation.id, { pinned: !conversation.pinned })
                    }}
                  >
                    <IconPin size={10} />
                  </button>
                  <button
                    className="icon-button danger"
                    title="Delete"
                    onClick={(e) => {
                      e.stopPropagation()
                      removeConversation(conversation.id)
                    }}
                  >
                    <IconTrash size={10} />
                  </button>
                </span>
              </div>
            ))}
          </div>
        ))}
        {groups.length === 0 && (
          <div className="panel-empty">
            {searchText ? 'No conversations match.' : 'No conversations yet.'}
          </div>
        )}
      </div>
      <div className="sidebar-footer">
        <button className="icon-button" title="Settings (⌘,)" onClick={() => openSettings()}>
          <IconGear />
        </button>
        {usage.tokens > 0 && (
          <span>
            {usage.tokens >= 1_000_000
              ? `${(usage.tokens / 1_000_000).toFixed(1)}M tok`
              : `${(usage.tokens / 1_000).toFixed(1)}K tok`}
            {usage.cost >= 0.01
              ? ` · ~$${usage.cost.toFixed(2)}`
              : usage.cost > 0
                ? ' · <$0.01'
                : ''}
          </span>
        )}
      </div>
    </aside>
  )
}
