// 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 [];
  }
}

// Migration: perbaiki createdBy dari "owner" / "mitra" / "kasir" string
// menjadi resellerId yang sebenarnya dari owner-settings (jika mitra).
export function migrateCreatedBy() {
  const list = readAll();
  let updated = false;
  for (const v of list) {
    if (v.createdBy && (v.createdBy.startsWith("mitra_") || v.createdBy === "owner" || v.createdBy === "kasir")) continue;
    const name = (v.createdByName || "").trim();
    if (!name) continue;
    try {
      const settingsPath = path.join(__dirname, "owner-settings-store.js");
      import(settingsPath).then(mod => {
        const settings = mod.getSettings();
        const found = settings.resellers.find(r =>
          r.name && r.name.toLowerCase() === name.toLowerCase()
        );
        if (found) {
          v.createdBy = found.id;
          v.createdByName = found.name;
          writeAll(list);
        }
      }).catch(() => {});
    } catch { /* ignore */ }
  }
  return { updated, total: list.length };
}

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 async function syncFromRemote() {
  const remoteUrl = process.env.REMOTE_SERVER_URL;
  const remotePass = process.env.REMOTE_ADMIN_PASSWORD || process.env.ADMIN_PASSWORD;
  if (!remoteUrl) return { ok: false, error: "REMOTE_SERVER_URL not configured" };

  const url = remoteUrl.replace(/\/$/, "");
  try {
    const res = await fetch(`${url}/api/admin/vouchers`, {
      method: "GET",
      headers: { "x-admin-password": remotePass },
    });
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    const { vouchers: remoteList } = await res.json();
    if (!Array.isArray(remoteList)) throw new Error("Invalid response format");

    const localList = readAll();
    let added = 0, updated = 0;

    for (const rV of remoteList) {
      const idx = localList.findIndex(v => v.code === rV.code);
      if (idx < 0) {
        localList.push({ ...rV });
        added++;
      } else {
        localList[idx] = { ...localList[idx], ...rV };
        updated++;
      }
    }
    writeAll(localList);
    return { ok: true, added, updated, total: remoteList.length };
  } catch (e) {
    return { ok: false, error: e.message };
  }
}

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;
}

// ═══════════════════════════════════════════
// TRIAL VOUCHER SYSTEM
// ═══════════════════════════════════════════

const TRIAL_DURATION_DAYS = 1;
const MAX_TRIAL_PER_USER = 5;

/**
 * Hitung jumlah trial voucher yang sudah dibuat oleh creator tertentu
 */
export function getTrialCount(createdBy) {
  const list = readAll();
  return list.filter(v => v.isTrial === true && v.createdBy === createdBy).length;
}

/**
 * Cek sisa kuota trial untuk creator tertentu
 */
export function getTrialQuota(createdBy) {
  return Math.max(0, MAX_TRIAL_PER_USER - getTrialCount(createdBy));
}

/**
 * Generate kode trial otomatis: TRIAL-{random 5}
 */
function generateTrialCode() {
  const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
  let random = "";
  for (let i = 0; i < 5; i++) {
    random += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return `TRIAL-${random}`;
}

/**
 * Buat trial voucher baru
 * @param {Object} params
 * @param {string} params.createdBy - owner / resellerId mitra
 * @param {string} params.createdByName - nama pembuat
 * @param {string} [params.customName] - nama kustom (opsional, untuk mode kustom)
 */
export function addTrialVoucher({ createdBy, createdByName, customName = null }) {
  const list = readAll();
  const trialCount = list.filter(v => v.isTrial === true && v.createdBy === createdBy).length;

  if (trialCount >= MAX_TRIAL_PER_USER) {
    throw new Error(`Batas kuota trial (${MAX_TRIAL_PER_USER}x) sudah habis. Tidak dapat membuat trial voucher lagi.`);
  }

  // Generate unique code
  let code;
  let attempts = 0;
  do {
    code = generateTrialCode();
    attempts++;
    if (attempts > 50) {
      throw new Error("Gagal generate kode trial unik, coba lagi.");
    }
  } while (list.some(v => v.code === code));

  // Nama voucher: custom name atau auto
  const voucherName = (customName || "").trim() || `Trial Member #${trialCount + 1}`;

  // Durasi: fixed 1 hari
  const days = TRIAL_DURATION_DAYS;
  const expiresAt = new Date(Date.now() + days * 24 * 60 * 60 * 1000).toISOString();

  const voucher = {
    code,
    tier: "pro", // trial selalu pro (standard)
    whatsapp: "",
    duration: "custom",
    durationDays: days,
    expiresAt,
    dailyLimit: 3, // trial: 3 generate/hari
    usage: {},
    addedAt: new Date().toISOString(),
    createdBy,
    createdByName,
    pricePaid: 0,
    resellerCost: 0,
    commission: 0,
    isTrial: true,
    trialName: voucherName,
    trialNumber: trialCount + 1,
  };

  list.push(voucher);
  writeAll(list);
  return {
    voucher,
    remainingQuota: MAX_TRIAL_PER_USER - (trialCount + 1),
    totalUsed: trialCount + 1,
  };
}
