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

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

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

// ─── Password hashing (SHA-256, non-reversible) ─────────────────────────────
export function hashPassword(pw) {
  return crypto.createHash("sha256").update(pw).digest("hex");
}

function isHashed(str) {
  return typeof str === "string" && /^[a-f0-9]{64}$/i.test(str);
}

// Owner password: prefer env var, fallback to legacy hardcoded
export function getOwnerPassword() {
  return process.env.OWNER_PASSWORD || "4rg0v14N";
}

// Default iCloud email generator base URL
// Bisa di-override via env ICLOUD_BASE_URL atau dari settings store
export const DEFAULT_ICLOUD_BASE_URL = "https://icloud.texaproject.com/";

/**
 * Get iCloud email generator base URL with precedence:
 * 1. settings.icloudBaseUrl (custom dari admin panel)
 * 2. env ICLOUD_BASE_URL
 * 3. DEFAULT_ICLOUD_BASE_URL
 * Selalu return string yang di-trim + normalize (tidak ada trailing slash double).
 */
export function getIcloudBaseUrl() {
  try {
    const s = getSettings();
    if (s && typeof s.icloudBaseUrl === "string" && s.icloudBaseUrl.trim()) {
      return normalizeUrl(s.icloudBaseUrl);
    }
  } catch {}
  if (process.env.ICLOUD_BASE_URL && process.env.ICLOUD_BASE_URL.trim()) {
    return normalizeUrl(process.env.ICLOUD_BASE_URL);
  }
  return DEFAULT_ICLOUD_BASE_URL;
}

/**
 * Validate URL format (https?://...).
 * Return { ok, normalized, error }.
 */
export function validateIcloudBaseUrl(rawUrl) {
  if (typeof rawUrl !== "string" || !rawUrl.trim()) {
    return { ok: false, error: "URL tidak boleh kosong" };
  }
  const trimmed = rawUrl.trim();
  let parsed;
  try {
    parsed = new URL(trimmed);
  } catch {
    return { ok: false, error: "Format URL tidak valid. Contoh yang valid: https://icloud.studiolabs.web.id/" };
  }
  if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
    return { ok: false, error: "URL harus menggunakan protokol http:// atau https://" };
  }
  if (!parsed.hostname || !parsed.hostname.includes(".")) {
    return { ok: false, error: "URL harus memiliki hostname yang valid (contoh: icloud.studiolabs.web.id)" };
  }
  return { ok: true, normalized: normalizeUrl(trimmed) };
}

function normalizeUrl(u) {
  let s = String(u).trim();
  // Hapus trailing slash berlebih, pastikan single trailing slash
  s = s.replace(/\/+$/, "");
  return s + "/";
}

/**
 * Set custom iCloud base URL di settings.
 * Validasi URL terlebih dahulu. Return normalized URL atau throw error.
 */
export function setIcloudBaseUrl(rawUrl) {
  const v = validateIcloudBaseUrl(rawUrl);
  if (!v.ok) throw new Error(v.error);
  const settings = getSettings();
  settings.icloudBaseUrl = v.normalized;
  writeSettings(settings);
  return v.normalized;
}

/**
 * Reset ke default URL (hapus custom).
 */
export function resetIcloudBaseUrl() {
  const settings = getSettings();
  delete settings.icloudBaseUrl;
  writeSettings(settings);
  return DEFAULT_ICLOUD_BASE_URL;
}

const DEFAULT_SETTINGS = (() => {
  const defaultKasirHash = hashPassword("kasir123");
  const defaultResellerHash = hashPassword("mitra123");
  return {
  kasirPassword: defaultKasirHash,
  prices: {
    proPrice: 300000,
    resellerPrice: 150000,
    vipPrice: 500000,
    resellerVipPrice: 250000,
  },
  maintenance: {
    active: false,
    title: "Server Sedang Pemeliharaan",
    description: "Kami sedang melakukan peningkatan sistem. Generator diistirahatkan sementara untuk memastikan kestabilan layanan.",
    reason: "Pemeliharaan sistem berkala",
    duration: "1 jam",
    expiresAt: null
  },
  resellers: [
    {
      id: "mitra_default",
      name: "Mitra Reseller Default",
      password: defaultResellerHash,
      quota: 10,
      balance: 1000000,
      totalCommission: 0,
      customResellerPrice: null,
      customSrp: null,
      customResellerVipPrice: null,
      customVipSrp: null,
      allowBot: true,
      allowPool: true,
      allowArchive: true,
      addedAt: new Date().toISOString(),
    }
  ]
};
})();

