import type {
  ChangeEvent,
  CSSProperties,
  DragEvent as ReactDragEvent,
  KeyboardEvent as ReactKeyboardEvent,
  PointerEvent as ReactPointerEvent,
  ReactNode,
  RefObject,
  UIEvent as ReactUIEvent
} from "react"
import type { ChatAttachment, ChatLaunchState, ProjectIntentSuggestion } from "@qjclaw/shared-types"
import type { ExpertGuideContent } from "../experts/ExpertsView"
import { ExpertEmptyState } from "../experts/ExpertsView"
import { ExpertPanelLead } from "../experts/ExpertPanelLead"
import type { ExpertVisualKey } from "../shell/ExpertTree"
import { BindEntry } from "./BindEntry"
import { ChatComposer } from "./ChatComposer"
import { ChatWorkspace } from "./ChatWorkspace"
import { ConversationStatusNotice, HomeIntentSuggestionNotice } from "./ConversationNotices"
import { MessageList, type ExpertKey, type MessageListMessage } from "./MessageList"
import type { MessageTraceState } from "./useMessageTraces"

type ViewMode = "chat" | "experts" | "tasks" | "automation" | "plugins" | "settings" | "knowledge"
type MessageReaction = "up" | "down"

interface HomeStarterPrompt {
  title: string
  description: string
  prompt: string
}

interface HomeShowcaseEmployee {
  visualKey: ExpertVisualKey
  title: string
  description: string
  prompt: string
}

interface ConversationWorkspaceStatusProps {
  panelActions: ReactNode
  showInlineStartupNotice: boolean
  chatLaunchState: ChatLaunchState
  startupCurtainStatus: string
}

interface ConversationWorkspaceEmptyStateProps {
  selectedSkillBadge: string
  selectedSkillIsDefault: boolean
  homeLeadIcon: ReactNode
  activeExpertName: string
  activeExpertKey: ExpertKey
  activeExpertVisualKey: ExpertVisualKey
  activeExpertGuide: ExpertGuideContent
  expertWorkspaceLogo: ReactNode
  homeIntentSuggestion: ProjectIntentSuggestion | null
  homeIntentDecisionPending: boolean
  homeIntentLabels: {
    title: string
    prefix: string
    suffix: string
    continue: string
    switchAction: string
  }
  showBindEntry: boolean
  bindEntry: {
    lobsterKeyDraft: string
    workspaceApiKeyConfigured: boolean
    saving: boolean
    bindingLabel: string
    onLobsterKeyChange: (value: string) => void
    onSave: () => void | Promise<void>
  }
  hasExpertProjects: boolean
  noExpertsLabel: string
  starterQuestionsHint: string
  homeEmptyTitle: string
  homeShowcaseEmployees: readonly HomeShowcaseEmployee[]
}

interface ConversationWorkspaceMessagesProps {
  messageListRef: RefObject<HTMLDivElement | null>
  messages: MessageListMessage[]
  showEmptyState: boolean
  messageTraces: Record<string, MessageTraceState>
  messageReactions: Record<string, MessageReaction | undefined>
  copiedToken: string
  sending: boolean
  messageLabels: {
    thinking: string
    traceTitle: string
    hideTrace: string
    traceCollapsed: string
  }
  copyIcon: ReactNode
  copiedIcon: ReactNode
  deleteIcon: ReactNode
  regenerateIcon: ReactNode
}

interface ConversationWorkspaceComposerProps {
  attachmentInputRef: RefObject<HTMLInputElement | null>
  skillMenuRef: RefObject<HTMLDivElement | null>
  prompt: string
  isBound: boolean
  isChannelSession: boolean
  canSend: boolean
  isComposerDragOver: boolean
  isComposerResizeActive: boolean
  composerShellStyle: CSSProperties
  attachmentAccept: string
  attachments: ChatAttachment[]
  composerPlaceholder: string
  sendButtonLabel: string
  skillMenuTitle: string
  defaultChatLabel: string
  defaultSkillId: string
  selectedSkillId: string
  selectedSkillName: string
  skills: Array<{ id: string; name: string; description: string }>
  skillMenuOpen: boolean
  attachmentIcon: ReactNode
  submitIcon: ReactNode
}

