// Seed data for the mock transport. Enough to exercise the playable slice locally
// (pnpm start) with no backend: a profile, one active mid-game whose board already
// has tiles, and two finished games. Coordinates are 0-indexed (centre 7,7). Words do
// not need to be strictly legal here — this is a visual/interaction fixture; real
// legality and scoring come from the backend.

import type {
  AccountRef,
  ChatMessage,
  GameView,
  Invitation,
  MoveRecord,
  Profile,
  Seat,
  Session,
  Stats,
} from '../model';

export const ME = 'me';

export const SESSION: Session = {
  token: 'mock-token',
  userId: ME,
  isGuest: true,
  displayName: 'You',
};

export const PROFILE: Profile = {
  userId: ME,
  displayName: 'You',
  preferredLanguage: 'en',
  timeZone: 'UTC',
  awayStart: '00:00',
  awayEnd: '07:00',
  hintBalance: 3,
  blockChat: false,
  blockFriendRequests: false,
  isGuest: false,
  notificationsInAppOnly: true,
  // Every variant enabled, so the mock-driven UI offers the full New Game picker.
  variantPreferences: ['erudit_ru', 'scrabble_ru', 'scrabble_en'],
  email: 'you@example.com',
  telegramLinked: false,
  vkLinked: false,
  // Every variant's current dictionary version, as the backend advertises it on the profile —
  // the offline preloader targets `variant@version`.
  dictVersions: { erudit_ru: 'v1.3.0', scrabble_ru: 'v1.3.0', scrabble_en: 'v1.3.0' },
  // Post-move interstitial config (short cooldowns so the mock stub is exercisable); not suppressed.
  ads: { cooldownGlobalS: 300, cooldownVsAiS: 1800, cooldownHintS: 60, suppressed: false },
  // The durable tier's per-kind active-game caps (the seeded defaults); the e2e lowers them through
  // window.__mock.setGameLimits to exercise the New-Game lock.
  gameLimits: { vsAi: 10, random: 10, friends: 10 },
};

// Seed social/account data for the mock (pnpm start + Playwright). The mock profile
// is a durable account so the social surfaces (friends, stats, history) are reachable.
// Ann is the active game's opponent but deliberately not a friend, so the in-game
// "add to friends" flow is demonstrable; Kaya (a finished-game opponent) is the friend.
export const MOCK_FRIENDS: AccountRef[] = [{ accountId: 'kaya', displayName: 'Kaya' }];

export const MOCK_INCOMING: AccountRef[] = [{ accountId: 'rick', displayName: 'Rick' }];

export const MOCK_STATS: Stats = {
  wins: 7,
  losses: 4,
  draws: 1,
  maxGamePoints: 421,
  maxWordPoints: 134,
  moves: 248, // plays across all games
  hintsUsed: 12, // -> hint share 12/248 = 4.8%
  // Letters are lower-cased as the backend emits them; the tile renderer upper-cases for
  // display. The 'd' in "wonderful" is a blank (value 0) to exercise wildcard rendering.
  // Erudit is absent on purpose, so the screen demonstrates skipping a not-yet-played variant.
  bestMoves: [
    {
      variant: 'scrabble_en',
      score: 134,
      word: [
        { letter: 'w', value: 4, blank: false },
        { letter: 'o', value: 1, blank: false },
        { letter: 'n', value: 1, blank: false },
        { letter: 'd', value: 0, blank: true },
        { letter: 'e', value: 1, blank: false },
        { letter: 'r', value: 1, blank: false },
        { letter: 'f', value: 4, blank: false },
        { letter: 'u', value: 1, blank: false },
        { letter: 'l', value: 1, blank: false },
      ],
    },
    {
      variant: 'scrabble_ru',
      score: 88,
      word: [
        { letter: 'с', value: 1, blank: false },
        { letter: 'ъ', value: 10, blank: false },
        { letter: 'ё', value: 4, blank: false },
        { letter: 'м', value: 2, blank: false },
        { letter: 'к', value: 2, blank: false },
        { letter: 'а', value: 1, blank: false },
      ],
    },
  ],
};

export function mockInvitations(): Invitation[] {
  return [
    {
      id: 'inv1',
      inviter: { accountId: 'kaya', displayName: 'Kaya' },
      invitees: [{ accountId: ME, displayName: 'You', seat: 1, response: 'pending' }],
      variant: 'scrabble_ru',
      turnTimeoutSecs: 86400,
      hintsAllowed: true,
      hintsPerPlayer: 1,
      multipleWordsPerTurn: false,
            dropoutTiles: 'remove',
      status: 'pending',
      gameId: '',
      expiresAtUnix: Math.floor(Date.now() / 1000) + 7 * 86400,
    },
  ];
}

function seat(s: number, accountId: string, displayName: string, score: number, isWinner = false): Seat {
  return { seat: s, accountId, displayName, score, hintsUsed: 0, isWinner };
}

