import type {
  IntegrationProvider,
  CardData,
  TestResult,
  PushResult,
  JsonValue,
} from "../types";

const DEFAULT_COLUMNS = [
  "name",
  "email",
  "cellPhone",
  "homePhone",
  "address",
  "city",
  "state",
  "zip",
  "gender",
  "dateOfBirth",
  "maritalStatus",
  "visitType",
  "prayerRequests",
  "followUp",
  "notes",
  "serviceAttended",
  "firstTimeGuestDate",
  "salvationDate",
];

interface CsvConfig {
  format: "csv" | "tsv";
  columns: string[];
  includeHeaders: boolean;
}

function parseConfig(config: JsonValue): CsvConfig {
  const c = config as Record<string, unknown>;
  return {
    format: (c.format as "csv" | "tsv") || "csv",
    columns: (c.columns as string[]) || DEFAULT_COLUMNS,
    includeHeaders: c.includeHeaders !== false,
  };
}

function escapeCell(val: string, delimiter: string): string {
  if (
    val.includes(delimiter) ||
    val.includes('"') ||
    val.includes("\n")
  ) {
    return `"${val.replace(/"/g, '""')}"`;
  }
  return val;
}

export function cardToCsvRow(
  card: CardData,
  columns: string[],
  delimiter: string
): string {
  return columns
    .map((col) => {
      const val = card[col];
      if (val === null || val === undefined) return "";
      if (val instanceof Date) return val.toISOString().split("T")[0];
      if (typeof val === "object") return escapeCell(JSON.stringify(val), delimiter);
      return escapeCell(String(val), delimiter);
    })
    .join(delimiter);
}

export const csvExportProvider: IntegrationProvider = {
  id: "csv_export",
  name: "CSV / Excel Export",
  description: "Generate CSV or TSV files from processed cards",
  icon: "csv_export",
  category: "export",
  supportsFieldMapping: false,
  supportsOAuth: false,
  configFields: [
    {
      key: "format",
      label: "Format",
      type: "select",
      options: [
        { value: "csv", label: "CSV (comma-separated)" },
        { value: "tsv", label: "TSV (tab-separated, Excel-friendly)" },
      ],
    },
    {
      key: "includeHeaders",
      label: "Include column headers",
      type: "boolean",
    },
  ],

  setupGuide: {
    summary:
      "CSV / Excel export is always available — no external service or API keys are required. Echo OCR generates CSV or TSV rows from processed cards that you can download or pipe into downstream tools.",
    steps: [
      {
        title: "Choose a format",
        body: "CSV is the universal default. TSV (tab-separated) is friendlier for Excel — it opens cleanly without import-wizard prompts and avoids comma-escaping issues with prayer requests or address fields.",
      },
      {
        title: "Decide whether to include headers",
        body: "Leave \"Include column headers\" on for most uses. Turn it off only if you're concatenating rows onto an existing file that already has headers.",
      },
      {
        title: "Export from the cards view",
        body: "From the main Cards page, select the cards you want and choose Export. Echo OCR generates a single CSV/TSV file with all selected rows in the configured column order.",
      },
      {
        title: "Columns included",
        body: "By default Echo OCR includes: name, email, cellPhone, homePhone, address, city, state, zip, gender, dateOfBirth, maritalStatus, visitType, prayerRequests, followUp, notes, serviceAttended, firstTimeGuestDate, salvationDate.",
      },
    ],
  },

  async testConnection(): Promise<TestResult> {
    return {
      success: true,
      message: "CSV export is always available — no external connection needed",
    };
  },

  async pushCard(
    card: CardData,
    config: JsonValue,
  ): Promise<PushResult> {
    try {
      const { format, columns } = parseConfig(config);
      const delimiter = format === "tsv" ? "\t" : ",";
      const row = cardToCsvRow(card, columns, delimiter);
      return {
        success: true,
        message: `Generated ${format.toUpperCase()} row (${row.length} chars)`,
      };
    } catch (err) {
      return {
        success: false,
        message: err instanceof Error ? err.message : "Export failed",
      };
    }
  },
};