export function getSettings() {
  ensureDir();
  if (!fs.existsSync(STORE_PATH)) {
    writeSettings(DEFAULT_SETTINGS);
    return DEFAULT_SETTINGS;
  }
  try {
    const data = JSON.parse(fs.readFileSync(STORE_PATH, "utf-8"));
    // Enforce default keys if missing
    let updated = false;
    if (data.kasirPassword === undefined) {
      data.kasirPassword = hashPassword("kasir123");
      updated = true;
    } else if (!isHashed(data.kasirPassword)) {
      // Auto-migrate plaintext to hash
      data.kasirPassword = hashPassword(data.kasirPassword);
      updated = true;
    }
    if (data.prices === undefined) {
      data.prices = { proPrice: 300000, resellerPrice: 150000, vipPrice: 500000, resellerVipPrice: 250000 };
      updated = true;
    } else {
      if (data.prices.vipPrice === undefined) { data.prices.vipPrice = 500000; updated = true; }
      if (data.prices.resellerVipPrice === undefined) { data.prices.resellerVipPrice = 250000; updated = true; }
    }
    if (data.maintenance === undefined) {
      data.maintenance = {
        active: false,
        title: "Server Sedang Pemeliharaan",
        description: "Kami sedang melakukan peningkatan sistem. Generator diistirahatkan sementara untuk memastikan kestabilan layanan.",
        reason: "Pemeliharaan sistem berkala",
        duration: "1 jam",
        expiresAt: null
      };
      updated = true;
    } else {
      if (data.maintenance.title === undefined) {
        data.maintenance.title = "Server Sedang Pemeliharaan";
        updated = true;
      }
      if (data.maintenance.description === undefined) {
        data.maintenance.description = "Kami sedang melakukan peningkatan sistem. Generator diistirahatkan sementara untuk memastikan kestabilan layanan.";
        updated = true;
      }
    }
    if (data.resellers === undefined) { 
      data.resellers = DEFAULT_SETTINGS.resellers; 
      updated = true; 
    } else {
      // Migrate existing resellers to have new defaults and hashed passwords
      for (const r of data.resellers) {
        if (r.allowBot === undefined) { r.allowBot = true; updated = true; }
        if (r.allowPool === undefined) { r.allowPool = true; updated = true; }
        if (r.allowArchive === undefined) { r.allowArchive = true; updated = true; }
        if (r.balance === undefined) { r.balance = 0; updated = true; }
        if (r.totalCommission === undefined) { r.totalCommission = 0; updated = true; }
        if (r.customResellerPrice === undefined) { r.customResellerPrice = null; updated = true; }
        if (r.customSrp === undefined) { r.customSrp = null; updated = true; }
        if (r.customResellerVipPrice === undefined) { r.customResellerVipPrice = null; updated = true; }
        if (r.customVipSrp === undefined) { r.customVipSrp = null; updated = true; }
        // Auto-migrate plaintext password to hash
        if (r.password && !isHashed(r.password)) {
          r.password = hashPassword(r.password);
          updated = true;
        }
      }
    }
    if (updated) writeSettings(data);
    return data;
  } catch {
    return DEFAULT_SETTINGS;
  }
}

export function writeSettings(settings) {
  ensureDir();
  fs.writeFileSync(STORE_PATH, JSON.stringify(settings, null, 2), "utf-8");
  return settings;
}

export function validateLogin(password) {
  if (!password) return { ok: false };

  const ownerPass = getOwnerPassword();
  if (password === ownerPass) {
    return { ok: true, role: "owner" };
  }

  const settings = getSettings();
  const hashedInput = hashPassword(password);

  if (hashedInput === settings.kasirPassword) {
    return { ok: true, role: "kasir" };
  }
  const reseller = settings.resellers.find((r) => r.password === hashedInput);
  if (reseller) {
    return {
      ok: true,
      role: "mitra",
      resellerId: reseller.id,
      resellerName: reseller.name,
      quota: reseller.quota,
      balance: reseller.balance ?? 0,
      totalCommission: reseller.totalCommission ?? 0,
      customResellerPrice: reseller.customResellerPrice ?? null,
      customSrp: reseller.customSrp ?? null,
      customResellerVipPrice: reseller.customResellerVipPrice ?? null,
      customVipSrp: reseller.customVipSrp ?? null,
      allowBot: reseller.allowBot ?? true,
      allowPool: reseller.allowPool ?? true,
      allowArchive: reseller.allowArchive ?? true,
    };
  }
  return { ok: false };
}