interface ConversationWorkspaceActionsProps {
  renderExpertIcon: (expertKey: ExpertVisualKey) => ReactNode
  renderIntentIcon: (projectId: string) => ReactNode
  onContinueHomeIntent: () => void | Promise<unknown>
  onSwitchHomeIntent: () => void | Promise<unknown>
  onStarterPrompt: (prompt: string) => void
  onExpertCardClick: (visualKey: string) => void
  renderThumbIcon: (direction: MessageReaction) => ReactNode
  renderMarkdownContent: (
    content: string,
    options: {
      messageId: string
      copiedToken: string
      onCopy: (token: string, text: string) => void | Promise<void>
    }
  ) => ReactNode[]
  buildDouyinVideoStatusCard: (message: MessageListMessage, expertKey: ExpertKey) => {
    title: string
    meta?: string
    hint?: string
  } | null
  formatMessageTimestamp: (value: string) => string
  onMessageListScroll: (event: ReactUIEvent<HTMLDivElement>) => void
  onCopyText: (token: string, text: string) => void | Promise<void>
  onDeleteMessage: (messageId: string) => void
  onTraceExpandedChange: (messageId: string, expanded: boolean) => void
  onRegenerateAssistantMessage: (messageId: string) => void | Promise<void>
  onToggleMessageReaction: (messageId: string, reaction: MessageReaction) => void
  onSubmit: () => void | Promise<void>
  onCancel: () => void | Promise<void>
  onPromptChange: (value: string) => void
  onTextareaKeyDown: (event: ReactKeyboardEvent<HTMLTextAreaElement>) => void | Promise<void>
  onAttachmentSelection: (event: ChangeEvent<HTMLInputElement>) => void
  onOpenAttachmentPicker: () => void
  onRemoveAttachment: (localPath: string) => void
  onToggleSkillMenu: () => void
  onClearSelectedSkill: () => void
  onChooseSkill: (skillId: string) => void
  onDragEnter: (event: ReactDragEvent<HTMLFormElement>) => void
  onDragOver: (event: ReactDragEvent<HTMLFormElement>) => void
  onDragLeave: (event: ReactDragEvent<HTMLFormElement>) => void
  onDrop: (event: ReactDragEvent<HTMLFormElement>) => void
  onResizePointerDown: (event: ReactPointerEvent<HTMLDivElement>) => void
  onResizePointerMove: (event: ReactPointerEvent<HTMLDivElement>) => void
  onResizePointerEnd: (event: ReactPointerEvent<HTMLDivElement>) => void
}

interface ConversationWorkspaceViewProps {
  viewMode: ViewMode
  workspaceRef: RefObject<HTMLDivElement | null>
  status: ConversationWorkspaceStatusProps
  emptyState: ConversationWorkspaceEmptyStateProps
  messages: ConversationWorkspaceMessagesProps
  composer: ConversationWorkspaceComposerProps
  actions: ConversationWorkspaceActionsProps
  activeRoleId?: string
  isStreaming?: boolean
}

