import { useEffect, useMemo, useRef, useState } from "react";
import { Image, ScrollView, Switch, Text, Textarea, View } from "@tarojs/components";
import Taro from "@tarojs/taro";
import { useLivePage } from "./hooks/use_live_page";
import { useMemberGuard } from "../../hooks/useMemberGuard";
import { normalizeDisplayText } from "./utils/formatters";
import { UI_TEXT } from "./constants";
import { ActionCard } from "./components/action_card";
import { ClarificationCard } from "./components/clarification_card";
import { SuggestionForm, ActivityForm, MutualAidForm } from "./components/draft_form";
import sendArrowIdleIcon from "../../assets/icons/send-arrow-up-idle.svg";
import sendArrowReadyIcon from "../../assets/icons/send-arrow-up-ready.svg";
import type { ChatMessage } from "./types";
import type { AgentCatalogAction, AgentGrant } from "../../api/agent";
import "./index.scss";

type LivePageState = ReturnType<typeof useLivePage>;
const KEYBOARD_REPORTED_EXTRA_PX = 72;
const QUICK_PROMPT_SUBTITLES: Record<string, string> = {
  "最近有什么活动适合我？": "按时间与报名状态推荐",
  "帮我写一篇建言献策": "整理标题、内容和分类",
  "帮我发布一条企业互助": "资源、需求都能先成稿",
  "我想查询我的积分": "查看积分和履职记录"
};

function normalizeKeyboardDuration(duration?: number) {
  const raw = Number(duration) || 0;
  if (raw > 10) return Math.min(360, Math.max(120, raw));
  if (raw > 0) return Math.min(360, Math.max(120, raw * 1000));
  return 220;
}

function grantName(grant: AgentGrant) {
  if (Boolean(grant.is_official ?? grant.isOfficial)) {
    return `${UI_TEXT.appName}服务`;
  }
  return normalizeDisplayText(grant.client_name ?? grant.clientName ?? "授权服务", "授权服务");
}

function grantMeta(grant: AgentGrant) {
  const status = String(grant.grant_status ?? grant.grantStatus ?? "active");
  const statusText: Record<string, string> = {
    active: "生效中",
    revoked: "已撤销",
    expired: "已过期"
  };
  return `授权${statusText[status] || status}`;
}

function PermissionActionRow({ p, grant, action }: { p: LivePageState; grant: AgentGrant; action: AgentCatalogAction }) {
  const checked = p.isGrantActionSelected(grant, action.actionCode);
  const disabled = !p.isGrantActive(grant) || action.allowedByRole === false;
  return (
    <View className={"live-page__permission-action " + (checked ? "is-checked " : "") + (disabled ? "is-disabled" : "")}>
      <View className="live-page__permission-action-copy">
        <Text className="live-page__permission-action-name">{p.actionDisplayName(action)}</Text>
        <View className="live-page__permission-action-tags">
          <Text>{action.module || "其他"}</Text>
          <Text>{p.actionRiskText(action)}</Text>
          {action.allowedByRole === false ? <Text>角色无权</Text> : null}
        </View>
      </View>
      <Switch
        className="live-page__permission-switch"
        checked={checked}
        disabled={disabled}
        color="#123e7c"
        onChange={(event) => p.toggleGrantAction(grant, action.actionCode, Boolean(event.detail.value))}
      />
    </View>
  );
}

function DraftBubble({ msg, draft, onDraftChange }: { msg: ChatMessage; draft: any; onDraftChange: (d: any) => void }) {
  if (!draft || draft.mode === "none") {
    // Fallback to original text rendering
    return <Text className="live-page__msg-text">{msg.text}</Text>;
  }
  if (draft.mode === "suggestion" && draft.suggestion) {
    return <SuggestionForm draft={draft.suggestion} onChange={(s) => onDraftChange({ ...draft, suggestion: s })} />;
  }
  if (draft.mode === "activity" && draft.activity) {
    return <ActivityForm draft={draft.activity} onChange={(a) => onDraftChange({ ...draft, activity: a })} />;
  }
  if (draft.mode === "mutualAid" && draft.mutualAid) {
    return <MutualAidForm draft={draft.mutualAid} onChange={(m) => onDraftChange({ ...draft, mutualAid: m })} />;
  }
  // Fallback for activityRegister or unknown
  return (
    <View>
      <Text className="live-page__draft-title">{msg.text.split("\n")[0]}</Text>
      {msg.draftLines?.slice(1).map((line) => (
        <Text key={msg.id + "-" + line} className="live-page__draft-line">{line}</Text>
      ))}
    </View>
  );
}

