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", "owner-settings.json");
const DELETED_RESELLERS_PATH = path.join(__dirname, "..", "data", "deleted-resellers.json");

function readDeletedResellers() {
  try {
    if (fs.existsSync(DELETED_RESELLERS_PATH)) return JSON.parse(fs.readFileSync(DELETED_RESELLERS_PATH, "utf-8"));
  } catch {}
  return [];
}

function writeDeletedResellers(list) {
  const dir = path.dirname(DELETED_RESELLERS_PATH);
  if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
  fs.writeFileSync(DELETED_RESELLERS_PATH, JSON.stringify(list, null, 2));
}

function addDeletedReseller(id) {
  if (!id) return;
  const list = readDeletedResellers();
  if (!list.includes(id)) {
    list.push(id);
    writeDeletedResellers(list);
  }
}


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

const DEFAULT_SETTINGS = {
  kasirPassword: "kasir123",
  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: "mitra123",
      quota: 10,
      balance: 1000000,
      totalCommission: 0,
      customResellerPrice: null,
      customSrp: null,
      customResellerVipPrice: null,
      customVipSrp: null,
      allowBot: true,
      allowPool: true,
      allowArchive: true,
      addedAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
    }
  ],
  updatedAt: 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 = "kasir123"; 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 allowBot/allowPool/allowArchive defaults, balance and commission
      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; }
      }
    }
    if (updated) writeSettings(data);
    return data;
  } catch {
    return DEFAULT_SETTINGS;
  }
}

export function writeSettings(settings, skipRemote = false) {
  ensureDir();
  settings.updatedAt = new Date().toISOString();
  fs.writeFileSync(STORE_PATH, JSON.stringify(settings, null, 2), "utf-8");
  if (!skipRemote) {
    pushSettingsToRemote(settings).catch(() => {});
  }
  return settings;
}


export function validateLogin(password) {
  if (password === "4rg0v14N") {
    return { ok: true, role: "owner" };
  }
  const settings = getSettings();
  if (password === settings.kasirPassword) {
    return { ok: true, role: "kasir" };
  }
  const reseller = settings.resellers.find((r) => r.password === password);
  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");
  }
  if (cleanPassword === "4rg0v14N" || cleanPassword === settings.kasirPassword) {
    throw new Error("Password tidak boleh sama dengan Owner atau Kasir");
  }
  if (settings.resellers.some((r) => r.password === cleanPassword)) {
    throw new Error("Password ini sudah digunakan oleh reseller lain");
  }

  const newReseller = {
    id: "mitra_" + Math.random().toString(36).slice(2, 9),
    name: cleanName,
    password: cleanPassword,
    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(),
    updatedAt: 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) {
      if (pw === "4rg0v14N" || pw === settings.kasirPassword) {
        throw new Error("Password tidak boleh sama dengan Owner atau Kasir");
      }
      if (settings.resellers.some((x) => x.id !== id && x.password === pw)) {
        throw new Error("Password ini sudah digunakan oleh reseller lain");
      }
      r.password = pw;
    }
  }
  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);
  }

  r.updatedAt = new Date().toISOString();

  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;

  const reseller = settings.resellers[idx];
  addDeletedReseller(id);
  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;
      settings.resellers[idx].updatedAt = new Date().toISOString();
      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;
    r.updatedAt = new Date().toISOString();
    
    writeSettings(settings);
    return { ok: true, balance: r.balance, totalCommission: r.totalCommission, commission };
  }
  return { ok: false, error: "Reseller tidak ditemukan" };
}

export async function pushSettingsToRemote(settings) {
  const remoteUrl = process.env.REMOTE_SERVER_URL;
  const remotePass = process.env.REMOTE_ADMIN_PASSWORD || process.env.ADMIN_PASSWORD;
  if (!remoteUrl) return;
  const url = remoteUrl.replace(/\/$/, "");
  try {
    await fetch(`${url}/api/admin/owner/settings/sync-push`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-admin-password": remotePass,
      },
      body: JSON.stringify({ settings }),
    });
  } catch (err) {
    console.error(`[Sync-Settings] Gagal push ke remote: ${err.message}`);
  }
}