export function ConversationWorkspaceView({
  viewMode,
  workspaceRef,
  status,
  emptyState,
  messages,
  composer,
  actions,
  activeRoleId,
  isStreaming
}: ConversationWorkspaceViewProps) {
  const homeMicrocopyStatus = emptyState.selectedSkillIsDefault ? "默认工作区" : "已切换"

  const panelLead = viewMode === "chat" ? (
    <div className="home-microcopy" aria-label={`工作区，${emptyState.selectedSkillBadge}`}>
      <span className="home-microcopy-icon-shell" aria-hidden="true">
        <span className="home-microcopy-icon">
          {emptyState.homeLeadIcon}
        </span>
        <span className="home-microcopy-icon-beam" />
      </span>
      <span className="home-microcopy-body">
        <strong className="home-microcopy-title">{emptyState.selectedSkillBadge}</strong>
      </span>
      <span className={"home-microcopy-status" + (emptyState.selectedSkillIsDefault ? " brand" : "")}>
        {homeMicrocopyStatus}
      </span>
    </div>
  ) : (
    <ExpertPanelLead
      activeExpertKey={emptyState.activeExpertKey}
      activeExpertName={emptyState.activeExpertName}
      activeExpertVisualKey={emptyState.activeExpertVisualKey}
      expertWorkspaceLogo={emptyState.expertWorkspaceLogo}
      renderExpertIcon={actions.renderExpertIcon}
    />
  )

  const activeEmptyState = viewMode === "experts" ? (
    <ExpertEmptyState
      activeExpertName={emptyState.activeExpertName}
      activeExpertKey={emptyState.activeExpertKey}
      activeExpertGuide={emptyState.activeExpertGuide}
      starterQuestionsHint={emptyState.starterQuestionsHint}
      onStarterPrompt={actions.onStarterPrompt}
      activeRoleId={activeRoleId}
      isStreaming={isStreaming}
    />
  ) : (
    <div className="empty-state home-empty-state">
      <div className="home-empty-copy">
        <strong className="home-empty-title">{emptyState.homeEmptyTitle}</strong>
      </div>
      <div className="home-showcase-grid" aria-label="数字员工展示">
        {emptyState.homeShowcaseEmployees.map((emp) => (
          <button
            key={emp.visualKey}
            type="button"
            className="home-showcase-card"
            data-visual={emp.visualKey}
            onClick={() => actions.onExpertCardClick(emp.visualKey)}
            aria-label={emp.title}
            title={emp.description}
          >
            <span className="home-showcase-icon" data-visual={emp.visualKey}>
              {actions.renderExpertIcon(emp.visualKey)}
            </span>
            <span className="home-showcase-name">{emp.title}</span>
          </button>
        ))}
      </div>
    </div>
  )

  const statusNotice = (
    <ConversationStatusNotice
      show={status.showInlineStartupNotice}
      chatLaunchState={status.chatLaunchState}
      status={status.startupCurtainStatus}
    />
  )

  const intentNotice = viewMode === "chat" ? (
    <HomeIntentSuggestionNotice
      suggestion={emptyState.homeIntentSuggestion}
      decisionPending={emptyState.homeIntentDecisionPending}
      labels={emptyState.homeIntentLabels}
      renderIcon={actions.renderIntentIcon}
      onContinue={actions.onContinueHomeIntent}
      onSwitch={actions.onSwitchHomeIntent}
    />
  ) : null

  const bodyContent = emptyState.showBindEntry
    ? (
        <BindEntry
          lobsterKeyDraft={emptyState.bindEntry.lobsterKeyDraft}
          workspaceApiKeyConfigured={emptyState.bindEntry.workspaceApiKeyConfigured}
          saving={emptyState.bindEntry.saving}
          bindingLabel={emptyState.bindEntry.bindingLabel}
          onLobsterKeyChange={emptyState.bindEntry.onLobsterKeyChange}
          onSave={emptyState.bindEntry.onSave}
        />
      )
    : viewMode === "experts" && !emptyState.hasExpertProjects
      ? <div className="empty-state">{emptyState.noExpertsLabel}</div>
      : (
          <MessageList
            messages={messages.messages}
            viewMode={viewMode}
            showBindEntry={emptyState.showBindEntry}
            showEmptyState={messages.showEmptyState}
            emptyState={activeEmptyState}
            messageListRef={messages.messageListRef}
            messageTraces={messages.messageTraces}
            messageReactions={messages.messageReactions}
            copiedToken={messages.copiedToken}
            sending={messages.sending}
            activeExpertKey={emptyState.activeExpertKey}
            labels={messages.messageLabels}
            copyIcon={messages.copyIcon}
            copiedIcon={messages.copiedIcon}
            deleteIcon={messages.deleteIcon}
            regenerateIcon={messages.regenerateIcon}
            renderThumbIcon={actions.renderThumbIcon}
            renderMarkdownContent={actions.renderMarkdownContent}
            buildDouyinVideoStatusCard={actions.buildDouyinVideoStatusCard}
            formatMessageTimestamp={actions.formatMessageTimestamp}
            onScroll={actions.onMessageListScroll}
            onCopyText={actions.onCopyText}
            onDeleteMessage={actions.onDeleteMessage}
            onTraceExpandedChange={actions.onTraceExpandedChange}
            onRegenerateAssistantMessage={actions.onRegenerateAssistantMessage}
            onToggleMessageReaction={actions.onToggleMessageReaction}
          />
        )

  const composerContent = (
    <ChatComposer
      prompt={composer.prompt}
      isBound={composer.isBound}
      isChannelSession={composer.isChannelSession}
      sending={messages.sending}
      canSend={composer.canSend}
      isDragOver={composer.isComposerDragOver}
      isResizeActive={composer.isComposerResizeActive}
      viewMode={viewMode}
      shellStyle={composer.composerShellStyle}
      attachmentInputRef={composer.attachmentInputRef}
      skillMenuRef={composer.skillMenuRef}
      attachmentAccept={composer.attachmentAccept}
      attachments={composer.attachments}
      placeholder={composer.composerPlaceholder}
      sendButtonLabel={composer.sendButtonLabel}
      skillMenuTitle={composer.skillMenuTitle}
      defaultChatLabel={composer.defaultChatLabel}
      defaultSkillId={composer.defaultSkillId}
      selectedSkillId={composer.selectedSkillId}
      selectedSkillName={composer.selectedSkillName}
      skills={composer.skills}
      skillMenuOpen={composer.skillMenuOpen}
      attachmentIcon={composer.attachmentIcon}
      submitIcon={composer.submitIcon}
      onSubmit={actions.onSubmit}
      onCancel={actions.onCancel}
      onPromptChange={actions.onPromptChange}
      onTextareaKeyDown={actions.onTextareaKeyDown}
      onAttachmentSelection={actions.onAttachmentSelection}
      onOpenAttachmentPicker={actions.onOpenAttachmentPicker}
      onRemoveAttachment={actions.onRemoveAttachment}
      onToggleSkillMenu={actions.onToggleSkillMenu}
      onClearSelectedSkill={actions.onClearSelectedSkill}
      onChooseSkill={actions.onChooseSkill}
      onDragEnter={actions.onDragEnter}
      onDragOver={actions.onDragOver}
      onDragLeave={actions.onDragLeave}
      onDrop={actions.onDrop}
      onResizePointerDown={actions.onResizePointerDown}
      onResizePointerMove={actions.onResizePointerMove}
      onResizePointerEnd={actions.onResizePointerEnd}
    />
  )

  return (
    <ChatWorkspace
      panelLead={panelLead}
      panelActions={status.panelActions}
      workspaceRef={workspaceRef}
      statusNotice={statusNotice}
      intentNotice={intentNotice}
      bodyContent={bodyContent}
      composerContent={composerContent}
    />
  )
}