function SourceTrace({ sources }: { sources?: ChatMessage["sources"] }) {
  const rows = (sources || []).filter((item) => item?.title || item?.snippet).slice(0, 3);
  if (!rows.length) return null;
  const openSource = (target?: string) => {
    if (!target) return;
    void Taro.navigateTo({ url: target });
  };
  return (
    <View className="live-page__sources">
      <Text className="live-page__sources-title">来源</Text>
      {rows.map((source, index) => (
        <View
          key={`${source.sourceTable || "source"}-${source.id || index}`}
          className={"live-page__source-card " + (source.pageTarget ? "is-clickable" : "")}
          onClick={() => openSource(source.pageTarget)}
        >
          <View className="live-page__source-head">
            <Text className="live-page__source-label">{source.sourceLabel || "平台内容"}</Text>
            {source.retrievalSource ? (
              <Text className="live-page__source-mode">{source.retrievalSource}</Text>
            ) : null}
            {source.pageTarget ? <Text className="live-page__source-open">查看</Text> : null}
          </View>
          <Text className="live-page__source-title">{source.title || "未命名来源"}</Text>
          {source.snippet ? <Text className="live-page__source-snippet">{source.snippet}</Text> : null}
        </View>
      ))}
    </View>
  );
}

function MessageFeedback({ msg, onFeedback }: { msg: ChatMessage; onFeedback: (messageId: number | undefined, rating: "up" | "down") => void }) {
  if (msg.role !== "assistant" || !msg.messageId || msg.variant === "pending") return null;
  const upActive = msg.feedbackRating === "up";
  const downActive = msg.feedbackRating === "down";
  return (
    <View className="live-page__feedback">
      <View
        className={"live-page__feedback-btn " + (upActive ? "is-active" : "")}
        onClick={(event) => {
          event.stopPropagation();
          onFeedback(msg.messageId, "up");
        }}
      >
        <Text>{upActive ? "已标记有帮助" : "有帮助"}</Text>
      </View>
      <View
        className={"live-page__feedback-btn " + (downActive ? "is-active is-negative" : "")}
        onClick={(event) => {
          event.stopPropagation();
          onFeedback(msg.messageId, "down");
        }}
      >
        <Text>{downActive ? "已标记需改进" : "需改进"}</Text>
      </View>
      {msg.feedbackPending ? <Text className="live-page__feedback-status">提交中</Text> : null}
    </View>
  );
}