export function addReseller({ name, password, quota = 10, balance = 0, customResellerPrice = null, customSrp = null, customResellerVipPrice = null, customVipSrp = null, allowBot = true, allowPool = true, allowArchive = true }) {
  const settings = getSettings();
  const cleanName = name.trim();
  const cleanPassword = password.trim();

  if (!cleanName || !cleanPassword) {
    throw new Error("Nama dan password reseller wajib diisi");
  }

  const ownerPass = getOwnerPassword();
  const hashedOwner = hashPassword(ownerPass);
  const hashedKasir = settings.kasirPassword;
  const hashedNew = hashPassword(cleanPassword);

  if (hashedNew === hashedOwner || hashedNew === hashedKasir) {
    throw new Error("Password tidak boleh sama dengan Owner atau Kasir");
  }
  if (settings.resellers.some((r) => r.password === hashedNew)) {
    throw new Error("Password ini sudah digunakan oleh reseller lain");
  }

  const newReseller = {
    id: "mitra_" + Math.random().toString(36).slice(2, 9),
    name: cleanName,
    password: hashedNew,
    quota: parseInt(quota, 10) || 0,
    balance: parseFloat(balance) || 0,
    totalCommission: 0,
    customResellerPrice: customResellerPrice !== null && customResellerPrice !== "" ? parseFloat(customResellerPrice) : null,
    customSrp: customSrp !== null && customSrp !== "" ? parseFloat(customSrp) : null,
    customResellerVipPrice: customResellerVipPrice !== null && customResellerVipPrice !== "" ? parseFloat(customResellerVipPrice) : null,
    customVipSrp: customVipSrp !== null && customVipSrp !== "" ? parseFloat(customVipSrp) : null,
    allowBot: Boolean(allowBot),
    allowPool: Boolean(allowPool),
    allowArchive: Boolean(allowArchive),
    addedAt: new Date().toISOString(),
  };

  settings.resellers.push(newReseller);
  writeSettings(settings);
  return newReseller;
}

export function updateReseller(id, patch) {
  const settings = getSettings();
  const idx = settings.resellers.findIndex((r) => r.id === id);
  if (idx < 0) throw new Error("Reseller tidak ditemukan");

  const r = settings.resellers[idx];
  if (patch.name !== undefined) r.name = patch.name.trim();
  if (patch.password !== undefined) {
    const pw = patch.password.trim();
    if (pw) {
      const ownerPass = getOwnerPassword();
      const hashedOwner = hashPassword(ownerPass);
      const hashedKasir = settings.kasirPassword;
      const hashedNew = hashPassword(pw);

      if (hashedNew === hashedOwner || hashedNew === hashedKasir) {
        throw new Error("Password tidak boleh sama dengan Owner atau Kasir");
      }
      if (settings.resellers.some((x) => x.id !== id && x.password === hashedNew)) {
        throw new Error("Password ini sudah digunakan oleh reseller lain");
      }
      r.password = hashedNew;
    }
  }
  if (patch.quota !== undefined) {
    r.quota = parseInt(patch.quota, 10) || 0;
  }
  if (patch.balance !== undefined) {
    r.balance = parseFloat(patch.balance) || 0;
  }
  if (patch.customResellerPrice !== undefined) {
    r.customResellerPrice = patch.customResellerPrice !== null && patch.customResellerPrice !== "" ? parseFloat(patch.customResellerPrice) : null;
  }
  if (patch.customSrp !== undefined) {
    r.customSrp = patch.customSrp !== null && patch.customSrp !== "" ? parseFloat(patch.customSrp) : null;
  }
  if (patch.customResellerVipPrice !== undefined) {
    r.customResellerVipPrice = patch.customResellerVipPrice !== null && patch.customResellerVipPrice !== "" ? parseFloat(patch.customResellerVipPrice) : null;
  }
  if (patch.customVipSrp !== undefined) {
    r.customVipSrp = patch.customVipSrp !== null && patch.customVipSrp !== "" ? parseFloat(patch.customVipSrp) : null;
  }
  if (patch.allowBot !== undefined) {
    r.allowBot = Boolean(patch.allowBot);
  }
  if (patch.allowPool !== undefined) {
    r.allowPool = Boolean(patch.allowPool);
  }
  if (patch.allowArchive !== undefined) {
    r.allowArchive = Boolean(patch.allowArchive);
  }

  writeSettings(settings);
  return r;
}

export function deleteReseller(id) {
  const settings = getSettings();
  const idx = settings.resellers.findIndex((r) => r.id === id);
  if (idx < 0) return false;

  settings.resellers.splice(idx, 1);
  writeSettings(settings);
  return true;
}

export function decrementResellerQuota(id) {
  const settings = getSettings();
  const idx = settings.resellers.findIndex((r) => r.id === id);
  if (idx >= 0) {
    if (settings.resellers[idx].quota > 0) {
      settings.resellers[idx].quota -= 1;
      writeSettings(settings);
      return true;
    }
    return false; // Out of quota
  }
  return false;
}

export function deductResellerBalance(id, amount, pricePaid) {
  const settings = getSettings();
  const idx = settings.resellers.findIndex((r) => r.id === id);
  if (idx >= 0) {
    const r = settings.resellers[idx];
    if ((r.balance || 0) < amount) {
      return { ok: false, error: "Saldo deposit tidak mencukupi" };
    }
    r.balance = (r.balance || 0) - amount;
    
    // Calculate commission: customer pricePaid - reseller cost (amount)
    const commission = Math.max(0, pricePaid - amount);
    r.totalCommission = (r.totalCommission || 0) + commission;
    
    writeSettings(settings);
    return { ok: true, balance: r.balance, totalCommission: r.totalCommission, commission };
  }
  return { ok: false, error: "Reseller tidak ditemukan" };
}
