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 || process.env.ADMIN_PASSWORD || "4rg0v14N";
}

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,
      debtEnabled: false,
      debtLimit: 0,
      fullAccessRequested: false,
      fullAccessRequestedAt: null,
      fullAccessGranted: false,
      fullAccessGrantedAt: null,
      fullAccessGrantedBy: null,
      fullAccessRevokedAt: null,
      fullAccessRevokedBy: null,
      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.debtEnabled === undefined) { r.debtEnabled = false; updated = true; }
        if (r.debtLimit === undefined) { r.debtLimit = 0; updated = true; }
        // Full-access migration
        if (r.fullAccessRequested === undefined) { r.fullAccessRequested = false; updated = true; }
        if (r.fullAccessRequestedAt === undefined) { r.fullAccessRequestedAt = null; updated = true; }
        if (r.fullAccessGranted === undefined) { r.fullAccessGranted = false; updated = true; }
        if (r.fullAccessGrantedAt === undefined) { r.fullAccessGrantedAt = null; updated = true; }
        if (r.fullAccessGrantedBy === undefined) { r.fullAccessGrantedBy = null; updated = true; }
        if (r.fullAccessRevokedAt === undefined) { r.fullAccessRevokedAt = null; updated = true; }
        if (r.fullAccessRevokedBy === undefined) { r.fullAccessRevokedBy = null; updated = true; }
        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,
      debtEnabled: reseller.debtEnabled ?? false,
      debtLimit: reseller.debtLimit ?? 0,
      fullAccessRequested: reseller.fullAccessRequested ?? false,
      fullAccessGranted: reseller.fullAccessGranted ?? false,
      fullAccessGrantedAt: reseller.fullAccessGrantedAt ?? null,
    };
  }
  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, debtEnabled = false, debtLimit = 0 }) {
  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),
    debtEnabled: Boolean(debtEnabled),
    debtLimit: parseFloat(debtLimit) || 0,
    fullAccessRequested: false,
    fullAccessRequestedAt: null,
    fullAccessGranted: false,
    fullAccessGrantedAt: null,
    fullAccessGrantedBy: null,
    fullAccessRevokedAt: null,
    fullAccessRevokedBy: null,
    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);
  }
  if (patch.debtEnabled !== undefined) {
    r.debtEnabled = Boolean(patch.debtEnabled);
  }
  if (patch.debtLimit !== undefined) {
    r.debtLimit = parseFloat(patch.debtLimit) || 0;
  }

  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];
    const currentBalance = r.balance || 0;
    const debtEnabled = r.debtEnabled === true;
    const debtLimit = r.debtLimit || 0;

    if (currentBalance < amount) {
      // If debt is not enabled, reject
      if (!debtEnabled) {
        return { ok: false, error: "Saldo deposit tidak mencukupi" };
      }
      // If debt is enabled, check against debt limit
      // Allowed negative: debtLimit (e.g. 500000 means balance can go to -500000)
      const afterDeduction = currentBalance - amount;
      if (Math.abs(afterDeduction) > debtLimit) {
        return { ok: false, error: `Saldo tidak mencukupi. Batas maksimal utang: Rp ${debtLimit.toLocaleString('id-ID')}. Dibutuhkan: Rp ${amount.toLocaleString('id-ID')}, Saldo saat ini: Rp ${currentBalance.toLocaleString('id-ID')}.` };
      }
    }

    r.balance = currentBalance - 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,
      isDebt: r.balance < 0,
      debtAmount: r.balance < 0 ? Math.abs(r.balance) : 0,
      debtLimit: debtEnabled ? debtLimit : 0,
      debtWarning: debtEnabled && r.balance < 0 && debtLimit > 0 && Math.abs(r.balance) >= debtLimit * 0.9,
    };
  }
  return { ok: false, error: "Reseller tidak ditemukan" };
}

// ═══ Full Access Management (Mitra ↔ Owner) ═══

// Mitra mengajukan permintaan akses penuh
export function requestFullAccess(resellerId) {
  const settings = getSettings();
  const idx = settings.resellers.findIndex((r) => r.id === resellerId);
  if (idx < 0) throw new Error("Reseller tidak ditemukan");

  const r = settings.resellers[idx];
  if (r.fullAccessGranted) {
    throw new Error("Anda sudah memiliki akses penuh yang aktif.");
  }
  if (r.fullAccessRequested) {
    throw new Error("Permintaan akses penuh sudah diajukan. Harap tunggu persetujuan owner.");
  }

  r.fullAccessRequested = true;
  r.fullAccessRequestedAt = new Date().toISOString();
  writeSettings(settings);
  return { ok: true, resellerId, name: r.name, requestedAt: r.fullAccessRequestedAt };
}

// Owner menyetujui akses penuh mitra
export function grantFullAccess(resellerId, approvedBy) {
  const settings = getSettings();
  const idx = settings.resellers.findIndex((r) => r.id === resellerId);
  if (idx < 0) throw new Error("Reseller tidak ditemukan");

  const r = settings.resellers[idx];
  if (r.fullAccessGranted && !r.fullAccessRevokedAt) {
    throw new Error("Mitra ini sudah memiliki akses penuh yang aktif.");
  }

  r.fullAccessRequested = false;
  r.fullAccessGranted = true;
  r.fullAccessGrantedAt = new Date().toISOString();
  r.fullAccessGrantedBy = approvedBy || "owner";
  r.fullAccessRevokedAt = null;
  r.fullAccessRevokedBy = null;
  writeSettings(settings);
  return { ok: true, resellerId, name: r.name, grantedAt: r.fullAccessGrantedAt, grantedBy: approvedBy };
}

// Owner mencabut akses penuh mitra
export function revokeFullAccess(resellerId, revokedBy) {
  const settings = getSettings();
  const idx = settings.resellers.findIndex((r) => r.id === resellerId);
  if (idx < 0) throw new Error("Reseller tidak ditemukan");

  const r = settings.resellers[idx];
  if (!r.fullAccessGranted) {
    throw new Error("Mitra ini tidak memiliki akses penuh yang aktif.");
  }

  r.fullAccessRequested = false;
  r.fullAccessGranted = false;
  r.fullAccessGrantedAt = null;
  r.fullAccessGrantedBy = null;
  r.fullAccessRevokedAt = new Date().toISOString();
  r.fullAccessRevokedBy = revokedBy || "owner";
  writeSettings(settings);
  return { ok: true, resellerId, name: r.name, revokedAt: r.fullAccessRevokedAt, revokedBy };
}

// Owner menolak permintaan akses penuh mitra
export function denyFullAccess(resellerId) {
  const settings = getSettings();
  const idx = settings.resellers.findIndex((r) => r.id === resellerId);
  if (idx < 0) throw new Error("Reseller tidak ditemukan");

  const r = settings.resellers[idx];
  if (!r.fullAccessRequested) {
    throw new Error("Tidak ada permintaan akses penuh yang tertunda.");
  }

  r.fullAccessRequested = false;
  r.fullAccessRequestedAt = null;
  writeSettings(settings);
  return { ok: true, resellerId, name: r.name, deniedAt: new Date().toISOString() };
}
