import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import VueDevTools from "vite-plugin-vue-devtools";
import fs from "fs";
import path from "path";

function mockPlugin() {
  const mockDir = path.resolve(process.cwd(), "mock");

  const filePath = (file) => path.resolve(mockDir, file);

  const send = (res, obj, code = 200) => {
    res.statusCode = code;
    res.setHeader("Content-Type", "application/json; charset=utf-8");
    res.end(JSON.stringify(obj));
  };

  const readJson = (file, fallback) => {
    const p = filePath(file);
    if (!fs.existsSync(p)) return fallback;
    try {
      return JSON.parse(fs.readFileSync(p, "utf-8") || "null") ?? fallback;
    } catch {
      return fallback;
    }
  };

  const writeJson = (file, data) => {
    const p = filePath(file);
    fs.writeFileSync(p, JSON.stringify(data, null, 2), "utf-8");
  };

  const readBodyJson = (req) =>
    new Promise((resolve, reject) => {
      let body = "";
      req.on("data", (c) => (body += c));
      req.on("end", () => {
        try {
          resolve(JSON.parse(body || "{}"));
        } catch (e) {
          reject(e);
        }
      });
    });

  const getPathname = (req) => {
    try {
      return new URL(req.url, "http://localhost").pathname;
    } catch {
      return req.url;
    }
  };

  // 统一 success
  const ok = (res) => send(res, { error: 0, msg: "success" });

  // ===== 业务联动：积分更新规则 =====
  // yearScore: score=duration*2，看起来是 1小时=2分
  const POINTS_PER_HOUR = 2;

  const addScore = (deltaHour) => {
    const deltaScore = (Number(deltaHour) || 0) * POINTS_PER_HOUR;

    // userInfo.json
    const ui = readJson("userInfo.json", { error: 0, data: {} });
    ui.data = ui.data || {};
    ui.data.totalScore = (Number(ui.data.totalScore) || 0) + deltaScore;
    writeJson("userInfo.json", ui);

    // userScore.json
    const us = readJson("userScore.json", { error: 0, data: {} });
    us.data = us.data || {};
    us.data.totalScore = (Number(us.data.totalScore) || 0) + deltaScore;
    writeJson("userScore.json", us);

    // scoreOverview.json
    const ov = readJson("scoreOverview.json", { error: 0, data: {} });
    ov.data = ov.data || {};
    ov.data.totalScore = (Number(ov.data.totalScore) || 0) + deltaScore;
    writeJson("scoreOverview.json", ov);

    // yearScore.json
    const ys = readJson("yearScore.json", { error: 0, data: {} });
    ys.data = ys.data || {};
    ys.data.times = (Number(ys.data.times) || 0) + 1;
    ys.data.duration =
      (Number(ys.data.duration) || 0) + (Number(deltaHour) || 0);
    ys.data.score = (Number(ys.data.score) || 0) + deltaScore;
    writeJson("yearScore.json", ys);
  };

  return {
    name: "simple-mock-plugin",
    configureServer(server) {
      server.middlewares.use(async (req, res, next) => {
        const pathname = getPathname(req);

        // ========== GET：仍然走你原来的静态文件 ==========
        const sendJSON = (file) => {
          const p = filePath(file);
          if (!fs.existsSync(p)) {
            return send(res, { error: `Mock file not found: ${file}` }, 404);
          }
          res.setHeader("Content-Type", "application/json; charset=utf-8");
          res.end(fs.readFileSync(p, "utf-8"));
        };

        if (pathname === "/api/userInfo" && req.method === "GET")
          return sendJSON("userInfo.json");
        if (pathname.startsWith("/api/actList") && req.method === "GET")
          return sendJSON("actList.json");
        if (
          pathname.startsWith("/api/report/myOverview") &&
          req.method === "GET"
        )
          return sendJSON("scoreOverview.json");
        if (pathname.startsWith("/api/report/rankList") && req.method === "GET")
          return sendJSON("rank.json");
        if (
          pathname.startsWith("/api/actDetails/details") &&
          req.method === "GET"
        ) {
          const url = new URL(req.url, `http://${req.headers.host}`);
          const id = Number(url.searchParams.get("id"));
          
          if (!id) {
            return send(res, { error: 1, msg: "missing id parameter" }, 400);
          }

          const actList = readJson("actList.json", {
            error: 0,
            data: { list: [] },
          });
          const act = (actList.data?.list || []).find((x) => Number(x.id) === id);
          
          if (!act) {
            return send(res, { error: 1, msg: "activity not found" }, 404);
          }

          const actDetails = readJson("actDetails.json", {
            error: 0,
            data: { details: {} },
          });
          const detailsTemplate = actDetails.data?.details || {};
          
          const result = {
            error: 0,
            data: {
              details: {
                id: act.id,
                title: act.title,
                startTime: act.startTime,
                endTime: act.endTime,
                place: act.place,
                content: detailsTemplate.content || "活动详情待补充",
                publisher: detailsTemplate.publisher || "福州大学至诚学院团委",
                hour: detailsTemplate.hour || 4,
                total: detailsTemplate.total || 50,
                canApply: act.canApply,
                applyStatus: act.applyStatus || 0,
                actPic: act.actPic
              }
            }
          };
          
          return send(res, result);
        }
        if (pathname.startsWith("/api/myApplyList") && req.method === "GET")
          return sendJSON("myApplyList.json");
        if (
          pathname.startsWith("/api/act/publisherList") &&
          req.method === "GET"
        )
          return sendJSON("publishers.json");
        if (
          pathname.startsWith("/api/act/durationsList") &&
          req.method === "GET"
        )
          return sendJSON("durationList.json");
        if (
          pathname.startsWith("/api/service/userScore") &&
          req.method === "GET"
        )
          return sendJSON("userScore.json");
        if (
          pathname.startsWith("/api/service/yearList") &&
          req.method === "GET"
        )
          return sendJSON("yearList.json");
        if (
          pathname.startsWith("/api/service/yearScore") &&
          req.method === "GET"
        )
          return sendJSON("yearScore.json");
        if (pathname.startsWith("/api/service/list") && req.method === "GET") {
          const sl = readJson("serviceList.json", {
            error: 0,
            data: { current: 1, pageSize: 10, pageCount: 1, list: [] },
          });
          const url = new URL(req.url, `http://${req.headers.host}`);
          const year = url.searchParams.get("year");
          let list = sl.data?.list || [];
          if (year && year !== "all") {
            const yearNum = Number(year);
            list = list.filter((item) => {
              const date = new Date(item.time);
              return date.getFullYear() === yearNum;
            });
          }
          const result = {
            error: 0,
            data: {
              ...sl.data,
              list,
              current: 1,
              pageCount: 1,
            },
          };
          return send(res, result);
        }
        if (pathname.startsWith("/api/service/details") && req.method === "GET") {
          const url = new URL(req.url, `http://${req.headers.host}`);
          const id = Number(url.searchParams.get("id"));
          
          if (!id) {
            return send(res, { error: 1, msg: "missing id parameter" }, 400);
          }

          const sl = readJson("serviceList.json", {
            error: 0,
            data: { current: 1, pageSize: 10, pageCount: 1, list: [] },
          });
          const record = (sl.data?.list || []).find((x) => Number(x.id) === id);
          
          if (!record) {
            return send(res, { error: 1, msg: "record not found" }, 404);
          }

          let placeText = record.publisher || "未知来源";
          if (typeof placeText === "number") {
            const publishers = readJson("publishers.json", {
              error: 0,
              data: { list: [] },
            });
            const publisherItem = (publishers.data?.list || []).find(
              (x) => x.value === placeText
            );
            placeText = publisherItem?.text || "未知来源";
          }

          const result = {
            error: 0,
            data: {
              details: {
                actTime: record.time,
                place: placeText,
                content: record.content || "",
                imgList: record.imgList || [record.pic || "./imgs/actImg.jpeg"],
                hour: record.hour || 0,
                uploadTime: record.uploadTime || record.time || Date.now(),
                status: record.status || 0
              }
            }
          };
          
          return send(res, result);
        }

        // ========== POST：全部改成“落盘” ==========
        // 1) 用户信息保存
        if (pathname === "/api/userInfo/submit" && req.method === "POST") {
          try {
            const incoming = await readBodyJson(req); // {name,code,gender,phoneNum,school,profession,userType...}
            const old = readJson("userInfo.json", { error: 0, data: {} });
            const next = {
              error: 0,
              data: { ...(old.data || {}), ...incoming },
            };
            writeJson("userInfo.json", next);
            return ok(res);
          } catch {
            return send(res, { error: 1, msg: "Invalid JSON body" }, 400);
          }
        }

        // 2) 申请/撤销活动：更新 myApplyList + actDetails(可选 actList)
        if (
          pathname.startsWith("/api/actDetails/apply") &&
          req.method === "POST"
        ) {
          try {
            const incoming = await readBodyJson(req);
            // 约定：至少要有 id；可选传 action: "apply" | "cancel"
            const id = Number(incoming.id ?? incoming.actId);
            const action = incoming.action || "apply";
            if (!id) return send(res, { error: 1, msg: "missing id" }, 400);

            // 读活动列表，用来补齐标题/时间/地点等字段
            const actList = readJson("actList.json", {
              error: 0,
              data: { list: [] },
            });
            const act = (actList.data?.list || []).find(
              (x) => Number(x.id) === id,
            );

            // myApplyList.json
            const applyJson = readJson("myApplyList.json", {
              error: 0,
              data: { current: 1, pageSize: 10, pageCount: 1, list: [] },
            });
            const list = applyJson.data?.list || [];
            const existsIdx = list.findIndex((x) => Number(x.id) === id);

            if (action === "cancel") {
              if (existsIdx >= 0) list.splice(existsIdx, 1);
            } else {
              // apply
              if (existsIdx < 0) {
                // 申请状态：你的 mock 里 1/2 出现过。这里用 1 表示已申请
                list.unshift({ ...(act || { id }), applyStatus: 1 });
              } else {
                list[existsIdx].applyStatus = 1;
              }
            }

            applyJson.data = applyJson.data || {};
            applyJson.data.list = list;
            applyJson.data.pageCount = 1;
            writeJson("myApplyList.json", applyJson);

            // actDetails.json：让详情页刷新后看到申请状态变化
            const detailsJson = readJson("actDetails.json", {
              error: 0,
              data: { details: {} },
            });
            if (
              detailsJson.data?.details &&
              Number(detailsJson.data.details.id) === id
            ) {
              if (action === "cancel") {
                detailsJson.data.details.applyStatus = 0;
                detailsJson.data.details.canApply = true;
              } else {
                detailsJson.data.details.applyStatus = 1;
                detailsJson.data.details.canApply = false;
              }
              writeJson("actDetails.json", detailsJson);
            }

            // actList.json（可选）：列表 canApply 同步变化
            if (act) {
              const idx = (actList.data?.list || []).findIndex(
                (x) => Number(x.id) === id,
              );
              if (idx >= 0) {
                actList.data.list[idx].canApply = action === "cancel";
                writeJson("actList.json", actList);
              }
            }

            return ok(res);
          } catch {
            return send(res, { error: 1, msg: "Invalid JSON body" }, 400);
          }
        }

        // 3) 上传服务记录：写 serviceList + 联动积分文件
        if (
          pathname.startsWith("/api/act/uploadService") &&
          req.method === "POST"
        ) {
          try {
            const incoming = await readBodyJson(req);
            // 约定：时长字段可能叫 hour / duration / value
            const hour =
              Number(
                incoming.hour ?? incoming.duration ?? incoming.value ?? 0,
              ) || 0;

            // serviceList.json 结构：{data:{list:[{id,pic,content,publisher,time,status}]}}
            const sl = readJson("serviceList.json", {
              error: 0,
              data: { current: 1, pageSize: 10, pageCount: 1, list: [] },
            });
            const list = sl.data?.list || [];

            const nextId =
              list.reduce((m, x) => Math.max(m, Number(x.id) || 0), 0) + 1;

            const imgList = (incoming.fileList || []).map(item => item.url || item.content || incoming.pic || "./imgs/actImg.jpeg");

            list.unshift({
              id: nextId,
              pic: incoming.pic || "./imgs/actImg.jpeg",
              imgList,
              content: incoming.content || "新增服务记录",
              publisher: incoming.publisher || "未知来源",
              time: incoming.time || Date.now(),
              status: 1, // 1=通过？你 recordDetails.status=1，看起来是已审核/有效
              // 额外字段可保留（不影响页面）
              hour,
            });

            sl.data = sl.data || {};
            sl.data.list = list;
            sl.data.pageCount = 1;
            writeJson("serviceList.json", sl);

            // 同步更新积分（按 1小时=2分）
            if (hour > 0) addScore(hour);

            return ok(res);
          } catch {
            return send(res, { error: 1, msg: "Invalid JSON body" }, 400);
          }
        }

        next();
      });
    },
  };
}

export default defineConfig({
  base: "./",
  plugins: [vue(), mockPlugin(), VueDevTools()],
});
