import React from "react";
import { Download, Info, Loader2, Pencil, Plus, Trash2, Upload } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Separator } from "@/components/ui/separator";
import { Switch } from "@/components/ui/switch";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Textarea } from "@/components/ui/textarea";
import { cn } from "@/lib/utils";
import type { AiBuilderAgentConfig, AiBuilderRuleItem } from "./types";

// ---------------------------------------------------------------------------
// SectionHeader
// ---------------------------------------------------------------------------

export type SectionHeaderProps = {
  title: string;
  description: string;
  className?: string;
};

export function SectionHeader({
  title,
  description,
  className,
}: SectionHeaderProps) {
  return (
    <div className={cn("flex flex-col gap-0.5", className)}>
      <h2 className="text-h5">{title}</h2>
      <p className="text-body-small text-muted-foreground">{description}</p>
    </div>
  );
}

// ---------------------------------------------------------------------------
// SettingRow
// ---------------------------------------------------------------------------

export type SettingRowProps = {
  icon: React.ReactNode;
  label: string;
  description: string;
  control: React.ReactNode;
  className?: string;
};

export function SettingRow({
  icon,
  label,
  description,
  control,
  className,
}: SettingRowProps) {
  return (
    <div className={cn("flex items-center gap-4 py-4", className)}>
      <div className="flex size-10 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground">
        {icon}
      </div>
      <div className="flex flex-1 flex-col gap-0.5">
        <span className="text-sm font-semibold">{label}</span>
        <span className="text-caption text-muted-foreground">
          {description}
        </span>
      </div>
      <div className="shrink-0">{control}</div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// SettingCard — wraps SettingRows with a bordered card + dividers
// ---------------------------------------------------------------------------

export type SettingCardProps = {
  rows: SettingRowProps[];
  className?: string;
};

export function SettingCard({ rows, className }: SettingCardProps) {
  return (
    <div className={cn("rounded-none border px-4", className)}>
      {rows.map((row, i) => (
        <React.Fragment key={row.label}>
          <SettingRow {...row} />
          {i < rows.length - 1 && <Separator />}
        </React.Fragment>
      ))}
    </div>
  );
}

// ---------------------------------------------------------------------------
// AgentConfigForm
// ---------------------------------------------------------------------------

export type AgentConfigFormProps = {
  config: AiBuilderAgentConfig;
  onChange: (config: AiBuilderAgentConfig) => void;
  className?: string;
};

export function AgentConfigForm({
  config,
  onChange,
  className,
}: AgentConfigFormProps) {
  return (
    <div
      className={cn("flex flex-col gap-4 rounded-none border p-6", className)}
    >
      <div className="flex flex-col gap-1.5">
        <Label htmlFor="agent-name">Agent Name</Label>
        <Input
          id="agent-name"
          value={config.name}
          onChange={(e) => onChange({ ...config, name: e.target.value })}
        />
      </div>
      <div className="flex flex-col gap-1.5">
        <Label htmlFor="agent-desc">Business Description</Label>
        <Textarea
          id="agent-desc"
          rows={4}
          placeholder="What business is this agent for? What industry?"
          value={config.businessDescription}
          onChange={(e) =>
            onChange({ ...config, businessDescription: e.target.value })
          }
        />
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// ResponseTemplateEditModal
// ---------------------------------------------------------------------------

export type ResponseTemplateEditModalProps = {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  channel: "email" | "chat";
  content: string;
  onConfirm: (content: string) => void;
};

export function ResponseTemplateEditModal({
  open,
  onOpenChange,
  channel,
  content,
  onConfirm,
}: ResponseTemplateEditModalProps) {
  const [draft, setDraft] = React.useState(content);

  React.useEffect(() => {
    if (open) setDraft(content);
  }, [open, content]);

  const isEmail = channel === "email";
  const channelLabel = isEmail ? "Email" : "Chat";
  const helperText = isEmail
    ? "Use {customer} to insert the customer name and {answer} to insert the response"
    : "Use {answer} to insert the response";

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-lg">
        <DialogHeader>
          <DialogTitle>Edit {channelLabel} response template</DialogTitle>
        </DialogHeader>

        <div className="flex flex-col gap-1.5 py-2">
          <Label htmlFor="template-content">
            {channelLabel} template content{" "}
            <span className="text-destructive">*</span>
          </Label>
          <Textarea
            id="template-content"
            rows={6}
            placeholder={`Enter content for ${channelLabel} template`}
            value={draft}
            onChange={(e) => setDraft(e.target.value)}
          />
          <p className="text-caption text-muted-foreground">{helperText}</p>
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button
            onClick={() => {
              onConfirm(draft);
              onOpenChange(false);
            }}
          >
            Confirm
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

// ---------------------------------------------------------------------------
// RuleOrderBadge
// ---------------------------------------------------------------------------

export type RuleOrderBadgeProps = {
  order: number;
  className?: string;
};

export function RuleOrderBadge({ order, className }: RuleOrderBadgeProps) {
  return (
    <Badge variant="secondary" className={className}>
      #{order}
    </Badge>
  );
}

// ---------------------------------------------------------------------------
// RuleSetSection
// ---------------------------------------------------------------------------

export type RuleListLoadMore = {
  hasMore: boolean;
  isLoadingMore: boolean;
  onLoadMore: () => void;
};

export type RuleSetSectionProps = {
  standardRules: AiBuilderRuleItem[];
  handoffRules: AiBuilderRuleItem[];
  onAddRule: (defaultType: "standard" | "handoff") => void;
  onEditRule: (id: string) => void;
  onDeleteRule: (id: string) => void;
  onToggleRule: (id: string, enabled: boolean) => void;
  onExport: () => void;
  onImport: () => void;
  /** Infinite-scroll wiring per rule list. */
  standardLoadMore?: RuleListLoadMore;
  handoffLoadMore?: RuleListLoadMore;
  /** Max height (px) of each scrollable rule list. */
  maxBodyHeight?: number;
  className?: string;
};

// ---------------------------------------------------------------------------
// RuleRow — individual rule row
// ---------------------------------------------------------------------------

function RuleRow({
  rule,
  onEdit,
  onDelete,
  onToggle,
}: {
  rule: AiBuilderRuleItem;
  onEdit: (id: string) => void;
  onDelete: (id: string) => void;
  onToggle: (id: string, enabled: boolean) => void;
}) {
  return (
    <TableRow>
      {/* Rule text */}
      <TableCell className="text-body-small overflow-hidden">
        <div className="break-words whitespace-normal">{rule.text}</div>
      </TableCell>

      {/* Actions */}
      <TableCell>
        <div className="flex items-center justify-end gap-1">
          <Switch
            checked={rule.isEnabled}
            onCheckedChange={(checked) => onToggle(rule.id, checked)}
            aria-label="Toggle rule"
          />
          <Button
            variant="ghost"
            size="icon"
            className="h-8 w-8"
            onClick={() => onEdit(rule.id)}
            aria-label="Edit rule"
          >
            <Pencil className="h-3.5 w-3.5" />
          </Button>
          <Button
            variant="ghost"
            size="icon"
            className="h-8 w-8 text-destructive hover:text-destructive"
            onClick={() => onDelete(rule.id)}
            aria-label="Delete rule"
          >
            <Trash2 className="h-3.5 w-3.5" />
          </Button>
        </div>
      </TableCell>
    </TableRow>
  );
}

// ---------------------------------------------------------------------------
// RuleTable
// ---------------------------------------------------------------------------

function RuleTable({
  rules,
  onEdit,
  onDelete,
  onToggle,
}: {
  rules: AiBuilderRuleItem[];
  onEdit: (id: string) => void;
  onDelete: (id: string) => void;
  onToggle: (id: string, enabled: boolean) => void;
}) {
  if (rules.length === 0) {
    return (
      <div className="flex h-24 items-center justify-center text-body-small text-muted-foreground">
        No rules added yet.
      </div>
    );
  }

  return (
    <Table className="table-fixed">
      <TableHeader>
        <TableRow>
          <TableHead>Rule Set</TableHead>
          <TableHead className="w-36 text-right">Actions</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {rules.map((rule) => (
          <RuleRow
            key={rule.id}
            rule={rule}
            onEdit={onEdit}
            onDelete={onDelete}
            onToggle={onToggle}
          />
        ))}
      </TableBody>
    </Table>
  );
}

function RuleTabContent({
  rules,
  description,
  onEditRule,
  onDeleteRule,
  onToggleRule,
  loadMore,
  maxBodyHeight = 360,
}: {
  rules: AiBuilderRuleItem[];
  description: string;
  onEditRule: (id: string) => void;
  onDeleteRule: (id: string) => void;
  onToggleRule: (id: string, enabled: boolean) => void;
  /** Infinite scroll — when omitted, the list is simply scrollable. */
  loadMore?: RuleListLoadMore;
  maxBodyHeight?: number;
}) {
  // Auto-load the next batch when the user scrolls near the bottom.
  const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {
    if (!loadMore?.hasMore || loadMore.isLoadingMore) return;
    const el = e.currentTarget;
    if (el.scrollHeight - el.scrollTop - el.clientHeight < 48) {
      loadMore.onLoadMore();
    }
  };

  return (
    <div className="mt-4 flex flex-col gap-3">
      <div className="flex items-start gap-2 rounded-none border border-blue-200 bg-blue-50 p-3">
        <Info className="mt-0.5 h-4 w-4 shrink-0 text-blue-600" />
        <p className="text-caption text-blue-700">{description}</p>
      </div>

      <div
        className="overflow-y-auto"
        style={{ maxHeight: maxBodyHeight }}
        onScroll={handleScroll}
      >
        <RuleTable
          rules={rules}
          onEdit={onEditRule}
          onDelete={onDeleteRule}
          onToggle={onToggleRule}
        />
        {loadMore?.isLoadingMore && (
          <div className="flex items-center justify-center gap-2 py-3 text-body-small text-muted-foreground">
            <Loader2 className="h-4 w-4 animate-spin" />
            Loading more…
          </div>
        )}
      </div>
    </div>
  );
}

export function RuleSetSection({
  standardRules,
  handoffRules,
  onAddRule,
  onEditRule,
  onDeleteRule,
  onToggleRule,
  onExport,
  onImport,
  standardLoadMore,
  handoffLoadMore,
  maxBodyHeight,
  className,
}: RuleSetSectionProps) {
  const [activeTab, setActiveTab] = React.useState<"standard" | "handoff">(
    "standard"
  );

  return (
    <div className={cn("flex flex-col gap-4", className)}>
      {/* Toolbar */}
      <div className="flex items-start justify-between gap-4">
        <SectionHeader
          title="Rule Set"
          description="You can adjust the behavior and response method of the Agent through rules."
        />
        <div className="flex shrink-0 items-center gap-2">
          <Button variant="outline" size="sm" onClick={onExport}>
            <Download className="mr-1.5 h-3.5 w-3.5" />
            Export
          </Button>
          <Button variant="outline" size="sm" onClick={onImport}>
            <Upload className="mr-1.5 h-3.5 w-3.5" />
            Import
          </Button>
          <Button size="sm" onClick={() => onAddRule(activeTab)}>
            <Plus className="mr-1.5 h-3.5 w-3.5" />
            Add rule
          </Button>
        </div>
      </div>

      {/* Tabs + content */}
      <Tabs
        defaultValue="standard"
        onValueChange={(v) => setActiveTab(v as "standard" | "handoff")}
      >
        <TabsList className="w-full">
          <TabsTrigger value="standard" className="flex-1">
            Standard Rules
          </TabsTrigger>
          <TabsTrigger value="handoff" className="flex-1">
            Hand-off Rules
          </TabsTrigger>
        </TabsList>

        <TabsContent value="standard">
          <RuleTabContent
            rules={standardRules}
            description="Standard rules guide AI behavior during response generation. These rules help the AI understand how to respond appropriately."
            onEditRule={onEditRule}
            onDeleteRule={onDeleteRule}
            onToggleRule={onToggleRule}
            loadMore={standardLoadMore}
            maxBodyHeight={maxBodyHeight}
          />
        </TabsContent>

        <TabsContent value="handoff">
          <RuleTabContent
            rules={handoffRules}
            description="Hand-off rules define when the AI should transfer a conversation to a human agent."
            onEditRule={onEditRule}
            onDeleteRule={onDeleteRule}
            onToggleRule={onToggleRule}
            loadMore={handoffLoadMore}
            maxBodyHeight={maxBodyHeight}
          />
        </TabsContent>
      </Tabs>
    </div>
  );
}

// ---------------------------------------------------------------------------
// AddEditRuleModal
// ---------------------------------------------------------------------------

export type AddEditRuleModalProps = {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  /** Pass a rule to edit; omit or pass null/undefined for "Add" mode */
  rule?: AiBuilderRuleItem | null;
  /** Pre-select the rule type in Add mode (defaults to "standard") */
  defaultType?: "standard" | "handoff";
  onConfirm: (text: string, type: "standard" | "handoff") => void;
};

export function AddEditRuleModal({
  open,
  onOpenChange,
  rule,
  defaultType = "standard",
  onConfirm,
}: AddEditRuleModalProps) {
  // Map between internal type key and display label (pattern: value === label)
  const RULE_TYPE_LABELS: Record<"standard" | "handoff", string> = {
    standard: "Standard Rule",
    handoff: "Hand-off Rule",
  };
  const LABEL_TO_TYPE: Record<string, "standard" | "handoff"> = {
    "Standard Rule": "standard",
    "Hand-off Rule": "handoff",
  };

  const isEdit = !!rule;
  const [draft, setDraft] = React.useState(rule?.text ?? "");
  const [ruleType, setRuleType] = React.useState<"standard" | "handoff">(
    defaultType
  );

  React.useEffect(() => {
    if (open) {
      setDraft(rule?.text ?? "");
      setRuleType(defaultType);
    }
  }, [open, rule, defaultType]);

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-lg">
        <DialogHeader>
          <DialogTitle>{isEdit ? "Edit Rule" : "Add Rule"}</DialogTitle>
        </DialogHeader>

        <div className="flex flex-col gap-3 py-2">
          {!isEdit && (
            <div className="flex flex-col gap-1.5">
              <Label htmlFor="rule-type">
                Rule Type <span className="text-destructive">*</span>
              </Label>
              <Select
                value={RULE_TYPE_LABELS[ruleType]}
                onValueChange={(v) => v && setRuleType(LABEL_TO_TYPE[v])}
              >
                <SelectTrigger id="rule-type" className="w-full">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="Standard Rule">Standard Rule</SelectItem>
                  <SelectItem value="Hand-off Rule">Hand-off Rule</SelectItem>
                </SelectContent>
              </Select>
            </div>
          )}

          <div className="flex flex-col gap-1.5">
            <Label htmlFor="rule-draft">
              Rule <span className="text-destructive">*</span>
            </Label>
            <Textarea
              id="rule-draft"
              rows={4}
              placeholder="Describe the rule the agent should follow…"
              value={draft}
              onChange={(e) => setDraft(e.target.value)}
            />
          </div>
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button
            disabled={!draft.trim()}
            onClick={() => {
              onConfirm(draft.trim(), ruleType);
              onOpenChange(false);
            }}
          >
            {isEdit ? "Save" : "Add"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
