import { useEffect, useState } from 'react';
import { useChat } from '../context/ChatProvider';
import { INSUFFICIENT_BALANCE_NOTICE } from '../hooks/useTKMindChat';
import type { CapabilityMap, PortalUser } from '../types';
import { useNetworkStatus } from '../hooks/useNetworkStatus';
import { getSessionDisplayName } from '../utils/sessions';
import { openAvatarPicker } from '../utils/userAvatar';
import { BalanceRing } from './BalanceRing';
import { HistorySidebar } from './HistorySidebar';
import { TKMindAvatar } from './TKMindAvatar';
import { ChatPanel } from './ChatPanel';
import { WechatBindPrompt } from './WechatBindPrompt';
import { WechatAccountButton } from './WechatAccountButton';
import { ChatHeaderMoreMenu } from './ChatHeaderMoreMenu';
import { NotificationCenter } from './NotificationCenter';
import type { MindSpaceSaveCategory } from '../types';

export function ChatView({
  user,
  capabilities,
  grantedSkills,
  onLogout,
  onOpenSpace,
  onOpenPage,
  onOpenAdmin,
}: {
  user?: PortalUser | null;
  capabilities?: CapabilityMap;
  grantedSkills?: string[];
  onUserUpdate?: (user: PortalUser) => void;
  onLogout?: () => void;
  onOpenSpace?: (target?: { categoryCode?: MindSpaceSaveCategory; pageId?: string }) => void;
  onOpenPage?: (pageId: string) => void;
  onOpenAdmin?: () => void;
}) {
  const {
    session,
    sessions,
    sessionsLoading,
    messages,
    chatState,
    error,
    notice,
    pendingTool,
    memoryLoading,
    submit,
    stop,
    approveTool,
    newSession,
    rememberCurrentContext,
    refreshProjectMemory,
    switchSession,
    deleteSession,
    retryConnect,
    dismissNotice,
    onSidebarOpen,
    balanceCents,
    totalCreditCents,
    tokensUsed,
    subscription,
    openRecharge,
    openSubscribe,
    uploadChatImage,
  } = useChat();
  const online = useNetworkStatus();
  const [sidebarOpen, setSidebarOpen] = useState(false);

  useEffect(() => {
    if (sidebarOpen) {
      onSidebarOpen();
    }
  }, [sidebarOpen, onSidebarOpen]);

  const busy = chatState === 'streaming' || chatState === 'loading' || chatState === 'connecting';

  const handleSelectSession = (sessionId: string) => {
    void switchSession(sessionId);
    setSidebarOpen(false);
  };

  const handleNewSession = () => {
    void newSession();
    setSidebarOpen(false);
  };

  const sessionTitle = session
    ? getSessionDisplayName(session)
    : chatState === 'connecting'
      ? '新对话'
      : '连接中…';

  const moreMenuItems = [
    {
      id: 'new-session',
      label: '新会话',
      onClick: () => void handleNewSession(),
    },
    {
      id: 'remember',
      label: '记住本轮',
      onClick: () => void rememberCurrentContext(),
      disabled: busy || memoryLoading || messages.length === 0,
    },
    {
      id: 'refresh-memory',
      label: memoryLoading ? '同步中…' : '刷新记忆',
      onClick: () => void refreshProjectMemory(),
      disabled: busy || memoryLoading,
    },
    ...(onOpenAdmin
      ? [{ id: 'admin', label: '管理', onClick: () => onOpenAdmin() }]
      : []),
    ...(onLogout
      ? [{ id: 'logout', label: '登出', onClick: () => onLogout(), danger: true }]
      : []),
  ];

  return (
    <div className="app-shell">
      <HistorySidebar
        open={sidebarOpen}
        sessions={sessions}
        activeSessionId={session?.id}
        loading={sessionsLoading}
        onClose={() => setSidebarOpen(false)}
        onSelect={handleSelectSession}
        onNew={handleNewSession}
        onDelete={(sessionId) => void deleteSession(sessionId)}
      />

      <div className="app">
        <header className="header">
          <div className="header-left">
            <button
              type="button"
              className="header-menu-btn"
              aria-label="展开历史对话"
              onClick={() => setSidebarOpen(true)}
            >
              ☰
            </button>
            <TKMindAvatar size="sm" className="header-brand-avatar" />
            <div>
              <div className="header-title">{user?.displayName ?? 'TKMind'}</div>
              <div className="header-sub">{sessionTitle}</div>
            </div>
          </div>
          <div className="header-actions header-actions-desktop">
            {typeof balanceCents === 'number' && (
              <BalanceRing
                balanceCents={balanceCents}
                totalCreditCents={totalCreditCents}
                tokensUsed={tokensUsed}
                subscription={subscription}
                onRecharge={openRecharge}
                onSubscribe={openSubscribe}
              />
            )}
            <NotificationCenter onOpenRecharge={() => openRecharge(false)} />
            {onOpenAdmin && (
              <button type="button" className="ghost-btn" onClick={onOpenAdmin}>
                管理
              </button>
            )}
            {onOpenSpace && (
              <button type="button" className="ghost-btn" onClick={() => onOpenSpace?.()}>
                我的空间
              </button>
            )}
            <button
              type="button"
              className="ghost-btn"
              disabled={busy || memoryLoading || messages.length === 0}
              onClick={() => void rememberCurrentContext()}
              title="把最近几条对话保存到 harness 项目知识库"
            >
              记住本轮
            </button>
            <button
              type="button"
              className="ghost-btn"
              disabled={busy || memoryLoading}
              onClick={() => void refreshProjectMemory()}
              title="从 harness 和项目文件重新加载长期记忆"
            >
              {memoryLoading ? '同步中…' : '刷新记忆'}
            </button>
            <button type="button" className="ghost-btn" onClick={() => void handleNewSession()}>
              新会话
            </button>
            {user && <WechatAccountButton returnTo={window.location.pathname} />}
            {onLogout && (
              <button type="button" className="ghost-btn logout-btn" onClick={onLogout}>
                登出
              </button>
            )}
          </div>

          <div className="header-actions header-actions-mobile">
            {typeof balanceCents === 'number' && (
              <BalanceRing
                balanceCents={balanceCents}
                totalCreditCents={totalCreditCents}
                tokensUsed={tokensUsed}
                subscription={subscription}
                onRecharge={openRecharge}
                onSubscribe={openSubscribe}
              />
            )}
            <NotificationCenter onOpenRecharge={() => openRecharge(false)} />
            {onOpenSpace && (
              <button
                type="button"
                className="header-icon-btn"
                aria-label="我的空间"
                title="我的空间"
                onClick={() => onOpenSpace?.()}
              >
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true">
                  <path
                    d="M4 8.5V19a1 1 0 001 1h14a1 1 0 001-1V8.5M4 8.5l8-4.5 8 4.5M4 8.5h16M9 21v-6h6v6"
                    stroke="currentColor"
                    strokeWidth="1.75"
                    strokeLinecap="round"
                    strokeLinejoin="round"
                  />
                </svg>
              </button>
            )}
            <ChatHeaderMoreMenu
              items={moreMenuItems}
              returnTo={window.location.pathname}
              showWechat={Boolean(user)}
            />
          </div>
        </header>

        {!online && (
          <div className="banner banner-offline">网络已断开，请检查连接后重试</div>
        )}

        {user && <WechatBindPrompt returnTo={window.location.pathname} />}

        {typeof balanceCents === 'number' && balanceCents <= 0 && (
          <div className="banner banner-error">
            <span>余额不足，请充值后继续使用</span>
            <button type="button" className="banner-action" onClick={() => openRecharge(false)}>
              去充值
            </button>
          </div>
        )}
        {typeof balanceCents === 'number' && balanceCents > 0 && balanceCents <= 100 && (
          <div className="banner banner-warning">
            <span>余额较低（¥{(balanceCents / 100).toFixed(2)}），建议提前充值</span>
            <button type="button" className="banner-action" onClick={() => openRecharge(false)}>
              去充值
            </button>
          </div>
        )}

        {notice && (
          <div className={`banner${notice === INSUFFICIENT_BALANCE_NOTICE ? ' banner-warning' : ' banner-info'}`}>
            <span style={{ whiteSpace: 'pre-line' }}>{notice}</span>
            {notice === INSUFFICIENT_BALANCE_NOTICE ? (
              <>
                <button type="button" className="banner-action" onClick={() => openRecharge(false)}>
                  去充值
                </button>
                <button type="button" className="banner-dismiss" onClick={dismissNotice}>
                  知道了
                </button>
              </>
            ) : (
              <button type="button" className="banner-dismiss" onClick={dismissNotice}>
                知道了
              </button>
            )}
          </div>
        )}

        {error && (
          <div className="banner banner-error">
            <span>{error}</span>
            <button type="button" className="banner-action" onClick={() => void retryConnect()}>
              重试
            </button>
          </div>
        )}

        <ChatPanel
          variant="full"
          user={user}
          messages={messages}
          chatState={chatState}
          pendingTool={pendingTool}
          session={session}
          capabilities={capabilities}
          grantedSkills={grantedSkills}
          onSubmit={(text, imageUrls) => void submit(text, undefined, imageUrls)}
          onUploadImage={uploadChatImage}
          onStop={stop}
          onApproveTool={approveTool}
          onPageSaved={(result) => {
            if (result.kind === 'page' && result.pageId) {
              onOpenPage?.(result.pageId);
              return;
            }
            onOpenSpace?.({ categoryCode: result.categoryCode });
          }}
        />
      </div>
    </div>
  );
}
