const fs = require("fs");
const path = require("path");
const { getSirayaDataRoot, ensureDir } = require("../paths");

const RECEIPT_KINDS = [
  "customer_receipt",
  "kitchen_ticket",
  "packing_slip",
  "delivery_receipt",
  "invoice_receipt",
];

function buildStandardTemplate(id, name, overrides = {}) {
  return {
    id,
    name,
    version: 2,
    receiptKind: overrides.receiptKind || "customer_receipt",
    paperWidth: 32,
    margins: { left: 0, right: 0 },
    business: {
      showLogo: false,
      showBranch: true,
      showAddress: true,
      showPhone: true,
      showWhatsapp: false,
      showWebsite: true,
      showNtn: false,
      showStrn: false,
      showTaxInfo: false,
    },
    branding: {
      logoPath: "",
      logoScale: 100,
      showPoweredBy: true,
      qrCode: { enabled: false, linkUrl: "", links: [], customText: "" },
      socialLinks: [],
      footerMessage: "Thank you for your order!",
      thankYouMessage: "Please visit again!",
    },
    sections: {
      header: true,
      orderMeta: true,
      items: true,
      totals: true,
      discount: true,
      tax: true,
      loyalty: true,
      payment: true,
      customer: true,
      cashier: true,
      notes: true,
      fbr: false,
      footer: true,
    },
    visual: {
      titleSize: "large",
      fontFamily: "default",
      currencyPrefix: "Rs ",
      dividerStyle: "dash",
      itemLayout: "standard",
      alignment: { header: "center", body: "left", footer: "center" },
    },
    conditionals: {
      showTaxDetails: true,
      showCustomerInfo: true,
      showCashierInfo: false,
      showQrCode: false,
      showLogo: false,
      showTableNumber: false,
      showOrderNotes: true,
      showOrderTime: true,
      showSubtotalLine: true,
      showTaxLine: true,
      showDiscountLine: true,
      showDiscountPercent: false,
      showPackingLine: true,
      showDeliveryLine: true,
      showItemModifiers: true,
      showBusinessTagline: false,
    },
    header: {
      title: "",
      lines: [],
      align: "center",
      banner: "",
    },
    footer: {
      lines: [],
      align: "center",
    },
    ...overrides,
  };
}

const DEFAULT_TEMPLATES = [
  buildStandardTemplate("standard-receipt", "Standard Receipt", {
    receiptKind: "customer_receipt",
    sections: {
      header: true,
      orderMeta: true,
      items: true,
      totals: true,
      discount: true,
      tax: true,
      loyalty: true,
      payment: true,
      customer: true,
      cashier: false,
      fbr: true,
      footer: true,
    },
    branding: {
      logoPath: "",
      logoScale: 100,
      showPoweredBy: true,
      qrCode: { enabled: false, linkUrl: "", links: [], customText: "" },
      socialLinks: [],
      footerMessage: "Thank you for your order!",
      thankYouMessage: "Please visit again!",
    },
  }),
  buildStandardTemplate("kitchen-ticket", "Kitchen Order Ticket", {
    receiptKind: "kitchen_ticket",
    header: { title: "", lines: [], align: "center", banner: "**** KITCHEN ****" },
    sections: {
      header: true,
      orderMeta: true,
      items: true,
      totals: false,
      discount: false,
      tax: false,
      loyalty: false,
      payment: false,
      customer: true,
      cashier: false,
      fbr: false,
      footer: true,
    },
    conditionals: {
      showTaxDetails: false,
      showCustomerInfo: true,
      showCashierInfo: false,
      showQrCode: false,
      showLogo: false,
    },
    footer: { lines: ["Prepare with care"], align: "center" },
  }),
  buildStandardTemplate("customer-copy", "Customer Copy", {
    receiptKind: "customer_receipt",
    header: { title: "", lines: [], align: "center", banner: "CUSTOMER COPY" },
  }),
  buildStandardTemplate("delivery-receipt", "Delivery Receipt", {
    receiptKind: "delivery_receipt",
    sections: {
      header: true,
      orderMeta: true,
      items: true,
      totals: true,
      discount: true,
      tax: true,
      loyalty: true,
      payment: true,
      customer: true,
      cashier: true,
      notes: true,
      fbr: false,
      footer: true,
    },
    conditionals: {
      showTaxDetails: true,
      showCustomerInfo: true,
      showCashierInfo: false,
      showQrCode: false,
      showLogo: false,
      showTableNumber: false,
      showOrderNotes: true,
      showOrderTime: true,
      showSubtotalLine: true,
      showTaxLine: true,
      showDiscountLine: true,
      showDiscountPercent: false,
      showPackingLine: true,
      showDeliveryLine: true,
      showItemModifiers: true,
      showBusinessTagline: false,
    },
  }),
  buildStandardTemplate("packing-slip", "Packing Slip", {
    receiptKind: "packing_slip",
    header: { title: "", lines: [], align: "center", banner: "PACKING SLIP" },
    sections: {
      header: true,
      orderMeta: true,
      items: true,
      totals: false,
      discount: false,
      tax: false,
      loyalty: false,
      payment: false,
      customer: true,
      cashier: false,
      fbr: false,
      footer: false,
    },
  }),
  buildStandardTemplate("invoice-receipt", "Invoice Receipt", {
    receiptKind: "invoice_receipt",
    business: {
      showLogo: true,
      showBranch: true,
      showAddress: true,
      showPhone: true,
      showWhatsapp: true,
      showWebsite: true,
      showNtn: true,
      showStrn: true,
      showTaxInfo: true,
    },
    sections: {
      header: true,
      orderMeta: true,
      items: true,
      totals: true,
      discount: true,
      tax: true,
      loyalty: true,
      payment: true,
      customer: true,
      cashier: true,
      fbr: true,
      footer: true,
    },
    conditionals: {
      showTaxDetails: true,
      showCustomerInfo: true,
      showCashierInfo: true,
      showQrCode: true,
      showLogo: true,
    },
  }),
];

