/**
 * ChatRoomScene.js
 * Chat room scene for in-game communication.
 * All messages are checked against content security before sending.
 * Muted users cannot send messages.
 */

const {
  SCREEN_WIDTH,
  SCREEN_HEIGHT,
  COLORS,
  SCENE,
} = require('../base/GameGlobal');
const { t } = require('../i18n/I18n');
const ContentSecurityManager = require('../managers/ContentSecurityManager');

// ============================================================
// Layout Constants
// ============================================================
const CENTER_X = SCREEN_WIDTH / 2;
const INPUT_HEIGHT = 36;
const SEND_BTN_WIDTH = 60;
const MAX_VISIBLE_MESSAGES = 50;
const MESSAGE_AREA_TOP = 50;
const MESSAGE_AREA_BOTTOM = SCREEN_HEIGHT - 60;

// ============================================================
// Chat Room Scene
// ============================================================
const ChatRoomScene = {
  // Chat state
  _messages: [],
  _inputText: '',
  _errorMessage: '',
  _isSending: false,
  _localViolation: false,
  _isMuted: false,
  _muteRemainingText: '',
  _scrollOffset: 0,

  // User info
  _openid: '',
  _nickname: '',

  // Touch rects
  _backBtnRect: null,
  _inputRect: null,
  _sendBtnRect: null,
  _reportTargetMsgIdx: -1,

  // Report overlay state
  _showReportOverlay: false,
  _reportContentId: '',
  _reportTargetUserId: '',
  _reportContentSummary: '',

  enter() {
    this._messages = [];
    this._inputText = '';
    this._errorMessage = '';
    this._isSending = false;
    this._localViolation = false;
    this._isMuted = false;
    this._muteRemainingText = '';
    this._scrollOffset = 0;
    this._showReportOverlay = false;

    // Load user info
    try {
      this._openid = wx.getStorageSync('player_openid') || '';
      const profile = wx.getStorageSync('player_profile');
      if (profile) {
        const parsed = JSON.parse(profile);
        this._nickname = parsed.nickname || '玩家';
      }
    } catch (e) {
      this._nickname = '玩家';
    }

    // Calculate layouts
    this._backBtnRect = { x: 10, y: 10, w: 60, h: 30 };
    this._inputRect = {
      x: 10,
      y: SCREEN_HEIGHT - INPUT_HEIGHT - 10,
      w: SCREEN_WIDTH - SEND_BTN_WIDTH - 30,
      h: INPUT_HEIGHT,
    };
    this._sendBtnRect = {
      x: SCREEN_WIDTH - SEND_BTN_WIDTH - 10,
      y: SCREEN_HEIGHT - INPUT_HEIGHT - 10,
      w: SEND_BTN_WIDTH,
      h: INPUT_HEIGHT,
    };

    // Check mute status
    this._checkMuteStatus();
  },

  exit() {
    wx.hideKeyboard();
  },

  update(dt) {},

  render(ctx) {
    // Background
    ctx.fillStyle = '#1a1a2e';
    ctx.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

    // Title bar
    ctx.fillStyle = 'rgba(0, 0, 0, 0.3)';
    ctx.fillRect(0, 0, SCREEN_WIDTH, 45);
    ctx.fillStyle = '#FFFFFF';
    ctx.font = 'bold 16px Arial';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(t('chat.title'), CENTER_X, 22);

    // Back button
    ctx.fillStyle = '#AAAAAA';
    ctx.font = '12px Arial';
    ctx.textAlign = 'left';
    ctx.fillText('← ' + t('common.back'), 15, 22);

    // Messages area
    this._renderMessages(ctx);

    // Input area
    this._renderInputArea(ctx);

    // Error message
    if (this._errorMessage) {
      ctx.fillStyle = '#FF4444';
      ctx.font = '11px Arial';
      ctx.textAlign = 'center';
      ctx.fillText(this._errorMessage, CENTER_X, SCREEN_HEIGHT - INPUT_HEIGHT - 25);
    }

    // Report overlay
    if (this._showReportOverlay) {
      this._renderReportOverlay(ctx);
    }
  },

  handleTouch(type, e) {
    if (type !== 'touchstart') return;
    const touch = e.touches[0];
    const x = touch.clientX;
    const y = touch.clientY;

    // Report overlay handling
    if (this._showReportOverlay) {
      this._handleReportOverlayTouch(x, y);
      return;
    }

    // Back button
    if (this._hitTest(x, y, this._backBtnRect)) {
      const sm = GameGlobal.sceneManager;
      sm.switchTo(SCENE.MENU);
      return;
    }

    // Input field - show keyboard
    if (this._hitTest(x, y, this._inputRect)) {
      if (this._isMuted) {
        this._errorMessage = `您已被禁言，剩余时间：${this._muteRemainingText}`;
        return;
      }
      this._showKeyboard();
      return;
    }

    // Send button
    if (this._hitTest(x, y, this._sendBtnRect)) {
      this._handleSend();
      return;
    }

    // Long press on message for reporting
    // (Simplified: double-tap to report for now)
  },

  // ============================================================
  // Message Sending
  // ============================================================

  _showKeyboard() {
    wx.showKeyboard({
      defaultValue: this._inputText,
      maxLength: 200,
      multiple: false,
      confirmHold: false,
      confirmType: 'send',
    });

    this._onKeyboardInput = (res) => {
      this._inputText = res.value;

      // Real-time local sensitive word check
      if (this._inputText) {
        const csm = GameGlobal.contentSecurityManager;
        if (csm && csm.isInitialized()) {
          const localCheck = csm.checkLocalText(this._inputText);
          if (localCheck.hasViolation) {
            this._localViolation = true;
            this._errorMessage = '内容包含违规信息，请修改';
          } else {
            this._localViolation = false;
            this._errorMessage = '';
          }
        }
      }
    };

    this._onKeyboardConfirm = () => {
      this._handleSend();
    };

    wx.onKeyboardInput(this._onKeyboardInput);
    wx.onKeyboardConfirm(this._onKeyboardConfirm);
  },

  _hideKeyboard() {
    if (this._onKeyboardInput) {
      wx.offKeyboardInput(this._onKeyboardInput);
      this._onKeyboardInput = null;
    }
    if (this._onKeyboardConfirm) {
      wx.offKeyboardConfirm(this._onKeyboardConfirm);
      this._onKeyboardConfirm = null;
    }
    wx.hideKeyboard();
  },

  async _handleSend() {
    if (this._isSending || this._localViolation) return;

    const csm = GameGlobal.contentSecurityManager;
    if (!csm || !csm.isInitialized()) return;

    const content = this._inputText.trim();
    if (!content) return;

    // Check mute status first
    if (this._isMuted) {
      this._errorMessage = `您已被禁言，剩余时间：${this._muteRemainingText}`;
      return;
    }

    // Local check
    const localCheck = csm.checkLocalText(content);
    if (localCheck.hasViolation) {
      this._errorMessage = '内容包含违规信息，请修改';
      return;
    }

    this._isSending = true;
    this._errorMessage = '';

    // Server-side check
    const result = await csm.fullTextCheck(this._openid, content, ContentSecurityManager.SCENE.CHAT);

    this._isSending = false;

    if (result.pass) {
      // Add message to list
      this._messages.push({
        id: `msg_${Date.now()}`,
        userId: this._openid,
        nickname: this._nickname,
        content,
        timestamp: Date.now(),
        isLocal: true,
      });

      // Keep only last MAX_VISIBLE_MESSAGES
      if (this._messages.length > MAX_VISIBLE_MESSAGES) {
        this._messages = this._messages.slice(-MAX_VISIBLE_MESSAGES);
      }

      this._inputText = '';
      this._errorMessage = '';
      this._hideKeyboard();

      // Scroll to bottom
      this._scrollOffset = 0;
    } else {
      this._errorMessage = result.errorMessage;
    }
  },

  // ============================================================
  // Mute Status Check
  // ============================================================

  async _checkMuteStatus() {
    const csm = GameGlobal.contentSecurityManager;
    if (!csm || !csm.isInitialized() || !this._openid) return;

    try {
      const status = await csm.getMuteStatus(this._openid);
      this._isMuted = status.isMuted;
      this._muteRemainingText = status.remainingText || '';
    } catch (e) {
      // Assume not muted on error
      this._isMuted = false;
    }
  },

  // ============================================================
  // Reporting
  // ============================================================

  _showReportForMessage(msgIdx) {
    if (msgIdx < 0 || msgIdx >= this._messages.length) return;
    const msg = this._messages[msgIdx];
    if (msg.isLocal) return; // Can't report own messages

    this._reportContentId = msg.id;
    this._reportTargetUserId = msg.userId;
    this._reportContentSummary = msg.content.substring(0, 20);
    this._showReportOverlay = true;
  },

  async _submitReport(reason) {
    const csm = GameGlobal.contentSecurityManager;
    if (!csm || !csm.isInitialized()) return;

    const result = await csm.submitReport({
      contentId: this._reportContentId,
      targetUserId: this._reportTargetUserId,
      contentType: 'chat',
      contentSummary: this._reportContentSummary,
      reporterId: this._openid,
      reason,
    });

    this._showReportOverlay = false;

    if (result.success) {
      wx.showToast({ title: '举报已提交', icon: 'success' });
    } else {
      wx.showToast({ title: result.message || '举报失败', icon: 'none' });
    }
  },

  // ============================================================
  // Render Helpers
  // ============================================================

  _renderMessages(ctx) {
    const areaTop = MESSAGE_AREA_TOP;
    const areaBottom = MESSAGE_AREA_BOTTOM;
    const padding = 10;
    const msgHeight = 40;
    const startY = areaBottom - msgHeight;

    // Clip to message area
    ctx.save();
    ctx.beginPath();
    ctx.rect(0, areaTop, SCREEN_WIDTH, areaBottom - areaTop);
    ctx.clip();

    // Render messages from bottom to top
    let y = startY - this._scrollOffset;
    for (let i = this._messages.length - 1; i >= 0; i--) {
      const msg = this._messages[i];
      if (y < areaTop - msgHeight || y > areaBottom) {
        y -= msgHeight;
        continue;
      }

      const isLocal = msg.isLocal;
      const msgX = isLocal ? SCREEN_WIDTH - padding - 200 : padding;

      // Message bubble
      ctx.fillStyle = isLocal ? 'rgba(74, 144, 226, 0.3)' : 'rgba(255, 255, 255, 0.1)';
      ctx.fillRect(msgX, y, 200, msgHeight - 4);

      // Border
      ctx.strokeStyle = isLocal ? '#4a90d9' : '#555555';
      ctx.lineWidth = 1;
      ctx.strokeRect(msgX, y, 200, msgHeight - 4);

      // Nickname
      ctx.fillStyle = isLocal ? '#FFD700' : '#CCCCCC';
      ctx.font = 'bold 10px Arial';
      ctx.textAlign = 'left';
      ctx.textBaseline = 'top';
      ctx.fillText(msg.nickname, msgX + 6, y + 3);

      // Content
      ctx.fillStyle = '#FFFFFF';
      ctx.font = '11px Arial';
      const contentPreview = msg.content.length > 25 ? msg.content.substring(0, 25) + '...' : msg.content;
      ctx.fillText(contentPreview, msgX + 6, y + 18);

      // Report button for non-local messages
      if (!isLocal) {
        ctx.fillStyle = '#FF6347';
        ctx.font = '9px Arial';
        ctx.textAlign = 'right';
        ctx.fillText('⚠举报', msgX + 196, y + 3);
      }

      y -= msgHeight;
    }

    ctx.restore();

    // Scroll hint if there are more messages
    if (this._messages.length > 0 && this._scrollOffset > 0) {
      ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
      ctx.font = '10px Arial';
      ctx.textAlign = 'center';
      ctx.fillText('↑ 向上滚动查看更多', CENTER_X, areaTop + 10);
    }
  },

  _renderInputArea(ctx) {
    // Input box background
    ctx.fillStyle = 'rgba(255, 255, 255, 0.1)';
    ctx.fillRect(this._inputRect.x, this._inputRect.y, this._inputRect.w, this._inputRect.h);

    ctx.strokeStyle = this._localViolation ? '#FF4444' : '#555555';
    ctx.lineWidth = 1;
    ctx.strokeRect(this._inputRect.x, this._inputRect.y, this._inputRect.w, this._inputRect.h);

    // Input text or placeholder
    ctx.fillStyle = this._inputText ? '#FFFFFF' : '#666666';
    ctx.font = '13px Arial';
    ctx.textAlign = 'left';
    ctx.textBaseline = 'middle';
    const displayText = this._inputText || (this._isMuted ? '您已被禁言' : t('chat.inputPlaceholder'));
    const truncated = displayText.length > 25 ? displayText.substring(0, 25) + '...' : displayText;
    ctx.fillText(truncated, this._inputRect.x + 8, this._inputRect.y + this._inputRect.h / 2);

    // Send button
    const canSend = this._inputText.trim() && !this._localViolation && !this._isSending && !this._isMuted;
    ctx.fillStyle = canSend ? '#4a90d9' : '#555555';
    ctx.fillRect(this._sendBtnRect.x, this._sendBtnRect.y, this._sendBtnRect.w, this._sendBtnRect.h);

    ctx.fillStyle = '#FFFFFF';
    ctx.font = 'bold 13px Arial';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(this._isSending ? '...' : t('chat.send'), this._sendBtnRect.x + this._sendBtnRect.w / 2, this._sendBtnRect.y + this._sendBtnRect.h / 2);
  },

  _renderReportOverlay(ctx) {
    // Semi-transparent overlay
    ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
    ctx.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

    // Report dialog
    const dialogW = Math.min(SCREEN_WIDTH * 0.8, 300);
    const dialogH = 220;
    const dialogX = CENTER_X - dialogW / 2;
    const dialogY = SCREEN_HEIGHT / 2 - dialogH / 2;

    ctx.fillStyle = '#2a2a3e';
    ctx.fillRect(dialogX, dialogY, dialogW, dialogH);

    ctx.strokeStyle = '#4a90d9';
    ctx.lineWidth = 2;
    ctx.strokeRect(dialogX, dialogY, dialogW, dialogH);

    // Title
    ctx.fillStyle = '#FFFFFF';
    ctx.font = 'bold 16px Arial';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(t('chat.reportTitle'), CENTER_X, dialogY + 25);

    // Report reason buttons
    const reasons = [
      { key: 'politics', label: t('chat.reportPolitics') },
      { key: 'pornography', label: t('chat.reportPornography') },
      { key: 'gambling', label: t('chat.reportGambling') },
      { key: 'other', label: t('chat.reportOther') },
    ];

    const btnW = dialogW - 40;
    const btnH = 30;
    let btnY = dialogY + 55;

    this._reportBtnRects = [];
    for (const reason of reasons) {
      const rect = { x: dialogX + 20, y: btnY, w: btnW, h: btnH };
      this._reportBtnRects.push({ rect, key: reason.key });

      ctx.fillStyle = 'rgba(255, 255, 255, 0.1)';
      ctx.fillRect(rect.x, rect.y, rect.w, rect.h);
      ctx.strokeStyle = '#555555';
      ctx.lineWidth = 1;
      ctx.strokeRect(rect.x, rect.y, rect.w, rect.h);

      ctx.fillStyle = '#FFFFFF';
      ctx.font = '13px Arial';
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.fillText(reason.label, rect.x + rect.w / 2, rect.y + rect.h / 2);

      btnY += btnH + 8;
    }

    // Cancel button
    const cancelRect = { x: CENTER_X - 50, y: dialogY + dialogH - 35, w: 100, h: 25 };
    this._reportCancelRect = cancelRect;

    ctx.fillStyle = '#666666';
    ctx.fillRect(cancelRect.x, cancelRect.y, cancelRect.w, cancelRect.h);
    ctx.fillStyle = '#FFFFFF';
    ctx.font = '12px Arial';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(t('chat.reportCancel'), cancelRect.x + cancelRect.w / 2, cancelRect.y + cancelRect.h / 2);
  },

  _handleReportOverlayTouch(x, y) {
    // Check report reason buttons
    if (this._reportBtnRects) {
      for (const btn of this._reportBtnRects) {
        if (this._hitTest(x, y, btn.rect)) {
          this._submitReport(btn.key);
          return;
        }
      }
    }

    // Cancel button
    if (this._reportCancelRect && this._hitTest(x, y, this._reportCancelRect)) {
      this._showReportOverlay = false;
      return;
    }
  },

  // ============================================================
  // Utility
  // ============================================================

  _hitTest(x, y, rect) {
    return rect && x >= rect.x && x <= rect.x + rect.w && y >= rect.y && y <= rect.y + rect.h;
  },
};

module.exports = ChatRoomScene;