<template>
  <section class="page-grid">
    <section class="panel panel-hero extension-hero">
      <div class="hero-copy">
        <p class="eyebrow">系统拓展</p>
        <span
          class="title-with-help"
          title="该模块仅系统管理员可见，用于维护全局右上角喇叭广播，以及后续 AI 聊天机器人接入免费 LLM API 的配置。"
        >
          <h3>广播通知与 AI 助手配置中心</h3>
        </span>
      </div>
      <div class="extension-status-card">
        <span class="panel-tag">ADMIN ONLY</span>
        <strong>{{ assistantConfig.enabled ? "真实 LLM 已启用" : "当前为占位助手模式" }}</strong>
        <p>{{ assistantConfig.model_name || "尚未配置模型名称" }}</p>
      </div>
    </section>

    <section class="panel">
      <div class="panel-header">
        <div>
          <p class="eyebrow">广播内容管理</p>
          <h3>右上角小喇叭横幅</h3>
        </div>
        <div class="workflow-inline-actions">
          <span class="panel-tag">{{ editingBroadcastId ? "编辑广播" : "新增广播" }}</span>
          <button class="ghost-button" type="button" @click="resetBroadcastForm">新建</button>
        </div>
      </div>

      <div v-if="feedbackMessage" class="feedback-banner">{{ feedbackMessage }}</div>
      <div v-if="errorMessage" class="feedback-banner error-banner">{{ errorMessage }}</div>

      <form class="stack-form compact-extension-form" @submit.prevent="saveBroadcast">
        <div class="double-field">
          <label class="form-field">
            <span>广播标题 <i class="required-mark">*</i></span>
            <input v-model.trim="broadcastForm.title" type="text" required />
          </label>
          <label class="form-field">
            <span>提示类型</span>
            <select v-model="broadcastForm.tone">
              <option value="INFO">信息</option>
              <option value="SUCCESS">成功</option>
              <option value="WARNING">预警</option>
              <option value="DANGER">重要</option>
            </select>
          </label>
        </div>

        <label class="form-field">
          <span>广播内容 <i class="required-mark">*</i></span>
          <input v-model.trim="broadcastForm.content" type="text" required />
        </label>

        <div class="form-field">
          <span>通知考勤点 <i class="required-mark">*</i></span>
          <div class="checkbox-grid">
            <label v-for="point in attendancePoints" :key="point.name" class="checkbox-field">
              <input v-model="broadcastForm.attendance_point_names" type="checkbox" :value="point.name" />
              <span>{{ point.name }}</span>
            </label>
          </div>
        </div>

        <div class="triple-field">
          <label class="form-field">
            <span>开始时间</span>
            <input v-model="broadcastForm.starts_at" type="datetime-local" />
          </label>
          <label class="form-field">
            <span>结束时间</span>
            <input v-model="broadcastForm.ends_at" type="datetime-local" />
          </label>
          <label class="form-field">
            <span>排序号</span>
            <input v-model.number="broadcastForm.sort_no" type="number" step="1" />
          </label>
        </div>

        <div class="double-field">
          <label class="form-field">
            <span>状态</span>
            <select v-model="broadcastForm.status">
              <option value="ACTIVE">启用</option>
              <option value="PAUSED">暂停</option>
            </select>
          </label>
          <div class="form-field extension-preview-field">
            <span>横幅预览</span>
            <div class="broadcast-banner extension-preview-banner" :class="`broadcast-${broadcastForm.tone.toLowerCase()}`">
              <span class="broadcast-speaker" aria-hidden="true">
                <svg viewBox="0 0 24 24" role="img">
                  <path d="M4 10.5H7.5L16 6.5V17.5L7.5 13.5H4V10.5Z" />
                  <path d="M7.5 13.5L9.2 19H12.2L10.4 14.8" />
                  <path d="M18.3 9.2L20.5 8" />
                  <path d="M18.7 12H21.4" />
                  <path d="M18.3 14.8L20.5 16" />
                </svg>
              </span>
              <strong>{{ broadcastForm.title || "广播标题" }}</strong>
              <span>{{ broadcastForm.content || "广播内容会显示在系统右上角" }}</span>
            </div>
          </div>
        </div>

        <button class="primary-button" type="submit">{{ editingBroadcastId ? "更新广播" : "保存广播" }}</button>
      </form>
    </section>

    <section class="panel">
      <div class="panel-header">
        <div>
          <p class="eyebrow">仓库编号配置</p>
          <h3>原材料库存批次号前缀</h3>
        </div>
        <span class="panel-tag">{{ rawLotPrefixConfig.config_value || "YL" }}</span>
      </div>

      <form class="stack-form compact-extension-form" @submit.prevent="saveRawLotPrefixConfig">
        <div class="double-field">
          <label class="form-field">
            <span>前缀</span>
            <input v-model.trim="rawLotPrefixForm.config_value" type="text" maxlength="20" placeholder="默认 YL" />
          </label>
          <label class="form-field">
            <span>说明</span>
            <input v-model.trim="rawLotPrefixForm.remark" type="text" placeholder="例如：原材料库存批次号默认前缀" />
          </label>
        </div>
        <div class="workflow-tip">
          生成效果示例：{{ rawLotPrefixForm.config_value || "YL" }}0001；序号达到 9999 后会自然扩展为 {{ rawLotPrefixForm.config_value || "YL" }}10000。
        </div>
        <button class="primary-button" type="submit">保存前缀</button>
      </form>
    </section>

    <section class="panel">
      <div class="panel-header">
        <div>
          <p class="eyebrow">生产模式配置</p>
          <h3>对接智能报工小程序</h3>
        </div>
        <span class="panel-tag">{{ smartOperationReportForm.enabled ? "已对接" : "未对接" }}</span>
      </div>

      <form class="stack-form compact-extension-form" @submit.prevent="saveSmartOperationReportConfig">
        <label class="checkbox-field extension-switch-field">
          <input v-model="smartOperationReportForm.enabled" type="checkbox" />
          <span>对接智能报工小程序</span>
        </label>
        <div class="workflow-tip">
          {{ smartOperationReportForm.enabled ? "开启后显示工序报工，并按小程序报工数据辅助计算生产进度。" : "关闭后隐藏工序报工，生产进度按ERP入库数据和BOM反推。" }}
        </div>
        <label class="form-field">
          <span>说明</span>
          <input v-model.trim="smartOperationReportForm.remark" type="text" placeholder="例如：客户未购买小程序模块，暂按ERP入库反推" />
        </label>
        <button class="primary-button" type="submit">保存生产模式</button>
      </form>
    </section>

    <section class="panel">
      <div class="panel-header">
        <div>
          <p class="eyebrow">广播列表</p>
          <h3>当前系统广播记录</h3>
        </div>
      </div>

      <TableControls
        v-model:search="broadcastControls.search.value"
        v-model:sort-key="broadcastControls.sortKey.value"
        v-model:sort-direction="broadcastControls.sortDirection.value"
        :sort-options="broadcastControls.sortOptions"
        placeholder="搜索标题、内容、状态、类型"
      />

      <div class="table-wrap">
        <table class="data-table compact-table">
          <thead>
            <tr>
              <th>标题</th>
              <th>考勤点</th>
              <th>内容</th>
              <th>类型</th>
              <th>状态</th>
              <th>开始</th>
              <th>结束</th>
              <th>排序</th>
              <th>操作</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="item in paginatedBroadcasts" :key="item.broadcast_id">
              <td>{{ item.title }}</td>
              <td>{{ formatAttendancePoints(item.attendance_point_names) }}</td>
              <td>{{ item.content }}</td>
              <td>{{ formatToneLabel(item.tone) }}</td>
              <td>{{ item.status === "ACTIVE" ? "启用" : "暂停" }}</td>
              <td>{{ formatDateTime(item.starts_at) }}</td>
              <td>{{ formatDateTime(item.ends_at) }}</td>
              <td>{{ item.sort_no }}</td>
              <td class="action-row"><button class="ghost-button" type="button" @click="editBroadcast(item)">编辑</button></td>
            </tr>
            <tr v-if="!filteredBroadcasts.length">
              <td colspan="9" class="empty-row">暂无广播内容</td>
            </tr>
          </tbody>
        </table>
      </div>
      <PaginationBar v-model:page="broadcastPage" v-model:page-size="broadcastPageSize" :total="filteredBroadcasts.length" />
    </section>

    <section class="panel">
      <div class="panel-header">
        <div>
          <p class="eyebrow">AI 机器人配置</p>
          <h3>免费 LLM API 与新对话系统提示词</h3>
        </div>
        <span class="panel-tag">{{ assistantConfig.api_key_configured ? "密钥已配置" : "未配置密钥" }}</span>
      </div>

      <form class="stack-form" @submit.prevent="saveAssistantConfig">
        <div class="triple-field">
          <label class="form-field">
            <span>助手名称</span>
            <input v-model.trim="assistantForm.assistant_name" type="text" required />
          </label>
          <label class="form-field">
            <span>供应商</span>
            <input v-model.trim="assistantForm.provider_name" type="text" placeholder="例如：OpenRouter / SiliconFlow" />
          </label>
          <label class="form-field">
            <span>模型名称</span>
            <input v-model.trim="assistantForm.model_name" type="text" placeholder="例如：deepseek-chat" />
          </label>
        </div>

        <div class="double-field">
          <label class="form-field">
            <span>API Base URL</span>
            <input v-model.trim="assistantForm.api_base_url" type="text" placeholder="https://api.example.com/v1" />
          </label>
          <label class="form-field">
            <span>API Key</span>
            <input v-model.trim="assistantForm.api_key" type="password" :placeholder="assistantConfig.api_key_configured ? '留空表示不修改现有密钥' : '请输入 API Key'" />
          </label>
        </div>

        <div class="double-field">
          <label class="form-field">
            <span>温度</span>
            <input v-model.number="assistantForm.temperature" type="number" min="0" max="2" step="0.1" />
          </label>
          <label class="form-field checkbox-field">
            <input v-model="assistantForm.enabled" type="checkbox" />
            <span>启用真实 LLM 调用</span>
          </label>
        </div>

        <label class="form-field">
          <span>每次新建对话的系统提示词</span>
          <textarea v-model.trim="assistantForm.system_prompt" rows="5"></textarea>
        </label>

        <button class="primary-button" type="submit">保存 AI 配置</button>
      </form>
    </section>
  </section>