function getTemplatesDir() {
  return path.join(getSirayaDataRoot(), "templates");
}

function getManifestPath() {
  return path.join(getTemplatesDir(), "manifest.json");
}

function getTemplatePath(id) {
  return path.join(getTemplatesDir(), `${id}.json`);
}

function defaultManifest() {
  return {
    version: 2,
    defaults: {
      customer_receipt: "standard-receipt",
      kitchen_ticket: "kitchen-ticket",
      packing_slip: "packing-slip",
      delivery_receipt: "delivery-receipt",
      invoice_receipt: "invoice-receipt",
    },
    templates: DEFAULT_TEMPLATES.map((t) => ({
      id: t.id,
      name: t.name,
      receiptKind: t.receiptKind,
    })),
    updatedAt: new Date().toISOString(),
  };
}

function validateTemplate(t) {
  if (!t || typeof t !== "object") throw new Error("Template must be an object");
  if (!t.id || !t.name) throw new Error("Template id and name required");
  if (t.version !== 2) throw new Error("Unsupported template version");
  return t;
}

function loadManifest() {
  const filePath = getManifestPath();
  if (!fs.existsSync(filePath)) return null;
  try {
    return JSON.parse(fs.readFileSync(filePath, "utf8"));
  } catch {
    return null;
  }
}

function saveManifest(manifest) {
  ensureDir(getTemplatesDir());
  fs.writeFileSync(getManifestPath(), JSON.stringify(manifest, null, 2), "utf8");
}

function normalizeTemplate(t) {
  if (!t || typeof t !== "object") return t;
  t.branding = t.branding || {};
  t.branding.qrCode = t.branding.qrCode || {};
  const qr = t.branding.qrCode;
  if (!qr.linkUrl && qr.customText) {
    qr.linkUrl = String(qr.customText).trim();
  }
  if (!Array.isArray(qr.links) || !qr.links.length) {
    if (qr.linkUrl) {
      qr.links = [{ url: String(qr.linkUrl).trim() }];
    } else {
      qr.links = [];
    }
  }
  if (t.branding.logoScale == null) t.branding.logoScale = 100;
  if (t.branding.showPoweredBy == null) t.branding.showPoweredBy = true;
  if (!qr.linkUrl && qr.links[0]?.url) qr.linkUrl = qr.links[0].url;
  t.conditionals = t.conditionals || {};
  const condDefaults = {
    showTaxDetails: true,
    showCustomerInfo: true,
    showCashierInfo: false,
    showQrCode: false,
    showLogo: false,
    showTableNumber: false,
    showOrderNotes: true,
    showOrderTime: true,
    showSubtotalLine: true,
    showTaxLine: true,
    showDiscountLine: true,
    showDiscountPercent: false,
    showPackingLine: true,
    showDeliveryLine: true,
    showItemModifiers: true,
    showBusinessTagline: false,
  };
  t.conditionals = { ...condDefaults, ...t.conditionals };
  t.sections = { notes: true, cashier: true, ...(t.sections || {}) };
  if (qr.enabled || t.conditionals.showQrCode) {
    qr.enabled = true;
    t.conditionals.showQrCode = true;
  }
  return t;
}

function loadTemplateById(id) {
  const filePath = getTemplatePath(id);
  if (!fs.existsSync(filePath)) return null;
  try {
    return validateTemplate(normalizeTemplate(JSON.parse(fs.readFileSync(filePath, "utf8"))));
  } catch {
    return null;
  }
}

function saveTemplateById(template) {
  const validated = validateTemplate(template);
  ensureDir(getTemplatesDir());
  fs.writeFileSync(getTemplatePath(validated.id), JSON.stringify(validated, null, 2), "utf8");
  const manifest = loadManifest() || defaultManifest();
  const idx = manifest.templates.findIndex((t) => t.id === validated.id);
  const entry = {
    id: validated.id,
    name: validated.name,
    receiptKind: validated.receiptKind,
  };
  if (idx >= 0) manifest.templates[idx] = entry;
  else manifest.templates.push(entry);
  manifest.updatedAt = new Date().toISOString();
  saveManifest(manifest);
  return validated;
}

