import * as fs from "node:fs";
import * as path from "node:path";
import * as readline from "node:readline/promises";
import { fileURLToPath } from "node:url";
import { createElement } from "react";
import { renderToFile } from "@react-pdf/renderer";
import { calculateTotals, initialState, PRICING } from "@mintel/pdf";
import { CombinedQuotePDF } from "../src/components/CombinedQuotePDF.js";
import {
  getTechDetails,
  getPrinciples,
  getMaintenanceDetails,
  getStandardsDetails,
} from "../src/logic/content-provider.js";

const __filename = fileURLToPath(import.meta.url);

async function main() {
  const args = process.argv.slice(2);
  const isInteractive = args.includes("--interactive") || args.includes("-I");
  const isEstimationOnly = args.includes("--estimation") || args.includes("-E");
  const inputPath = args.find(
    (_, i) => args[i - 1] === "--input" || args[i - 1] === "-i",
  );

  let state = { ...initialState };

  if (inputPath) {
    const rawData = fs.readFileSync(
      path.resolve(process.cwd(), inputPath),
      "utf8",
    );
    const diskState = JSON.parse(rawData);
    state = { ...state, ...diskState };
  }

  if (isInteractive) {
    state = await runWizard(state);
  }

  // Final confirmation of data needed for PDF
  if (!state.name || !state.email) {
    console.warn(
      "⚠️ Missing recipient name or email. Document might look incomplete.",
    );
  }

  const totals = calculateTotals(state, PRICING);
  const { totalPrice, monthlyPrice, totalPagesCount } = totals;

  const finalOutputPath = generateDefaultPath(state);
  const outputDir = path.dirname(finalOutputPath);
  if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir, { recursive: true });
  }

  // Resolve assets for the PDF
  const assetsDir = path.resolve(process.cwd(), "src/assets");
  const headerIcon = path.join(assetsDir, "logo/Icon White Transparent.png");
  const footerLogo = path.join(assetsDir, "logo/Logo Black Transparent.png");

  console.log(`🚀 Generating PDF: ${finalOutputPath}`);

  const estimationProps = {
    state,
    totalPrice,
    monthlyPrice,
    totalPagesCount,
    pricing: PRICING,
    headerIcon,
    footerLogo,
  };

  await renderToFile(
    createElement(CombinedQuotePDF as any, {
      estimationProps,
      techDetails: getTechDetails(),
      principles: getPrinciples(),
      maintenanceDetails: getMaintenanceDetails(),
      standardsDetails: getStandardsDetails(),
      mode: isEstimationOnly ? "estimation" : "full",
      showAgbs: !isEstimationOnly, // AGBS only for full quotes
    }) as any,
    finalOutputPath,
  );

  console.log("✅ Done!");
}

async function runWizard(state: any) {
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
  });

  console.log("\n--- Mintel Quote Generator Wizard ---\n");

  const ask = async (q: string, def?: string) => {
    const answer = await rl.question(`${q}${def ? ` [${def}]` : ""}: `);
    return answer || def || "";
  };

  const selectOne = async (
    q: string,
    options: { id: string; label: string }[],
  ) => {
    console.log(`\n${q}:`);
    options.forEach((opt, i) => console.log(`${i + 1}) ${opt.label}`));
    const answer = await rl.question("Selection (number): ");
    const idx = parseInt(answer) - 1;
    return options[idx]?.id || options[0].id;
  };

  state.name = await ask("Recipient Name", state.name);
  state.email = await ask("Recipient Email", state.email);
  state.companyName = await ask("Company Name", state.companyName);

  state.projectType = await selectOne("Project Type", [
    { id: "website", label: "Website" },
    { id: "web-app", label: "Web App" },
  ]);

  if (state.projectType === "website") {
    state.websiteTopic = await ask("Website Topic", state.websiteTopic);
    // Simplified for now, in a real tool we'd loop through all options
  }

  rl.close();
  return state;
}

function generateDefaultPath(state: any) {
  const now = new Date();
  const month = now.toISOString().slice(0, 7);
  const day = now.toISOString().slice(0, 10);
  // Add seconds and minutes for 100% unique names without collision
  const time = now
    .toLocaleTimeString("de-DE", {
      hour: "2-digit",
      minute: "2-digit",
      second: "2-digit",
    })
    .replace(/:/g, "-");
  const company = (state.companyName || state.name || "Unknown").replace(
    /[^a-z0-9]/gi,
    "_",
  );
  return path.join(
    process.cwd(),
    "out",
    "estimations",
    month,
    `${day}_${time}_${company}_${state.projectType}.pdf`,
  );
}

main().catch((err) => {
  console.error("❌ Error:", err);
  process.exit(1);
});