</template>

<script setup>
import { onMounted, reactive, ref } from "vue";

import PaginationBar from "../components/PaginationBar.vue";
import TableControls from "../components/TableControls.vue";
import { fetchResource, postResource, putResource } from "../services/api";
import { resetSmartOperationReportConfigCache } from "../services/systemFeatures";
import { dictionaryFallback, normalizeDictionaryKey } from "../utils/dictionaries";
import { formatDateTime } from "../utils/formatters";
import { usePagination } from "../utils/pagination";
import { useTableControls } from "../utils/tableControls";

const broadcasts = ref([]);
const attendancePoints = ref([]);
const assistantConfig = ref({});
const rawLotPrefixConfig = ref({});
const smartOperationReportConfig = ref({});
const feedbackMessage = ref("");
const errorMessage = ref("");
const editingBroadcastId = ref(null);

const broadcastForm = reactive(buildEmptyBroadcastForm());
const assistantForm = reactive(buildEmptyAssistantForm());
const rawLotPrefixForm = reactive({ config_value: "YL", remark: "" });
const smartOperationReportForm = reactive({ enabled: true, remark: "" });

const broadcastControls = useTableControls(broadcasts, {
  searchFields: ["title", "content", "tone", "status", (row) => row.attendance_point_names?.join(" / ")],
  sortOptions: [
    { key: "broadcast_id", label: "创建顺序" },
    { key: "title", label: "标题" },
    { key: "status", label: "状态" },
    { key: "sort_no", label: "排序号" },
    { key: "updated_at", label: "更新时间" }
  ],
  defaultSortKey: "broadcast_id",
  defaultSortDirection: "desc"
});

