class BoardsController < ApplicationController
  include BoardAccessible

  before_action :require_login
  before_action :set_game
  before_action :set_board, only: [ :show, :toggle_public ]

  def index
    # 参加中の掲示板（共通掲示板含む）を取得
    # ゲーム終了後は履歴モードとして、過去に参加していた掲示板もすべて表示
    @current_participant = @game.participants.find_by(user: current_user)

    # マップ表示用：各国がどの掲示板（交渉）を持っているかのデータを作成
    # { "FRANCE" => ["GERMANY", "ENGLAND"], ... } のような形式でビューに渡す
    @diplomacy_matrix = build_diplomacy_matrix

    if @game.status == "finished"
      # 履歴モード：かつて参加していた掲示板をすべて表示
      @boards = @game.boards.includes(:participants, :board_posts, :board_memberships)
                            .select { |b| b.member?(@current_participant) || b.global? }
                            .sort_by { |b| [ b.global? ? 0 : 1, b.created_at ] }
    else
      return redirect_to game_path(@game), alert: "参加者ではないためアクセスできません" unless @current_participant

      # 進行中：参加中の掲示板のみ（eager load で N+1 防止）
      @boards = @current_participant.boards.includes(:participants, :board_posts, :board_memberships).order(created_at: :desc)
      # 共通掲示板のフォールバック
      global_board = @game.boards.global.first
      if global_board && !@boards.include?(global_board)
        @boards = [ global_board ] + @boards
      end
      @boards = @boards.sort_by { |b| b.global? ? 0 : 1 }
    end
  end

  def show
    @current_participant = @game.participants.find_by(user: current_user)

    # アクセス制御
    access_allowed = false

    if @board.global?
      # 共通掲示板はゲーム参加者なら誰でもアクセス可能
      # 未読管理のためにメンバーシップがない場合は作成する
      access_allowed = true
      unless @board.board_memberships.exists?(participant: @current_participant)
        @board.board_memberships.create(participant: @current_participant, joined_at: Time.current)
      end
    elsif @board.member?(@current_participant)
      access_allowed = true
    elsif @game.status == "finished"
      # ゲーム終了後は、元メンバーならアクセス可能（共通掲示板は上記でカバー済み）
      is_past_member = @board.board_memberships.exists?(participant: @current_participant)
      access_allowed = is_past_member
    elsif @board.is_public?
      # 公開掲示板は誰でも閲覧可能
      access_allowed = true
    end

    unless access_allowed
      return redirect_to game_boards_path(@game), alert: "権限がありません"
    end

    # 既読更新
    if @current_participant && @board.active_memberships.exists?(participant: @current_participant)
      last_post = @board.board_posts.last
      if last_post
        membership = @board.board_memberships.find_by(participant: @current_participant)
        membership.mark_read!(last_post.id)
      end
    end

    @posts = @board.board_posts.includes(:participant).order(created_at: :desc)
    @proposals = @board.board_proposals.includes(:proposer).order(created_at: :desc)
    @new_post = BoardPost.new
    @new_proposal = BoardProposal.new
    @active_members = @board.active_memberships.includes(:participant).map(&:participant)

    # メンバー追加用：招待可能なプレイヤー一覧
    if @board.negotiation? && !@board.history_mode?
      existing_member_ids = @board.board_memberships.where(left_at: nil).pluck(:participant_id)
      @candidates = @game.participants.where.not(id: existing_member_ids).where.not(power: nil)
    end
  end

  def new
    @board = Board.new(board_type: "negotiation")
    @current_participant = @game.participants.find_by(user: current_user)
    # 自分以外の参加者一覧
    @participants = @game.participants.where.not(id: @current_participant.id).where.not(power: nil)
  end

  def create
    @current_participant = @game.participants.find_by(user: current_user)

    # トランザクションで掲示板作成とメンバー追加を一括実行
    ActiveRecord::Base.transaction do
      @board = @game.boards.new(board_params)
      @board.board_type = "negotiation"
      @board.created_by_participant_id = @current_participant.id

      if @board.save
        # 作成者をメンバーに追加
        @board.board_memberships.create!(participant: @current_participant, joined_at: Time.current)

        # 招待されたメンバーを追加
        if params[:invited_participant_ids].present?
          params[:invited_participant_ids].each do |pid|
            @board.board_memberships.create!(participant_id: pid, joined_at: Time.current)
          end
        end

        redirect_to game_board_path(@game, @board), notice: "交渉用掲示板を作成しました"
      else
        @participants = @game.participants.where.not(id: @current_participant.id).where.not(power: nil)
        render :new, status: :unprocessable_entity
      end
    end
  rescue ActiveRecord::RecordInvalid
    @participants = @game.participants.where.not(id: @current_participant.id).where.not(power: nil)
    render :new, status: :unprocessable_entity
  end

  def toggle_public
    # 公開宣言機能（追加提案）
    @current_participant = @game.participants.find_by(user: current_user)
    unless @board.member?(@current_participant)
      return redirect_to game_board_path(@game, @board), alert: "権限がありません"
    end

    @board.update(is_public: !@board.is_public)
    status = @board.is_public ? "公開" : "非公開"
    redirect_to game_board_path(@game, @board), notice: "掲示板を#{status}に設定しました"
  end

  private

  def board_params
    params.fetch(:board, {}).permit(:is_public)
  end

  def build_diplomacy_matrix
    powers = @game.participants.where.not(power: nil).pluck(:power)
    matrix = {}
    powers.each { |p| matrix[p] = [] }

    # 自分が参加している掲示板・公開された掲示板の関係を表示
    visible_boards = @game.boards.negotiation.includes(:participants, :board_memberships)

    visible_boards.each do |board|
      # アクセス権チェック（簡易）
      is_member = board.board_memberships.exists?(participant: @current_participant, left_at: nil)
      next unless is_member || board.is_public || @game.status == "finished"

      # メンバー間のリンクを作成
      members = board.participants.pluck(:power)
      members.each do |p1|
        members.each do |p2|
          next if p1 == p2
          matrix[p1] ||= []
          matrix[p1] << p2 unless matrix[p1].include?(p2)
        end
      end
    end

    matrix
  end
end
