// File-based JSON store for member vouchers.
// Each voucher: { code, tier, addedAt }

import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const STORE_PATH = path.join(__dirname, "..", "data", "vouchers.json");

function ensureDir() {
  const dir = path.dirname(STORE_PATH);
  if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
}

function readAll() {
  ensureDir();
  if (!fs.existsSync(STORE_PATH)) return [];
  try {
    const list = JSON.parse(fs.readFileSync(STORE_PATH, "utf-8"));
    let migrated = false;
    for (const v of list) {
      if (v.tier !== "pro" && v.tier !== "vip") {
        v.tier = "pro";
        migrated = true;
      }
    }
    if (migrated) {
      fs.writeFileSync(STORE_PATH, JSON.stringify(list, null, 2));
    }
    return list;
  } catch {
    return [];
  }
}

function writeAll(list) {
  ensureDir();
  fs.writeFileSync(STORE_PATH, JSON.stringify(list, null, 2));
}

export function listVouchers() {
  return readAll();
}

export function addVoucher({ code, tier = "pro", whatsapp = "", duration = "1bulan", durationDays = 30, dailyLimit = 5, createdBy = "owner", createdByName = "Owner", pricePaid = 0, resellerCost = 0, commission = 0 }) {
  const cleanWhatsapp = whatsapp.trim();
  let cleanCode = code ? code.trim().toUpperCase() : "";

  if (!cleanCode) {
    if (!cleanWhatsapp) {
      throw new Error("Nomor Whatsapp Member wajib diisi jika Kode Voucher dikosongkan");
    }
    const digits = cleanWhatsapp.replace(/\D/g, "");
    if (digits.length < 5) {
      throw new Error("Nomor Whatsapp harus memiliki minimal 5 digit angka");
    }
    const last5 = digits.slice(-5);
    cleanCode = `TEKNO-${last5}`;
  }

  const list = readAll();
  if (list.some((v) => v.code === cleanCode)) {
    throw new Error(`Voucher "${cleanCode}" sudah terdaftar`);
  }

  // Calculate active period (expiresAt)
  let days = 30;
  if (duration === "custom") {
    days = parseInt(durationDays, 10);
    if (isNaN(days) || days <= 0) {
      throw new Error("Masa aktif (hari) harus berupa angka positif");
    }
  }
  const expiresAt = new Date(Date.now() + days * 24 * 60 * 60 * 1000).toISOString();

  // Validate daily limit
  const limit = parseInt(dailyLimit, 10);
  if (isNaN(limit) || limit <= 0) {
    throw new Error("Limit harian generate harus berupa angka positif");
  }

  const cleanTier = (tier === "vip") ? "vip" : "pro";
  const voucher = {
    code: cleanCode,
    tier: cleanTier,
    whatsapp: cleanWhatsapp,
    duration,
    durationDays: days,
    expiresAt,
    dailyLimit: limit,
    usage: {},
    addedAt: new Date().toISOString(),
    createdBy,
    createdByName,
    pricePaid: parseFloat(pricePaid) || 0,
    resellerCost: parseFloat(resellerCost) || 0,
    commission: parseFloat(commission) || 0,
  };

  list.push(voucher);
  writeAll(list);
  return voucher;
}

export function deleteVoucher(code) {
  const cleanCode = code.trim().toUpperCase();
  const list = readAll();
  const idx = list.findIndex((v) => v.code === cleanCode);
  if (idx < 0) return false;
  
  list.splice(idx, 1);
  writeAll(list);
  return true;
}

export function updateVoucher(code, patch) {
  const cleanCode = code.trim().toUpperCase();
  const list = readAll();
  const idx = list.findIndex((v) => v.code === cleanCode);
  if (idx < 0) throw new Error("Voucher tidak ditemukan");

  const v = list[idx];

  if (patch.tier !== undefined) {
    v.tier = (patch.tier === "vip") ? "vip" : "pro";
  }
  if (patch.whatsapp !== undefined) {
    v.whatsapp = patch.whatsapp.trim();
  }
  if (patch.dailyLimit !== undefined) {
    const limit = parseInt(patch.dailyLimit, 10);
    if (isNaN(limit) || limit <= 0) {
      throw new Error("Limit harian generate harus berupa angka positif");
    }
    v.dailyLimit = limit;
  }
  if (patch.expiresAt !== undefined) {
    const date = new Date(patch.expiresAt);
    if (isNaN(date.getTime())) {
      throw new Error("Tanggal kedaluwarsa tidak valid");
    }
    v.expiresAt = date.toISOString();
  }
  if (patch.pricePaid !== undefined) {
    v.pricePaid = parseFloat(patch.pricePaid) || 0;
  }
  if (patch.resellerCost !== undefined) {
    v.resellerCost = parseFloat(patch.resellerCost) || 0;
  }
  if (patch.commission !== undefined) {
    v.commission = parseFloat(patch.commission) || 0;
  }

  writeAll(list);
  return v;
}

export function validateVoucher(code) {
  if (!code) return { ok: false, error: "Kode voucher harus diisi" };
  const cleanCode = code.trim().toUpperCase();
  const list = readAll();
  const voucher = list.find((v) => v.code === cleanCode);
  
  if (!voucher) {
    return { ok: false, error: "Kode voucher tidak valid" };
  }
  
  // Check active period
  if (voucher.expiresAt && Date.now() > new Date(voucher.expiresAt).getTime()) {
    return { ok: false, error: "Masa aktif voucher sudah habis (expired)" };
  }
  
  return { ok: true, tier: voucher.tier, voucher };
}

export function hasBatchRecord(code, batchId) {
  if (!batchId) return false;
  const cleanCode = code.trim().toUpperCase();
  const list = readAll();
  const v = list.find((x) => x.code === cleanCode);
  return v && v.usedBatches && v.usedBatches.includes(batchId);
}

export function incrementUsage(code, batchId = null) {
  const cleanCode = code.trim().toUpperCase();
  const list = readAll();
  const idx = list.findIndex((v) => v.code === cleanCode);
  if (idx >= 0) {
    const todayStr = new Date().toISOString().split("T")[0];
    if (!list[idx].usage) list[idx].usage = {};

    if (batchId) {
      if (!list[idx].usedBatches) list[idx].usedBatches = [];
      if (list[idx].usedBatches.includes(batchId)) {
        return true; // Already counted
      }
      list[idx].usedBatches.push(batchId);
    }

    list[idx].usage[todayStr] = (list[idx].usage[todayStr] || 0) + 1;
    writeAll(list);
    return true;
  }
  return false;
}