const filteredBroadcasts = broadcastControls.rows;
const {
  page: broadcastPage,
  pageSize: broadcastPageSize,
  rows: paginatedBroadcasts
} = usePagination(filteredBroadcasts);

function buildEmptyBroadcastForm() {
  return {
    title: "",
    content: "",
    attendance_point_names: [],
    tone: "INFO",
    status: "ACTIVE",
    starts_at: "",
    ends_at: "",
    sort_no: 10
  };
}

function buildEmptyAssistantForm() {
  return {
    assistant_name: "嘉恒工艺助手",
    provider_name: "",
    api_base_url: "",
    api_key: "",
    model_name: "",
    temperature: 0.3,
    system_prompt: "你是宁波嘉恒智能五金 ERP 的企业助手，优先解释业务流程、字段含义、数据异常和操作步骤。",
    enabled: false
  };
}

function normalizeDateTime(value) {
  return value ? `${value}:00` : null;
}

function toDateTimeInput(value) {
  return value ? String(value).replace("T", " ").slice(0, 16).replace(" ", "T") : "";
}

function formatToneLabel(value) {
  return {
    INFO: "信息",
    SUCCESS: "成功",
    WARNING: "预警",
    DANGER: "重要"
  }[normalizeDictionaryKey(value)] || dictionaryFallback(value, "-", "未识别通知类型");
}

