/**
 * Unit tests for chatStore.restoreBoardStateFromMessages (P2 #11).
 *
 * Locks in the reload behavior: after the client restarts, selecting a
 * private board meeting conversation must rebuild BoardState from the
 * persisted `board_started` message so the status view shows the
 * topic, expert list, and round counter — and sets `status` to
 * "completed" when a `board_conclusion` message is also present.
 *
 * Without this, users see "0 专家" and an empty topic every time they
 * reload the page.
 */

import { describe, expect, it } from 'vitest'
import { restoreBoardStateFromMessages } from '@/stores/chatStore'
import type { IChatMessage } from '@/api/types'

function boardStartedMsg(round: number = 0): IChatMessage {
  return {
    id: 'msg-start',
    role: 'assistant',
    content: '私董会开始：AI 未来',
    timestamp: '2026-07-01T10:00:00Z',
    status: 'completed',
    message_type: 'board_started',
    board_started: {
      team_id: 'team-1',
      topic: 'AI 未来',
      max_rounds: 5,
      experts: [
        {
          name: 'Alice',
          avatar: 'F',
          color: '#7a5af8',
          is_moderator: true,
          persona: '主持人',
        },
        {
          name: 'Bob',
          avatar: 'P',
          color: '#22c55e',
          is_moderator: false,
          persona: '工程师',
        },
      ],
    },
    board_round: round,
  }
}

function speechMsg(name: string, round: number): IChatMessage {
  return {
    id: `msg-speech-${name}-${round}`,
    role: 'assistant',
    content: `${name} 的第 ${round} 轮发言`,
    timestamp: '2026-07-01T10:00:01Z',
    status: 'completed',
    message_type: 'board_speech',
    expert_name: name,
    board_round: round,
  }
}

function conclusionMsg(totalRounds: number): IChatMessage {
  return {
    id: 'msg-conclusion',
    role: 'assistant',
    content: '私董会已结束',
    timestamp: '2026-07-01T10:05:00Z',
    status: 'completed',
    message_type: 'board_conclusion',
    board_conclusion: {
      summary: '总结',
      decision_advice: '建议',
      total_rounds: totalRounds,
      consensus_points: [],
      dissent_points: [],
    },
    board_round: totalRounds,
  }
}

describe('restoreBoardStateFromMessages', () => {
  it('returns null when no board_started message exists', () => {
    const messages: IChatMessage[] = [
      {
        id: 'm1',
        role: 'user',
        content: 'hello',
        timestamp: '2026-07-01T10:00:00Z',
      },
    ]
    expect(restoreBoardStateFromMessages(messages)).toBeNull()
  })

  it('rebuilds experts and topic from board_started', () => {
    const state = restoreBoardStateFromMessages([boardStartedMsg()])
    expect(state).not.toBeNull()
    expect(state?.topic).toBe('AI 未来')
    expect(state?.max_rounds).toBe(5)
    expect(state?.experts).toHaveLength(2)
    expect(state?.experts[0].name).toBe('Alice')
    expect(state?.experts[0].is_moderator).toBe(true)
    expect(state?.experts[1].name).toBe('Bob')
  })

  it('falls back to expert identity palette when color is missing', () => {
    const msg = boardStartedMsg()
    msg.board_started!.experts = [
      {
        name: 'Stranger',
        avatar: '',
        color: '',
        is_moderator: false,
        persona: '',
      },
    ]
    const state = restoreBoardStateFromMessages([msg])
    expect(state?.experts[0].avatar).not.toBe('')
    expect(state?.experts[0].color).toMatch(/^#[0-9a-fA-F]{3,8}$/)
  })

  it('keeps status="discussing" when no conclusion message present', () => {
    const messages = [
      boardStartedMsg(),
      speechMsg('Alice', 1),
      speechMsg('Bob', 1),
    ]
    const state = restoreBoardStateFromMessages(messages)
    expect(state?.status).toBe('discussing')
  })

  it('marks status="completed" when board_conclusion message present', () => {
    const messages = [
      boardStartedMsg(),
      speechMsg('Alice', 1),
      speechMsg('Bob', 1),
      speechMsg('Alice', 2),
      conclusionMsg(2),
    ]
    const state = restoreBoardStateFromMessages(messages)
    expect(state?.status).toBe('completed')
  })

  it('computes current_round from the latest speech/summary/conclusion', () => {
    const messages = [
      boardStartedMsg(),
      speechMsg('Alice', 1),
      speechMsg('Bob', 1),
      speechMsg('Alice', 3),
    ]
    const state = restoreBoardStateFromMessages(messages)
    expect(state?.current_round).toBe(3)
  })

  it('ignores non-board messages when computing current_round', () => {
    const messages: IChatMessage[] = [
      boardStartedMsg(),
      speechMsg('Alice', 2),
      {
        id: 'm-rand',
        role: 'assistant',
        content: 'not board',
        timestamp: '2026-07-01T10:00:00Z',
        message_type: 'chat',
        // board_round=99 — should be ignored because message_type is 'chat'
        board_round: 99,
      },
    ]
    const state = restoreBoardStateFromMessages(messages)
    expect(state?.current_round).toBe(2)
  })
})