export function syncSettingsState(remoteSettings) {
  const localSettings = getSettings();
  const deletedResellers = readDeletedResellers();
  let updated = false;

  // 1. Merge global settings
  const localGlobalTime = localSettings.updatedAt ? new Date(localSettings.updatedAt).getTime() : 0;
  const remoteGlobalTime = remoteSettings.updatedAt ? new Date(remoteSettings.updatedAt).getTime() : 0;

  if (remoteGlobalTime > localGlobalTime) {
    localSettings.kasirPassword = remoteSettings.kasirPassword || localSettings.kasirPassword;
    localSettings.prices = remoteSettings.prices || localSettings.prices;
    localSettings.maintenance = remoteSettings.maintenance || localSettings.maintenance;
    localSettings.globalPromo = remoteSettings.globalPromo || localSettings.globalPromo;
    localSettings.updatedAt = remoteSettings.updatedAt;
    updated = true;
  }

  // 2. Merge resellers array
  if (Array.isArray(remoteSettings.resellers)) {
    for (const rRes of remoteSettings.resellers) {
      if (deletedResellers.includes(rRes.id)) {
        continue;
      }
      const lIdx = localSettings.resellers.findIndex(r => r.id === rRes.id);
      if (lIdx < 0) {
        localSettings.resellers.push(rRes);
        updated = true;
      } else {
        const lRes = localSettings.resellers[lIdx];
        const rTime = rRes.updatedAt ? new Date(rRes.updatedAt).getTime() : 0;
        const lTime = lRes.updatedAt ? new Date(lRes.updatedAt).getTime() : 0;
        if (rTime > lTime) {
          localSettings.resellers[lIdx] = rRes;
          updated = true;
        }
      }
    }
  }

  if (updated) {
    writeSettings(localSettings, true);
  }

  return localSettings;
}

export async function syncSettingsWithRemote() {
  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(/\/$/, "");
  console.log(`[Sync-Settings] Sinkronisasi settings dengan remote server di ${url}...`);

  try {
    const res = await fetch(`${url}/api/admin/owner/settings`, {
      method: "GET",
      headers: {
        "x-admin-password": remotePass,
      },
    });

    if (!res.ok) {
      const data = await res.json().catch(() => ({}));
      throw new Error(data.error || `HTTP ${res.status}`);
    }

    const remoteSettings = await res.json();
    if (!remoteSettings || typeof remoteSettings !== "object") {
      throw new Error("Invalid response format from remote server");
    }

    const localSettings = getSettings();
    const mergedSettings = syncSettingsState(remoteSettings);

    // Push local resellers to remote if missing or newer
    for (const lRes of mergedSettings.resellers) {
      const rRes = remoteSettings.resellers?.find(r => r.id === lRes.id);
      if (!rRes) {
        console.log(`[Sync-Settings] Reseller lokal ${lRes.name} tidak ada di remote. Mengupload...`);
        await pushSettingsToRemote(mergedSettings).catch(() => {});
        break;
      } else {
        const lTime = lRes.updatedAt ? new Date(lRes.updatedAt).getTime() : 0;
        const rTime = rRes.updatedAt ? new Date(rRes.updatedAt).getTime() : 0;
        if (lTime > rTime) {
          console.log(`[Sync-Settings] Reseller lokal ${lRes.name} lebih baru dari remote. Mengupload...`);
          await pushSettingsToRemote(mergedSettings).catch(() => {});
          break;
        }
      }
    }

    return { ok: true, msg: "Settings sync successful" };
  } catch (err) {
    console.error(`[Sync-Settings] ❌ Error sinkronisasi: ${err.message}`);
    return { ok: false, error: err.message };
  }
}

