/**
 * Create / edit a Smart List — a saved, **dynamic** contact segment: name +
 * optional description + a condition query (the published
 * `ContactAlertQueryBuilder` + `ALERT_QUERY_FIELDS`) with a live match-count
 * preview.
 *
 * Same saved-query engine as a Contact Alert but **without the alert
 * `severity`** — a Smart List's purpose is *targeting / sending* (the Email
 * Marketing composer consumes it as a recipient source), not monitoring.
 * Membership is dynamic: any client matching the conditions is included now
 * and in future; editing the conditions recomputes membership. At least one
 * complete condition is required — Save stays disabled otherwise.
 *
 * Lists are shared company assets; there is deliberately no per-list sharing
 * control.
 */
import { type ReactElement, useEffect, useMemo, useState } from "react";
import { Users } from "lucide-react";
import {
  Utils as QbUtils,
  type ImmutableTree,
} from "@react-awesome-query-builder/ui";
import { Button } from "./button";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from "./dialog";
import { Field, FieldLabel } from "./field";
import { Input } from "./input";
import { Textarea } from "./textarea";
import { TagInput } from "./tag-input";
import {
  ContactAlertQueryBuilder,
  ALERT_QUERY_FIELDS,
  createAlertTree,
} from "./contact-alert-dialog";
import { QB_CONFIG } from "./contact-alert-dialog/config";
import { isTreeValid } from "./contact-alert-dialog/utils";

export interface CreateSmartListPayload {
  name: string;
  description: string;
  /** The sanitized query tree — serialize with `QbUtils.getTree` for the API. */
  filterSegment: ImmutableTree;
  /** Tags the segment matches — a contact with ANY of them is included. */
  tags: string[];
}

export interface CreateSmartListDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  mode?: "create" | "edit";
  initialName?: string;
  initialDescription?: string;
  /** Seed conditions — e.g. when saving the current Contacts filter as a list. */
  initialQuery?: Parameters<typeof createAlertTree>[0];
  /** Live count of contacts matching the current conditions. */
  matchingCount?: number;
  /** The broker's tag library, for the Tags condition autocomplete. */
  availableTags?: string[];
  initialTags?: string[];
  onSave?: (payload: CreateSmartListPayload) => void;
  /** Fires as the tree changes so the host can refresh the live match count. */
  onQueryChange?: (tree: ImmutableTree) => void;
  isLoading?: boolean;
}

export function CreateSmartListDialog({
  open,
  onOpenChange,
  mode = "create",
  initialName = "",
  initialDescription = "",
  initialQuery,
  matchingCount,
  availableTags = [],
  initialTags = [],
  onSave,
  onQueryChange,
  isLoading = false,
}: CreateSmartListDialogProps): ReactElement {
  const [name, setName] = useState(initialName);
  const [description, setDescription] = useState(initialDescription);
  const [tree, setTree] = useState(() => createAlertTree(initialQuery));
  const [tags, setTags] = useState<string[]>(initialTags);

  // Reset local state each time the dialog opens.
  useEffect(() => {
    if (open) {
      setName(initialName);
      setDescription(initialDescription);
      setTree(createAlertTree(initialQuery));
      setTags(initialTags);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps -- reset from initial* props only on open, not while typing
  }, [open]);

  const hasValidRule = useMemo(() => isTreeValid(tree), [tree]);
  // A smart list can be built from tags, conditions, or both.
  const canSave =
    name.trim().length > 0 && (hasValidRule || tags.length > 0) && !isLoading;

  const handleTreeChange = (next: ImmutableTree): void => {
    setTree(next);
    onQueryChange?.(next);
  };

  const handleSave = (): void => {
    if (!canSave) return;
    const filterSegment = QbUtils.sanitizeTree(tree, QB_CONFIG).fixedTree;
    onSave?.({
      name: name.trim(),
      description: description.trim(),
      filterSegment,
      tags,
    });
    onOpenChange(false);
  };

  return (
    <Dialog onOpenChange={isLoading ? undefined : onOpenChange} open={open}>
      <DialogContent size="2xl">
        <DialogHeader>
          <DialogTitle>
            {mode === "edit" ? "Edit smart list" : "Create smart list"}
          </DialogTitle>
        </DialogHeader>

        <div className="max-h-[64vh] overflow-y-auto px-1">
          <div className="flex flex-col gap-4">
            <Field>
              <FieldLabel>Smart list name</FieldLabel>
              <Input
                onChange={(e) => {
                  setName(e.target.value);
                }}
                placeholder="e.g. High-equity refinance prospects"
                value={name}
              />
            </Field>

            <Field>
              <FieldLabel>Description (optional)</FieldLabel>
              <Textarea
                className="min-h-16"
                onChange={(e) => {
                  setDescription(e.target.value);
                }}
                placeholder="What this segment is for — helps your team pick the right list."
                value={description}
              />
            </Field>

            <Field>
              <FieldLabel>Tags</FieldLabel>
              <TagInput
                value={tags}
                onChange={setTags}
                suggestions={availableTags}
                allowCreate={false}
                placeholder="Select tags…"
                aria-label="Tags this smart list matches"
              />
              <span className="text-caption text-muted-foreground">
                Includes any contact carrying at least one selected tag.
              </span>
            </Field>

            <div className="flex flex-col gap-1.5">
              <span className="text-label-small text-foreground">
                Conditions
              </span>
              <ContactAlertQueryBuilder
                fields={ALERT_QUERY_FIELDS}
                onChange={handleTreeChange}
                value={tree}
              />
              <span className="text-caption text-muted-foreground">
                Membership is dynamic — any client matching these conditions is
                included automatically. Add tags above, conditions here, or
                both.
              </span>
            </div>

            {typeof matchingCount === "number" && (
              <div className="flex items-center gap-2 border border-border bg-muted/40 px-3 py-2 text-body-small text-muted-foreground">
                <Users className="size-4 text-primary" />
                <span>
                  <span className="font-medium text-foreground">
                    ≈ {matchingCount.toLocaleString()}
                  </span>{" "}
                  clients currently match
                </span>
              </div>
            )}
          </div>
        </div>

        <DialogFooter>
          <Button
            onClick={() => {
              onOpenChange(false);
            }}
            variant="outline"
          >
            Cancel
          </Button>
          <Button disabled={!canSave} onClick={handleSave}>
            {mode === "edit" ? "Save changes" : "Create smart list"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

export default CreateSmartListDialog;
