import { useState, useEffect } from "react";
import { useQuery, useMutation } from "@tanstack/react-query";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Textarea } from "@/components/ui/textarea";
import { Label } from "@/components/ui/label";
import { MessageSquare, Send, Loader2, Save } from "lucide-react";
import { useToast } from "@/hooks/use-toast";
import { apiRequest, queryClient } from "@/lib/queryClient";
import type { Patient } from "@repo/db/types";

interface SmsTemplateDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  patient: Patient | null;
}

const DEFAULT_TEMPLATES: Record<string, { name: string; body: string }> = {
  appointment_reminder: {
    name: "Appointment Reminder",
    body: (firstName: string) =>
      `Hi ${firstName}, this is your dental office. Reminder: You have an appointment scheduled. Please confirm or call us if you need to reschedule.`,
  } as any,
  appointment_confirmation: {
    name: "Appointment Confirmation",
    body: (firstName: string) =>
      `Hi ${firstName}, your appointment has been confirmed. We look forward to seeing you! If you have any questions, please call our office.`,
  } as any,
  follow_up: {
    name: "Follow-Up",
    body: (firstName: string) =>
      `Hi ${firstName}, thank you for visiting our dental office. How are you feeling after your treatment? Please let us know if you have any concerns.`,
  } as any,
  payment_reminder: {
    name: "Payment Reminder",
    body: (firstName: string) =>
      `Hi ${firstName}, this is a friendly reminder about your outstanding balance. Please contact our office to discuss payment options.`,
  } as any,
  general: {
    name: "General Message",
    body: (firstName: string) => `Hi ${firstName}, this is your dental office. `,
  } as any,
  custom: {
    name: "Custom Message",
    body: () => "",
  } as any,
};

const TEMPLATE_KEYS = Object.keys(DEFAULT_TEMPLATES);

function getDefaultBody(key: string, firstName: string): string {
  const t = DEFAULT_TEMPLATES[key];
  if (!t) return "";
  return typeof t.body === "function" ? (t.body as any)(firstName) : t.body;
}

export function SmsTemplateDialog({
  open,
  onOpenChange,
  patient,
}: SmsTemplateDialogProps) {
  const [selectedKey, setSelectedKey] = useState("appointment_reminder");
  const [messageText, setMessageText] = useState("");
  const { toast } = useToast();

  const { data: savedTemplates = {} } = useQuery<Record<string, string>>({
    queryKey: ["/api/twilio/templates"],
    enabled: open,
  });

  // Resolve effective body for a given key (saved override or default)
  const resolveBody = (key: string) => {
    if (key === "custom") return "";
    if (savedTemplates[key]) {
      // Replace placeholder first name with actual patient name
      return savedTemplates[key].replace(/^Hi \w+,/, `Hi ${patient?.firstName ?? ""},`);
    }
    return getDefaultBody(key, patient?.firstName ?? "");
  };

  // When dialog opens or template changes, populate message
  useEffect(() => {
    if (open) setMessageText(resolveBody(selectedKey));
  }, [open, selectedKey, savedTemplates, patient?.firstName]);

  const sendMutation = useMutation({
    mutationFn: async (message: string) => {
      return apiRequest("POST", "/api/twilio/send-sms", {
        to: patient!.phone,
        message,
        patientId: patient!.id,
      });
    },
    onSuccess: () => {
      toast({ title: "SMS Sent", description: `Message sent to ${patient?.firstName} ${patient?.lastName}` });
      onOpenChange(false);
      setSelectedKey("appointment_reminder");
      setMessageText("");
    },
    onError: (err: any) => {
      toast({ title: "Failed to Send SMS", description: err.message || "Please check your Twilio configuration.", variant: "destructive" });
    },
  });

  const updateMutation = useMutation({
    mutationFn: async ({ key, body }: { key: string; body: string }) => {
      return apiRequest("PUT", `/api/twilio/templates/${key}`, { body });
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["/api/twilio/templates"] });
      toast({ title: "Template Updated", description: "This template will be used going forward." });
    },
    onError: (err: any) => {
      toast({ title: "Failed to Update Template", description: err.message, variant: "destructive" });
    },
  });

  const handleTemplateChange = (key: string) => {
    setSelectedKey(key);
    setMessageText(resolveBody(key));
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[500px]">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <MessageSquare className="h-5 w-5" />
            Send SMS to {patient?.firstName} {patient?.lastName}
          </DialogTitle>
          <DialogDescription>
            Choose a template or write a custom message
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4 py-4">
          <div className="space-y-2">
            <Label>Message Template</Label>
            <Select value={selectedKey} onValueChange={handleTemplateChange}>
              <SelectTrigger data-testid="select-sms-template">
                <SelectValue placeholder="Select a template" />
              </SelectTrigger>
              <SelectContent>
                {TEMPLATE_KEYS.map((key) => (
                  <SelectItem key={key} value={key}>
                    {DEFAULT_TEMPLATES[key]?.name ?? key}
                    {savedTemplates[key] ? " ✎" : ""}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <div className="space-y-2">
            <div className="flex items-center justify-between">
              <Label>Message</Label>
              {selectedKey !== "custom" && (
                <Button
                  type="button"
                  variant="outline"
                  size="sm"
                  className="h-7 text-xs gap-1"
                  disabled={!messageText.trim() || updateMutation.isPending}
                  onClick={() => updateMutation.mutate({ key: selectedKey, body: messageText })}
                >
                  {updateMutation.isPending ? (
                    <Loader2 className="h-3 w-3 animate-spin" />
                  ) : (
                    <Save className="h-3 w-3" />
                  )}
                  {updateMutation.isPending ? "Saving..." : "Update Template"}
                </Button>
              )}
            </div>
            <Textarea
              value={messageText}
              onChange={(e) => setMessageText(e.target.value)}
              placeholder="Type your message here..."
              rows={5}
              className="resize-none"
              data-testid="textarea-sms-message"
            />
            <p className="text-xs text-muted-foreground">
              {patient?.phone
                ? `Will be sent to: ${patient.phone}`
                : "No phone number available"}
            </p>
          </div>
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button
            onClick={() => sendMutation.mutate(messageText)}
            disabled={!patient?.phone || !messageText.trim() || sendMutation.isPending || !patient}
            className="gap-2"
            data-testid="button-send-sms"
          >
            {sendMutation.isPending ? (
              <Loader2 className="h-4 w-4 animate-spin" />
            ) : (
              <Send className="h-4 w-4" />
            )}
            {sendMutation.isPending ? "Sending..." : "Send SMS"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