function deleteTemplateById(id) {
  const manifest = loadManifest();
  if (!manifest) throw new Error("MANIFEST_NOT_FOUND");
  if (Object.values(manifest.defaults).includes(id)) {
    const err = new Error("CANNOT_DELETE_DEFAULT_TEMPLATE");
    err.status = 409;
    throw err;
  }
  const filePath = getTemplatePath(id);
  if (fs.existsSync(filePath)) fs.unlinkSync(filePath);
  manifest.templates = manifest.templates.filter((t) => t.id !== id);
  saveManifest(manifest);
}

function cloneTemplate(id, newId, newName) {
  const src = loadTemplateById(id);
  if (!src) throw new Error("TEMPLATE_NOT_FOUND");
  const clone = {
    ...JSON.parse(JSON.stringify(src)),
    id: newId,
    name: newName || `${src.name} (Copy)`,
  };
  return saveTemplateById(clone);
}

function setDefaultForKind(receiptKind, templateId) {
  const t = loadTemplateById(templateId);
  if (!t) throw new Error("TEMPLATE_NOT_FOUND");
  const manifest = loadManifest() || defaultManifest();
  manifest.defaults[receiptKind] = templateId;
  saveManifest(manifest);
  return manifest;
}

function resolveTemplateForJob({ receiptKind, templateId }) {
  const manifest = loadManifest();
  if (templateId) {
    const t = loadTemplateById(templateId);
    if (t) return t;
  }
  if (manifest) {
    const defaultId = manifest.defaults[receiptKind] || manifest.defaults.customer_receipt;
    const t = loadTemplateById(defaultId);
    if (t) return t;
  }
  const fallback = DEFAULT_TEMPLATES.find(
    (t) => t.receiptKind === receiptKind,
  ) || DEFAULT_TEMPLATES[0];
  return fallback;
}

function migrateFromV1(v1Template, businessConfig = {}) {
  const cfg = businessConfig || {};
  const standard = buildStandardTemplate("standard-receipt", "Standard Receipt", {
    header: {
      title: v1Template.header?.title || "",
      lines: Array.isArray(v1Template.header?.lines)
        ? v1Template.header.lines.map((l) => String(l || "").trim()).filter(Boolean)
        : [],
      align: v1Template.header?.align || "center",
      banner: "",
    },
    footer: v1Template.footer || { lines: ["Thank you for your order!"], align: "center" },
    sections: {
      header: true,
      orderMeta: v1Template.sections?.orderMeta !== false,
      items: v1Template.sections?.items !== false,
      totals: v1Template.sections?.totals !== false,
      discount: true,
      tax: true,
      loyalty: v1Template.sections?.loyalty !== false,
      payment: v1Template.sections?.payment !== false,
      customer: true,
      cashier: false,
      fbr: false,
      footer: v1Template.sections?.footer !== false,
    },
    paperWidth: v1Template.paperWidth || 32,
    visual: {
      titleSize: v1Template.styles?.titleSize || "large",
      fontFamily: "default",
      currencyPrefix: v1Template.styles?.currencyPrefix || "Rs ",
      dividerStyle: "dash",
      itemLayout: "standard",
      alignment: { header: "center", body: "left", footer: "center" },
    },
    conditionals: {
      showTaxDetails: true,
      showCustomerInfo: true,
      showCashierInfo: false,
      showQrCode: false,
      showLogo: Boolean(v1Template.header?.showLogo),
    },
  });
  return standard;
}

function initializeTemplates(businessConfig = {}) {
  ensureDir(getTemplatesDir());
  if (loadManifest()) return loadManifest();

  const v1Path = path.join(getSirayaDataRoot(), "receipt-template.json");
  if (fs.existsSync(v1Path)) {
    try {
      const v1 = JSON.parse(fs.readFileSync(v1Path, "utf8"));
      const migrated = migrateFromV1(v1, businessConfig);
      saveTemplateById(migrated);
    } catch {
      /* use defaults */
    }
  }

  for (const t of DEFAULT_TEMPLATES) {
    if (!loadTemplateById(t.id)) {
      saveTemplateById({ ...t });
    }
  }

  const manifest = defaultManifest();
  saveManifest(manifest);
  return manifest;
}

function listTemplates() {
  const manifest = loadManifest() || initializeTemplates();
  return {
    manifest,
    templates: manifest.templates.map((meta) => ({
      ...meta,
      template: loadTemplateById(meta.id),
    })),
  };
}

module.exports = {
  RECEIPT_KINDS,
  DEFAULT_TEMPLATES,
  initializeTemplates,
  loadManifest,
  loadTemplateById,
  saveTemplateById,
  deleteTemplateById,
  cloneTemplate,
  setDefaultForKind,
  resolveTemplateForJob,
  migrateFromV1,
  listTemplates,
  validateTemplate,
  getTemplatesDir,
};