function resetBroadcastForm() {
  editingBroadcastId.value = null;
  Object.assign(broadcastForm, buildEmptyBroadcastForm());
  broadcastForm.attendance_point_names = attendancePoints.value.map((point) => point.name);
}

function editBroadcast(item) {
  editingBroadcastId.value = item.broadcast_id;
  Object.assign(broadcastForm, {
    title: item.title || "",
    content: item.content || "",
    attendance_point_names: item.attendance_point_names?.length
      ? [...item.attendance_point_names]
      : attendancePoints.value.map((point) => point.name),
    tone: item.tone || "INFO",
    status: item.status || "ACTIVE",
    starts_at: toDateTimeInput(item.starts_at),
    ends_at: toDateTimeInput(item.ends_at),
    sort_no: Number(item.sort_no || 0)
  });
}

function formatAttendancePoints(pointNames) {
  return pointNames?.length ? pointNames.join(" / ") : "-";
}

function applyAssistantConfig(config) {
  assistantConfig.value = config || {};
  Object.assign(assistantForm, {
    assistant_name: config?.assistant_name || "嘉恒工艺助手",
    provider_name: config?.provider_name || "",
    api_base_url: config?.api_base_url || "",
    api_key: "",
    model_name: config?.model_name || "",
    temperature: Number(config?.temperature ?? 0.3),
    system_prompt: config?.system_prompt || buildEmptyAssistantForm().system_prompt,
    enabled: Boolean(config?.enabled)
  });
}

function applyRawLotPrefixConfig(config) {
  rawLotPrefixConfig.value = config || {};
  rawLotPrefixForm.config_value = config?.config_value || "YL";
  rawLotPrefixForm.remark = config?.remark || "";
}

function applySmartOperationReportConfig(config) {
  smartOperationReportConfig.value = config || {};
  smartOperationReportForm.enabled = config?.enabled !== false;
  smartOperationReportForm.remark = config?.remark || "";
}