function play(
  player: number,
  dir: 'H' | 'V',
  tiles: Array<[number, number, string]>,
  words: string[],
  score: number,
  total: number,
): MoveRecord {
  const ts = tiles.map(([row, col, letter]) => ({ row, col, letter, blank: false }));
  return {
    player,
    action: 'play',
    dir,
    mainRow: ts[0]?.row ?? 7,
    mainCol: ts[0]?.col ?? 7,
    tiles: ts,
    words,
    count: words.length,
    score,
    total,
  };
}

export interface MockGame {
  view: GameView;
  moves: MoveRecord[];
  rack: string[];
  bagLen: number;
  hintsRemaining: number;
  chat: ChatMessage[];
}

// --- active game G1: scrabble_en, You (seat 0) vs Ann (seat 1), your turn ---

const G1_MOVES: MoveRecord[] = [
  play(0, 'H', [
    [7, 5, 'H'],
    [7, 6, 'E'],
    [7, 7, 'L'],
    [7, 8, 'L'],
    [7, 9, 'O'],
  ], ['HELLO'], 16, 16),
  play(1, 'V', [
    [6, 9, 'W'],
    [8, 9, 'R'],
    [9, 9, 'L'],
    [10, 9, 'D'],
  ], ['WORLD'], 9, 9),
  play(0, 'H', [
    [8, 10, 'A'],
    [8, 11, 'T'],
  ], ['RAT'], 3, 19),
  play(1, 'V', [
    [9, 10, 'N'],
    [10, 10, 'D'],
  ], ['AND'], 4, 13),
];

function activeGame(): MockGame {
  return {
    view: {
      id: 'g1',
      variant: 'scrabble_en',
      dictVersion: 'v1',
      vsAi: false,
      unreadChat: false,
      unreadMessages: false,
      kind: 2,
      status: 'active',
      players: 2,
      toMove: 0,
      turnTimeoutSecs: 86400,
      multipleWordsPerTurn: true,
      noRepeatWords: false,
      moveCount: G1_MOVES.length,
      endReason: '',
      lastActivityUnix: Math.floor(Date.now() / 1000) - 7200,
      seats: [seat(0, ME, 'You', 19), seat(1, 'ann', 'Ann', 13)],
    },
    moves: G1_MOVES,
    rack: ['R', 'E', 'T', 'I', 'N', 'A', '?'],
    bagLen: 58,
    hintsRemaining: 1,
    chat: [
      {
        id: 'c1',
        gameId: 'g1',
        senderId: 'ann',
        kind: 'message',
        body: 'good luck!',
        createdAtUnix: Math.floor(Date.now() / 1000) - 3600,
      },
    ],
  };
}

// --- finished games ---

function finishedG2(): MockGame {
  return {
    view: {
      id: 'g2',
      variant: 'scrabble_en',
      dictVersion: 'v1',
      vsAi: false,
      unreadChat: false,
      unreadMessages: false,
      kind: 2,
      status: 'finished',
      players: 2,
      toMove: 0,
      turnTimeoutSecs: 86400,
      multipleWordsPerTurn: true,
      noRepeatWords: false,
      moveCount: 2,
      endReason: 'normal',
      lastActivityUnix: Math.floor(Date.now() / 1000) - 86400,
      seats: [seat(0, ME, 'You', 320, true), seat(1, 'kaya', 'Kaya', 281)],
    },
    moves: [
      play(0, 'H', [
        [7, 6, 'Q'],
        [7, 7, 'U'],
        [7, 8, 'I'],
        [7, 9, 'Z'],
      ], ['QUIZ'], 48, 48),
      play(1, 'V', [
        [6, 9, 'J'],
        [8, 9, 'A'],
        [9, 9, 'M'],
      ], ['JAZM'], 30, 30),
    ],
    rack: [],
    bagLen: 0,
    hintsRemaining: 0,
    chat: [],
  };
}

function finishedG3(): MockGame {
  return {
    view: {
      id: 'g3',
      variant: 'scrabble_ru',
      dictVersion: 'v1',
      vsAi: false,
      unreadChat: false,
      unreadMessages: false,
      kind: 2,
      status: 'finished',
      players: 2,
      toMove: 0,
      turnTimeoutSecs: 86400,
      multipleWordsPerTurn: false,
      noRepeatWords: false,
      moveCount: 1,
      endReason: 'resignation',
      lastActivityUnix: Math.floor(Date.now() / 1000) - 172800,
      seats: [seat(0, ME, 'You', 150), seat(1, 'rick', 'Rick', 212, true)],
    },
    moves: [
      play(0, 'H', [
        [7, 6, 'С'],
        [7, 7, 'Л'],
        [7, 8, 'О'],
        [7, 9, 'В'],
        [7, 10, 'О'],
      ], ['СЛОВО'], 12, 12),
    ],
    rack: [],
    bagLen: 0,
    hintsRemaining: 0,
    chat: [],
  };
}

export function seedGames(): Map<string, MockGame> {
  const m = new Map<string, MockGame>();
  for (const g of [activeGame(), finishedG2(), finishedG3()]) m.set(g.view.id, g);
  return m;
}
