import express from "express";
import fs from "fs";
import bodyParser from "body-parser";
import cors from "cors";
import axios from "axios";
import path from "path";
import _ from "lodash";

import dotenv from "dotenv";

dotenv.config();

const metaPath = path.join(process.cwd(), "meta.json");
const dataFile = "data.json";
const cachePrefix = "product-cache-";
const productsFile = path.join(process.cwd(), "products.json");
const app = express();

// Cho phép tất cả origin gọi API
app.use(cors());

app.use(express.json({ limit: "10mb" }));
// parse JSON body
app.use(bodyParser.json());

// POST thêm product (tự động update nếu id đã tồn tại)
app.post("/products", (req, res) => {
  const { id, ...rest } = req.body;
  if (!id) return res.status(400).json({ error: "Product must have an id" });

  // Đọc dữ liệu cũ (nếu có)
  let data = {};
  if (fs.existsSync(productsFile)) {
    data = JSON.parse(fs.readFileSync(productsFile, "utf8") || "{}");
  }

  // Thêm / ghi đè theo id
  data[id] = { id, ...rest };

  // Ghi lại file
  fs.writeFileSync(productsFile, JSON.stringify(data, null, 2));

  res.json({ success: true, product: data[id] });
});

// GET product theo id
app.get("/products/:id", (req, res) => {
  if (!fs.existsSync(productsFile)) return res.json({});
  const data = JSON.parse(fs.readFileSync(productsFile, "utf8") || "{}");
  res.json(data[req.params.id] || null);
});

// API lưu dữ liệu
app.post("/sync", (req, res) => {
  const data = req.body;

  if (!Array.isArray(data)) {
    return res.status(400).json({ error: "Dữ liệu phải là array" });
  }

  // Chuẩn hoá dữ liệu (có thêm date)
  const mapped = data.map((item) => ({
    ...item,
    date: new Date().toISOString(),
  }));

  // Đọc dữ liệu cũ
  let oldData = [];
  try {
    oldData = JSON.parse(fs.readFileSync(dataFile, "utf-8"));
  } catch (e) {
    oldData = [];
  }

  // So sánh (bỏ qua field date vì nó luôn khác)
  const stripDate = (arr) => arr.map(({ date, ...rest }) => rest);

  const oldStripped = stripDate(oldData);
  const newStripped = stripDate(mapped);

  if (!_.isEqual(oldStripped, newStripped)) {
    // Nếu khác → xoá cache
    const files = fs.readdirSync(".");
    files.forEach((file) => {
      if (file.startsWith(cachePrefix)) {
        fs.unlinkSync(path.join(".", file));
      }
    });
    console.log("Dữ liệu thay đổi → xoá cache");
  } else {
    console.log("Dữ liệu không đổi → giữ cache");
  }

  // Ghi dữ liệu mới
  fs.writeFileSync(dataFile, JSON.stringify(mapped, null, 2));

  res.json({ message: "Đã lưu dữ liệu thành công", saved: mapped.length });
});

// API đọc lại dữ liệu
app.get("/data", (req, res) => {
  if (!fs.existsSync("data.json")) {
    return res.json([]);
  }
  const content = fs.readFileSync("data.json", "utf-8");
  res.json(JSON.parse(content));
});

app.post("/", async (req, res) => {
  try {
    // ===== Helpers =====
    const readJSON = (path, fallback = null) => {
      try {
        return JSON.parse(fs.readFileSync(path, "utf-8"));
      } catch {
        return fallback;
      }
    };
    const writeJSON = (path, data) => {
      try {
        fs.writeFileSync(path, JSON.stringify(data, null, 2));
      } catch (e) {
        console.warn("Không ghi được file:", e.message);
      }
    };

    // ===== Meta =====
    let meta = readJSON(metaPath, { total: 4000 });

    const { info, ...filter } = req.body?.filter || {};
    const originalFilter = { ...filter };
    const status = filter?.where?.status_listing;

    if (["listed", "unlisted"].includes(status)) {
      filter.skip = 0;
    }

    // ===== Cache check =====
    const cacheFile = `${cachePrefix}${JSON.stringify(originalFilter)}.json`;
    if (fs.existsSync(cacheFile)) {
      return res.json(readJSON(cacheFile, {}));
    }

    // ===== Load publisted data nếu cần =====
    let publistedData = [];
    if (status && meta.total) {
      filter.limit = meta.total;
      publistedData = readJSON("data.json", []);
    }

    // ===== Call API gốc =====
    const { data } = await axios({
      headers: { Authorization: req.headers.authorization },
      url: "transferGetData",
      baseURL: process.env.BASE_URL,
      method: "POST",
      data: { ...req.body, filter },
    });

    // Update meta
    if (typeof data.total === "number") {
      writeJSON(metaPath, { total: data.total });
    }

    // ===== Xử lý listed/unlisted =====
    if (status === "listed" || status === "unlisted") {
      const skip = originalFilter.skip || 0;
      const limit = originalFilter.limit || data.data.length;

      let filteredData = data.data.filter((item) => {
        const key = item?.title.includes(item.code)
          ? `${item.title}`.toLowerCase()
          : `${item.title} - ${item.code}`.toLowerCase();

        if (status === "listed") {
          return publistedData.some(
            (i) =>
              `${i.title}`.toLowerCase().includes(key) &&
              i?.url_info == info?.url
          );
        } else {
          return !publistedData.some(
            (i) =>
              `${i.title}`.toLowerCase().includes(key) &&
              i?.url_info == info?.url
          );
        }
      });

      data.total = filteredData.length;
      data.data = filteredData.slice(skip, skip + limit);
      data.filter = { ...originalFilter, skip, limit };

      writeJSON(cacheFile, data);
    }

    res.json(data);
  } catch (err) {
    console.error("API error:", err.message);
    res.status(500).json({ error: err.message });
  }
});

// Route trả về privacy policy
app.get("/policy", (req, res) => {
  res.sendFile(path.join(process.cwd(), "views", "policy.html"));
});

app.listen(3000, () => {
  console.log("Server chạy tại http://localhost:3000");
});