async function loadAll() {
  const [pointRows, broadcastRows, config, rawLotPrefix, smartOperationReport] = await Promise.all([
    fetchResource("/master-data/miniapp-attendance-points", []),
    fetchResource("/system-extension/broadcasts", []),
    fetchResource("/system-extension/assistant-config", buildEmptyAssistantForm()),
    fetchResource("/system-extension/raw-material-lot-prefix", { config_value: "YL", remark: "" }),
    fetchResource("/system-extension/smart-operation-report", { enabled: true, config_value: "开启", remark: "" })
  ]);
  attendancePoints.value = pointRows;
  broadcasts.value = broadcastRows;
  if (!broadcastForm.attendance_point_names.length) {
    broadcastForm.attendance_point_names = pointRows.map((point) => point.name);
  }
  applyAssistantConfig(config);
  applyRawLotPrefixConfig(rawLotPrefix);
  applySmartOperationReportConfig(smartOperationReport);
}

async function saveBroadcast() {
  feedbackMessage.value = "";
  errorMessage.value = "";
  try {
    if (!broadcastForm.attendance_point_names.length) {
      throw new Error("请至少选择一个通知考勤点");
    }
    const payload = {
      title: broadcastForm.title,
      content: broadcastForm.content,
      attendance_point_names: broadcastForm.attendance_point_names,
      tone: broadcastForm.tone,
      status: broadcastForm.status,
      starts_at: normalizeDateTime(broadcastForm.starts_at),
      ends_at: normalizeDateTime(broadcastForm.ends_at),
      sort_no: Number(broadcastForm.sort_no || 0)
    };
    const result = editingBroadcastId.value
      ? await putResource(`/system-extension/broadcasts/${editingBroadcastId.value}`, payload)
      : await postResource("/system-extension/broadcasts", payload);
    feedbackMessage.value = `广播「${result.title}」已保存`;
    resetBroadcastForm();
    broadcasts.value = await fetchResource("/system-extension/broadcasts", []);
  } catch (error) {
    errorMessage.value = error.message || "广播保存失败";
  }
}

async function saveAssistantConfig() {
  feedbackMessage.value = "";
  errorMessage.value = "";
  try {
    const payload = {
      assistant_name: assistantForm.assistant_name,
      provider_name: assistantForm.provider_name || null,
      api_base_url: assistantForm.api_base_url || null,
      api_key: assistantForm.api_key || null,
      model_name: assistantForm.model_name || null,
      temperature: Number(assistantForm.temperature || 0.3),
      system_prompt: assistantForm.system_prompt || null,
      enabled: Boolean(assistantForm.enabled)
    };
    const result = await putResource("/system-extension/assistant-config", payload);
    applyAssistantConfig(result);
    feedbackMessage.value = "AI 机器人配置已保存";
  } catch (error) {
    errorMessage.value = error.message || "AI 配置保存失败";
  }
}

async function saveRawLotPrefixConfig() {
  feedbackMessage.value = "";
  errorMessage.value = "";
  try {
    const result = await putResource("/system-extension/raw-material-lot-prefix", {
      config_value: rawLotPrefixForm.config_value || "YL",
      remark: rawLotPrefixForm.remark || null
    });
    applyRawLotPrefixConfig(result);
    feedbackMessage.value = "原材料库存批次号前缀已保存";
  } catch (error) {
    errorMessage.value = error.message || "原材料库存批次号前缀保存失败";
  }
}

async function saveSmartOperationReportConfig() {
  feedbackMessage.value = "";
  errorMessage.value = "";
  try {
    const result = await putResource("/system-extension/smart-operation-report", {
      enabled: Boolean(smartOperationReportForm.enabled),
      remark: smartOperationReportForm.remark || null
    });
    applySmartOperationReportConfig(result);
    resetSmartOperationReportConfigCache(result);
    feedbackMessage.value = "生产模式配置已保存";
  } catch (error) {
    errorMessage.value = error.message || "生产模式配置保存失败";
  }
}

onMounted(async () => {
  await loadAll();
});
</script>
