"use client";

import * as React from "react";
import { ArrowRight, Plus, Trash2, Sparkles } from "lucide-react";
import { Button } from "@/components/ui/button";
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";

export type SourceField = {
  key: string;
  label: string;
  type: string;
  group: "core" | "custom";
};

export type ExternalField = {
  id: string;
  name: string;
  type?: string;
};

export type FieldMapping = Record<string, string>;

interface FieldMappingEditorProps {
  sourceFields: SourceField[];
  externalFields: ExternalField[];
  value: FieldMapping;
  onChange: (mapping: FieldMapping) => void;
  externalLabel?: string;
  loading?: boolean;
}

type Row = {
  id: string;
  sourceKey: string;
  externalId: string;
};

function normalize(s: string): string {
  return s.toLowerCase().replace(/[^a-z0-9]/g, "");
}

function autoMatch(
  sourceFields: SourceField[],
  externalFields: ExternalField[]
): FieldMapping {
  const mapping: FieldMapping = {};
  const usedExternal = new Set<string>();

  for (const sf of sourceFields) {
    const normalizedSource = normalize(sf.key.replace(/^fieldData\./, ""));
    const normalizedLabel = normalize(sf.label);

    const match = externalFields.find((ef) => {
      if (usedExternal.has(ef.id)) return false;
      const nName = normalize(ef.name);
      return nName === normalizedSource || nName === normalizedLabel;
    });

    if (match) {
      mapping[sf.key] = match.id;
      usedExternal.add(match.id);
    }
  }
  return mapping;
}

export function FieldMappingEditor({
  sourceFields,
  externalFields,
  value,
  onChange,
  externalLabel = "External Field",
  loading = false,
}: FieldMappingEditorProps) {
  const rows: Row[] = React.useMemo(() => {
    const entries = Object.entries(value).filter(
      ([k]) => !k.startsWith("_")
    );
    return entries.map(([sourceKey, externalId], i) => ({
      id: `${sourceKey}-${i}`,
      sourceKey,
      externalId,
    }));
  }, [value]);

  const updateMapping = (newRows: Row[]) => {
    const next: FieldMapping = {};
    for (const r of newRows) {
      if (r.sourceKey && r.externalId) {
        next[r.sourceKey] = r.externalId;
      }
    }
    onChange(next);
  };

  const handleAdd = () => {
    updateMapping([...rows, { id: `new-${Date.now()}`, sourceKey: "", externalId: "" }]);
  };

  const handleRemove = (idx: number) => {
    const next = rows.filter((_, i) => i !== idx);
    updateMapping(next);
  };

  const handleChangeRow = (
    idx: number,
    field: "sourceKey" | "externalId",
    val: string | null
  ) => {
    const next = rows.map((r, i) => (i === idx ? { ...r, [field]: val ?? "" } : r));
    updateMapping(next);
  };

  const handleAutoSuggest = () => {
    onChange(autoMatch(sourceFields, externalFields));
  };

  const coreFields = sourceFields.filter((f) => f.group === "core");
  const customFields = sourceFields.filter((f) => f.group === "custom");

  if (loading) {
    return (
      <p className="text-sm text-muted-foreground">
        Loading available fields…
      </p>
    );
  }

  if (externalFields.length === 0) {
    return (
      <div className="rounded-lg border border-dashed p-4 text-sm text-muted-foreground">
        Connect the integration first to load available fields from the external
        system.
      </div>
    );
  }

  return (
    <div className="space-y-3">
      {rows.length === 0 && (
        <div className="rounded-lg border border-dashed p-6 text-center">
          <p className="text-sm text-muted-foreground">
            No field mappings configured yet.
          </p>
          <p className="mt-1 text-xs text-muted-foreground">
            Add mappings to control which card fields sync to the external
            system.
          </p>
        </div>
      )}

      {rows.map((row, idx) => (
        <div
          key={row.id}
          className="flex items-center gap-2 rounded-lg border bg-card/40 p-2"
        >
          <div className="flex-1">
            <Select
              value={row.sourceKey}
              onValueChange={(v) => handleChangeRow(idx, "sourceKey", v)}
            >
              <SelectTrigger>
                <SelectValue placeholder="Card field…" />
              </SelectTrigger>
              <SelectContent>
                {coreFields.length > 0 && (
                  <SelectGroup>
                    <SelectLabel>Core Fields</SelectLabel>
                    {coreFields.map((f) => (
                      <SelectItem key={f.key} value={f.key}>
                        {f.label}
                      </SelectItem>
                    ))}
                  </SelectGroup>
                )}
                {customFields.length > 0 && (
                  <SelectGroup>
                    <SelectLabel>Custom Fields</SelectLabel>
                    {customFields.map((f) => (
                      <SelectItem key={f.key} value={f.key}>
                        {f.label}
                      </SelectItem>
                    ))}
                  </SelectGroup>
                )}
              </SelectContent>
            </Select>
          </div>

          <ArrowRight className="size-4 shrink-0 text-muted-foreground" />

          <div className="flex-1">
            <Select
              value={row.externalId}
              onValueChange={(v) => handleChangeRow(idx, "externalId", v)}
            >
              <SelectTrigger>
                <SelectValue placeholder={`${externalLabel}…`} />
              </SelectTrigger>
              <SelectContent>
                {externalFields.map((ef) => (
                  <SelectItem key={ef.id} value={ef.id}>
                    {ef.name}
                    {ef.type && (
                      <span className="ml-2 text-xs text-muted-foreground">
                        ({ef.type})
                      </span>
                    )}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <Button
            variant="ghost"
            size="icon"
            onClick={() => handleRemove(idx)}
            className="shrink-0 text-muted-foreground hover:text-destructive"
            aria-label="Remove mapping"
          >
            <Trash2 className="size-4" />
          </Button>
        </div>
      ))}

      <div className="flex items-center gap-2">
        <Button variant="outline" size="sm" onClick={handleAdd} className="rounded-xl">
          <Plus className="mr-1.5 size-3.5" />
          Add Mapping
        </Button>
        {rows.length === 0 && externalFields.length > 0 && (
          <Button
            variant="ghost"
            size="sm"
            onClick={handleAutoSuggest}
            className="rounded-xl"
          >
            <Sparkles className="mr-1.5 size-3.5" />
            Auto-match by name
          </Button>
        )}
      </div>
    </div>
  );
}