export default function LivePage() {
  useMemberGuard("连小新仅面向正式会员开放");
  const p = useLivePage();
  const [keyboardHeight, setKeyboardHeight] = useState(0);
  const [keyboardTransitionMs, setKeyboardTransitionMs] = useState(220);
  const [textareaLineCount, setTextareaLineCount] = useState(1);
  const [closingHistory, setClosingHistory] = useState(false);
  const [closingSettings, setClosingSettings] = useState(false);
  const [creatingConversation, setCreatingConversation] = useState(false);
  const keyboardCloseTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
  const historyCloseTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
  const settingsCloseTimer = useRef<ReturnType<typeof setTimeout> | null>(null);

  const renderHero = p.messages.length === 0 && !p.loading;
  const hasInputValue = Boolean(p.inputValue.trim());
  const estimatedLineCount = useMemo(() => {
    if (!p.inputValue) return 1;
    return p.inputValue.split("\n").reduce((count, line) => {
      return count + Math.max(1, Math.ceil(Array.from(line).length / 18));
    }, 0);
  }, [p.inputValue]);
  const composerLineCount = p.inputValue ? Math.min(3, Math.max(1, textareaLineCount, estimatedLineCount)) : 1;
  const composerInputStyle = { height: `${36 * composerLineCount + 32}rpx` };
  const bodyStyle = { paddingBottom: `${116 + (composerLineCount - 1) * 36}rpx` };
  const keyboardLift = keyboardHeight > 0 ? Math.max(0, keyboardHeight - KEYBOARD_REPORTED_EXTRA_PX) : 0;
  const composerWrapStyle = {
    transform: `translate3d(0, -${keyboardLift}px, 0)`,
    transitionDuration: `${keyboardTransitionMs}ms`
  };

  const clearKeyboardCloseTimer = () => {
    if (!keyboardCloseTimer.current) return;
    clearTimeout(keyboardCloseTimer.current);
    keyboardCloseTimer.current = null;
  };

  const clearHistoryCloseTimer = () => {
    if (!historyCloseTimer.current) return;
    clearTimeout(historyCloseTimer.current);
    historyCloseTimer.current = null;
  };

  const clearSettingsCloseTimer = () => {
    if (!settingsCloseTimer.current) return;
    clearTimeout(settingsCloseTimer.current);
    settingsCloseTimer.current = null;
  };

  const dismissKeyboard = () => {
    setKeyboardTransitionMs(180);
    void Taro.hideKeyboard();
  };

  const openHistoryPanel = (event?: { stopPropagation: () => void }) => {
    event?.stopPropagation();
    dismissKeyboard();
    clearHistoryCloseTimer();
    setClosingHistory(false);
    p.setShowHistory(true);
    void p.refreshConversations();
  };

  const closeHistoryPanel = (event?: { stopPropagation: () => void }) => {
    event?.stopPropagation();
    if (closingHistory) return;
    clearHistoryCloseTimer();
    setClosingHistory(true);
    p.setShowHistory(false);
    historyCloseTimer.current = setTimeout(() => {
      setClosingHistory(false);
      historyCloseTimer.current = null;
    }, 220);
  };

  const openSettingsPanel = (event?: { stopPropagation: () => void }) => {
    event?.stopPropagation();
    dismissKeyboard();
    clearSettingsCloseTimer();
    setClosingSettings(false);
    void p.openSettings();
  };

  const closeSettingsPanel = (event?: { stopPropagation: () => void }) => {
    event?.stopPropagation();
    if (closingSettings) return;
    clearSettingsCloseTimer();
    setClosingSettings(true);
    p.setShowSettings(false);
    settingsCloseTimer.current = setTimeout(() => {
      setClosingSettings(false);
      settingsCloseTimer.current = null;
    }, 220);
  };

  const createHistoryConversation = async (event?: { stopPropagation: () => void }) => {
    event?.stopPropagation();
    if (creatingConversation) return;
    setCreatingConversation(true);
    try {
      const nextId = await p.createFreshConversation(p.selectedModel);
      if (nextId > 0) {
        await p.refreshConversations(nextId);
      }
      closeHistoryPanel();
    } finally {
      setCreatingConversation(false);
    }
  };

  const selectHistoryConversation = (conversationId: number, event?: { stopPropagation: () => void }) => {
    event?.stopPropagation();
    p.setActiveConversationId(conversationId);
    p.activeConversationIdRef.current = conversationId;
    closeHistoryPanel();
  };

  useEffect(() => {
    const handleKeyboardHeightChange: Taro.onKeyboardHeightChange.Callback = (res) => {
      clearKeyboardCloseTimer();
      setKeyboardTransitionMs(220);
      setKeyboardHeight(Math.max(0, Number(res.height) || 0));
    };
    Taro.onKeyboardHeightChange(handleKeyboardHeightChange);
    return () => {
      clearKeyboardCloseTimer();
      Taro.offKeyboardHeightChange(handleKeyboardHeightChange);
    };
  }, []);

  useEffect(() => {
    return () => {
      clearKeyboardCloseTimer();
      clearHistoryCloseTimer();
      clearSettingsCloseTimer();
    };
  }, []);

  return (
    <View className={"live-page " + (keyboardHeight > 0 ? "is-keyboard" : "")} onClick={dismissKeyboard}>
      <View className="live-page__topbar">
        <View className="live-page__brand">
          <Text className="live-page__brand-title">{UI_TEXT.heroTitle}</Text>
          <Text className="live-page__brand-subtitle">{p.bootstrapping ? UI_TEXT.loading : UI_TEXT.heroSubtitle}</Text>
        </View>
        <View className="live-page__top-actions">
          <View className="live-page__text-btn" onClick={openHistoryPanel}>
            <Text>历史</Text>
          </View>
          <View className="live-page__top-divider" />
          <View className="live-page__text-btn" onClick={openSettingsPanel}>
            <Text>权限</Text>
          </View>
        </View>
      </View>

      <View className="live-page__body" style={bodyStyle}>
        {renderHero ? (
          <View className="live-page__hero">
            <View className="live-page__service-grid">
              {UI_TEXT.quickPrompts.map((item) => (
                <View key={item} className="live-page__service-entry" onClick={() => void p.handleSend(item)}>
                  <Text className="live-page__service-entry-title">{item.replace("？", "")}</Text>
                  <Text className="live-page__service-entry-desc">{QUICK_PROMPT_SUBTITLES[item] || "一句话发起办理"}</Text>
                  <Text className="live-page__service-entry-arrow">立即处理</Text>
                </View>
              ))}
            </View>
          </View>
        ) : (
          <ScrollView className="live-page__chat-list" scrollY scrollIntoView={p.bottomRef.current}>
            {p.messages.map((item) => (
              <View key={item.id} id={item.id} className={"live-page__msg-row " + (item.role === "user" ? "is-user" : "is-assistant")}>
                {item.variant === "pending" && p.pending ? (
                  <ActionCard
                    pending={p.pending}
                    capability={p.actionCapabilityFor(p.pending.actionCode)}
                    onConfirm={() => void p.executePending()}
                    onCancel={() => p.setPending(null)}
                  />
                ) : item.choiceOptions && item.choiceOptions.length > 0 ? (
                  <ClarificationCard
                    question={item.text}
                    options={item.choiceOptions}
                    onSelect={(action) => void p.handleActionClick(action)}
                  />
                ) : item.role === "user" ? (
                  <View className="live-page__msg-bubble is-user">
                    <Text className="live-page__msg-text">{item.text}</Text>
                  </View>
                ) : item.draftLines ? (
                  <View className={"live-page__assistant-panel " + (item.variant === "success" ? "is-success" : "")}>
                    <DraftBubble msg={item} draft={p.draft} onDraftChange={(d) => p.setDraft(d)} />
                  </View>
                ) : (
                  <View className={"live-page__assistant-text " + (item.variant === "success" ? "is-success" : "")}>
                    <Text className="live-page__msg-text">{item.text}</Text>
                  </View>
                )}
                {item.role === "assistant" ? <SourceTrace sources={item.sources} /> : null}
                {item.role === "assistant" ? <MessageFeedback msg={item} onFeedback={p.handleMessageFeedback} /> : null}
                {item.pageTarget && item.role === 'assistant' && (
                  <View className="live-page__msg-nav">
                    <View className="live-page__msg-nav-btn" onClick={() => void Taro.navigateTo({ url: item.pageTarget! })}>
                      <Text>前往查看 →</Text>
                    </View>
                  </View>
                )}
                {item.variant !== "pending" && item.actions && item.actions.length > 0 && (
                  <View className="live-page__msg-actions">
                    {item.actions.map((action) => (
                      <View key={item.id + "-" + action.action} className="live-page__msg-action-btn" onClick={() => void p.handleActionClick(action.action)}>
                        <Text>{action.label}</Text>
                      </View>
                    ))}
                  </View>
                )}
                <Text className="live-page__msg-time">{item.time}</Text>
              </View>
            ))}
            <View id={p.bottomRef.current} />
          </ScrollView>
        )}
      </View>

      <View
        className={"live-page__composer-wrap " + (keyboardHeight > 0 ? "is-keyboard" : "")}
        style={composerWrapStyle}
        onClick={(e) => e.stopPropagation()}
      >
        <View className="live-page__composer">
          <Textarea
            className="live-page__composer-input"
            style={composerInputStyle}
            value={p.inputValue}
            placeholder={UI_TEXT.placeholder}
            onInput={(e) => p.setInputValue(String(e.detail.value || ""))}
            onFocus={(e) => {
              clearKeyboardCloseTimer();
              const height = Math.max(0, Number(e.detail.height) || 0);
              if (height > 0) setKeyboardHeight(height);
            }}
            onBlur={() => {
              setKeyboardTransitionMs(180);
              clearKeyboardCloseTimer();
              keyboardCloseTimer.current = setTimeout(() => {
                setKeyboardHeight(0);
                keyboardCloseTimer.current = null;
              }, 260);
            }}
            onLineChange={(e) => setTextareaLineCount(Math.max(1, Number(e.detail.lineCount) || 1))}
            onKeyboardHeightChange={(e) => {
              clearKeyboardCloseTimer();
              setKeyboardTransitionMs(normalizeKeyboardDuration(e.detail.duration));
              setKeyboardHeight(Math.max(0, Number(e.detail.height) || 0));
            }}
            confirmType="send"
            confirmHold
            cursorSpacing={0}
            adjustPosition={false}
            adjustKeyboardTo="bottom"
            fixed
            disableDefaultPadding
            showConfirmBar={false}
            maxlength={-1}
            onConfirm={() => void p.handleSend()}
          />
          <View className={"live-page__composer-send " + (hasInputValue ? "is-ready" : "")} onClick={() => void p.handleSend()}>
            <Image className="live-page__send-icon" src={hasInputValue ? sendArrowReadyIcon : sendArrowIdleIcon} mode="aspectFit" />
          </View>
        </View>
      </View>

      {(p.showHistory || closingHistory) && (
        <View className={"live-page__overlay is-history " + (closingHistory ? "is-closing" : "")} onClick={closeHistoryPanel}>
          <View className="live-page__drawer" onClick={(e) => e.stopPropagation()}>
            <View className="live-page__drawer-head">
              <Text className="live-page__drawer-title">{UI_TEXT.drawerTitle}</Text>
              <View className="live-page__drawer-close-btn" onClick={closeHistoryPanel}>
                <Text>关闭</Text>
              </View>
            </View>
            <View className={"live-page__drawer-new " + (creatingConversation ? "is-loading" : "")} onClick={createHistoryConversation}>
              <Text>{creatingConversation ? "创建中..." : "+ 新建会话"}</Text>
            </View>
            <ScrollView className="live-page__drawer-list" scrollY>
              {p.conversations.map((item) => (
                <View
                  key={item.id}
                  className={"live-page__history-item " + (item.id === p.activeConversationId ? "is-active" : "")}
                  onClick={(event) => selectHistoryConversation(item.id, event)}
                >
                  <Text className="live-page__history-title">{item.title}</Text>
                  <Text className="live-page__history-summary">{item.summary || UI_TEXT.noConversationSummary}</Text>
                  <View className="live-page__history-meta">
                    <Text>{item.updatedAt}</Text>
                    <Text>{UI_TEXT.modelNames[item.modelCode || ""] || item.modelCode || ""}</Text>
                  </View>
                </View>
              ))}
            </ScrollView>
          </View>
        </View>
      )}

      {(p.showSettings || closingSettings) && (
        <View className={"live-page__overlay is-settings " + (closingSettings ? "is-closing" : "")} onClick={closeSettingsPanel}>
          <View className="live-page__settings" onClick={(e) => e.stopPropagation()}>
            <View className="live-page__drawer-head">
              <View>
                <Text className="live-page__drawer-title">权限</Text>
                <Text className="live-page__drawer-subtitle">管理连小新可读取和申请办理的范围</Text>
              </View>
              <View className="live-page__drawer-close-btn" onClick={closeSettingsPanel}>
                <Text>关闭</Text>
              </View>
            </View>

            <View className="live-page__permission-summary">
              <View>
                <Text className="live-page__permission-summary-num">{String(p.permissionSummary.grants)}</Text>
                <Text className="live-page__permission-summary-label">授权</Text>
              </View>
              <View>
                <Text className="live-page__permission-summary-num">{String(p.permissionSummary.readOnly)}</Text>
                <Text className="live-page__permission-summary-label">只读</Text>
              </View>
              <View>
                <Text className="live-page__permission-summary-num">{String(p.permissionSummary.operable)}</Text>
                <Text className="live-page__permission-summary-label">可操作</Text>
              </View>
              <View className="live-page__permission-refresh" onClick={() => void p.loadAgentPermissions()}>
                <Text>刷新</Text>
              </View>
            </View>

            {p.permissionNotice ? <Text className="live-page__permission-notice">{p.permissionNotice}</Text> : null}
            {p.permissionError ? <Text className="live-page__permission-error">{p.permissionError}</Text> : null}

            <ScrollView className="live-page__permission-scroll" scrollY>
              {p.permissionLoading ? (
                <View className="live-page__permission-empty"><Text>{UI_TEXT.loading}</Text></View>
              ) : p.agentGrants.length === 0 ? (
                <View className="live-page__permission-empty"><Text>当前还没有服务授权，进入后会自动创建。</Text></View>
              ) : (
                p.agentGrants.map((grant) => {
                  const grantId = Number(grant.id || 0);
                  const selected = p.getGrantSelectedActions(grant);
                  const readSelected = selected.filter((code) => p.readOnlyCatalogActions.some((item) => item.actionCode === code)).length;
                  const operableSelected = selected.filter((code) => p.operableCatalogActions.some((item) => item.actionCode === code)).length;
                  return (
                    <View key={grant.id} className="live-page__permission-grant">
                      <View className="live-page__permission-grant-head">
                        <View>
                          <Text className="live-page__permission-grant-name">{grantName(grant)}</Text>
                          <Text className="live-page__permission-grant-meta">{grantMeta(grant)}</Text>
                        </View>
                        {Boolean(grant.is_official ?? grant.isOfficial) ? <Text className="live-page__permission-badge">官方</Text> : null}
                      </View>

                      <View className="live-page__permission-counts">
                        <Text>只读 {readSelected}</Text>
                        <Text>可操作 {operableSelected}</Text>
                        <Text>{p.isGrantActive(grant) ? "可编辑" : "已停用"}</Text>
                      </View>

                      <View className="live-page__permission-section">
                        <Text className="live-page__permission-section-title">只读范围</Text>
                        <Text className="live-page__permission-section-desc">资料、积分、活动、问卷等读取能力，只按你的账号权限返回。</Text>
                        {p.readOnlyCatalogActions.length === 0 ? (
                          <Text className="live-page__permission-empty-line">暂无可配置只读能力</Text>
                        ) : (
                          p.readOnlyCatalogActions.map((action) => (
                            <PermissionActionRow key={`${grant.id}-read-${action.actionCode}`} p={p} grant={grant} action={action} />
                          ))
                        )}
                      </View>

                      <View className="live-page__permission-section">
                        <Text className="live-page__permission-section-title">可操作范围</Text>
                        <Text className="live-page__permission-section-desc">发布、报名、提交、审核等动作仍会走确认，不会自动越权执行。</Text>
                        {p.operableCatalogActions.length === 0 ? (
                          <Text className="live-page__permission-empty-line">暂无可配置操作能力</Text>
                        ) : (
                          p.operableCatalogActions.map((action) => (
                            <PermissionActionRow key={`${grant.id}-operate-${action.actionCode}`} p={p} grant={grant} action={action} />
                          ))
                        )}
                      </View>

                      <View className="live-page__permission-save" onClick={() => void p.saveGrantScope(grant)}>
                        <Text>{p.permissionSavingId === grantId ? "保存中..." : "保存权限范围"}</Text>
                      </View>
                    </View>
                  );
                })
              )}

            </ScrollView>
          </View>
        </View>
      )}
    </View>
  );
}
