"use client";

import { useState, useEffect, useRef, useMemo } from "react";
import { fetchWithCSRF } from "@/lib/csrf-client";

interface ConversationMessage {
  id: string;
  role: "user" | "assistant" | "staff";
  content: string;
  language: string;
  intent: string | null;
  toolsUsed: string[];
  metadata: Record<string, unknown> | null;
  timestamp: Date;
}

interface Conversation {
  id: string;
  organizationId: string;
  userPhone: string;
  userName: string | null;
  language: string;
  status: string;
  lastMessageAt: Date | null;
  messageCount: number;
  createdAt: Date;
  messages: ConversationMessage[];
  humanControlled: boolean;
  humanControlledAt: string | null;
  humanControlledBy: string | null;
}

interface Booking {
  who: string;
  what: string;
  when: string;
}

interface ConversationSummary {
  topics: string[];
  bookings: Booking[];
  hasBooking: boolean;
  messageCount: number;
  firstMessageAt: Date | null;
  lastMessageAt: Date | null;
}

/** Analyze messages to extract topics and booking information */
function extractSummary(messages: ConversationMessage[]): ConversationSummary {
  const topics = new Set<string>();
  const bookings: Booking[] = [];

  // Booking confirmation patterns
  const bookingPatterns = [
    /(?:booked|confirmed|scheduled|appointment set).*?(?:for|with)\s+(.+?)(?:\s+(?:on|at|for)\s+(.+?))?(?:\.|!|$)/i,
    /viewing.*?(?:booked|confirmed|scheduled).*?(?:for|with)?\s*(.+?)(?:\s+(?:on|at)\s+(.+?))?(?:\.|!|$)/i,
    /(?:appointment|booking|viewing)\s+(?:has been|is)\s+(?:confirmed|booked|scheduled)/i,
  ];

  // Date/time patterns in booking context
  const dateTimePattern =
    /(\d{1,2}(?:\/\d{1,2}\/\d{2,4}|\s+(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\w*\s+\d{2,4}))\s*(?:at\s+)?(\d{1,2}:\d{2}\s*(?:AM|PM)?)?/i;
  const arabicBookingPattern = /(?:تم الحجز|تأكيد الموعد|تم تأكيد|موعد محجوز)/;

  for (const msg of messages) {
    // Extract topics from intents
    if (msg.intent) {
      const intentMap: Record<string, string> = {
        property_search: "Property Search",
        viewing_request: "Viewing Request",
        viewing_management: "Viewing Management",
        company_query: "Company Inquiry",
        appointment_booking: "Appointment Booking",
        appointment_request: "Appointment Request",
        general: "General Inquiry",
        greeting: "Greeting",
        support: "Support",
      };
      const topic = intentMap[msg.intent] || msg.intent.replace(/_/g, " ");
      if (msg.intent !== "off_topic" && msg.intent !== "abuse") {
        topics.add(topic);
      }
    }

    // Only check assistant messages for booking confirmations
    if (msg.role !== "assistant") continue;
    const content = msg.content;

    // Check for Arabic booking confirmations
    if (arabicBookingPattern.test(content)) {
      const nameMatch = content.match(/(?:للسيد|الأخ|السيد|لـ)\s+(\S+)/);
      const dateMatch = content.match(dateTimePattern);
      bookings.push({
        who: nameMatch?.[1] || "Customer",
        what: "Appointment/Viewing",
        when: dateMatch ? dateMatch[0].trim() : "Date in message",
      });
      continue;
    }

    // Check English booking confirmations
    for (const pattern of bookingPatterns) {
      if (pattern.test(content)) {
        // Extract details from the full message
        const nameMatch = content.match(
          /(?:for|with|Mr\.?|Ms\.?|Mrs\.?)\s+([A-Z][a-z]+(?:\s+[A-Z][a-z]+)?)/,
        );
        const propertyMatch = content.match(
          /(?:at|in|for the|property:?|viewing:?)\s+([A-Z][^,.!?\n]{3,40})/,
        );
        const dateMatch = content.match(dateTimePattern);
        const timeMatch = content.match(/(\d{1,2}:\d{2}\s*(?:AM|PM|am|pm))/);

        bookings.push({
          who: nameMatch?.[1] || "Customer",
          what: propertyMatch?.[1]?.trim() || "Viewing/Appointment",
          when:
            [dateMatch?.[0], timeMatch?.[1]].filter(Boolean).join(" ") ||
            "See conversation",
        });
        break;
      }
    }
  }

  const sorted = [...messages].sort(
    (a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime(),
  );

  return {
    topics: Array.from(topics),
    bookings,
    hasBooking: bookings.length > 0,
    messageCount: messages.length,
    firstMessageAt: sorted.length ? new Date(sorted[0].timestamp) : null,
    lastMessageAt: sorted.length
      ? new Date(sorted[sorted.length - 1].timestamp)
      : null,
  };
}

interface ConversationDetailModalProps {
  conversation: Conversation;
  onClose: () => void;
  onConversationUpdate?: (updated: Conversation) => void;
  apiBasePath?: string;
}

export function ConversationDetailModal({
  conversation,
  onClose,
  onConversationUpdate,
  apiBasePath = "/api/staff/whatsapp-conversations",
}: ConversationDetailModalProps) {
  const messagesEndRef = useRef<HTMLDivElement>(null);
  const [reply, setReply] = useState("");
  const [sending, setSending] = useState(false);
  const [messages, setMessages] = useState<ConversationMessage[]>(
    conversation.messages,
  );
  const [isHumanControlled, setIsHumanControlled] = useState(
    conversation.humanControlled,
  );
  const [togglingHandoff, setTogglingHandoff] = useState(false);

  const summary = useMemo(() => extractSummary(messages), [messages]);

  // Scroll to bottom when messages change
  useEffect(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
  }, [messages]);

  // Auto-poll messages every 5 seconds while modal is open
  useEffect(() => {
    const interval = setInterval(async () => {
      try {
        const res = await fetch(`${apiBasePath}/${conversation.id}`);
        const data = await res.json();
        if (data.success && data.data.messages) {
          setMessages(data.data.messages);
          setIsHumanControlled(data.data.humanControlled);
        }
      } catch {
        /* silent */
      }
    }, 5000);
    return () => clearInterval(interval);
  }, [conversation.id, apiBasePath]);

  // Close on Escape key
  useEffect(() => {
    const handleEscape = (e: KeyboardEvent) => {
      if (e.key === "Escape") onClose();
    };
    window.addEventListener("keydown", handleEscape);
    return () => window.removeEventListener("keydown", handleEscape);
  }, [onClose]);

  const [error, setError] = useState<string | null>(null);

  // Send reply handler
  const handleSendReply = async () => {
    if (!reply.trim() || sending) return;
    setSending(true);
    setError(null);
    try {
      const res = await fetchWithCSRF(
        `${apiBasePath}/${conversation.id}/reply`,
        {
          method: "POST",
          body: JSON.stringify({ message: reply.trim() }),
        },
      );
      const data = await res.json();
      if (!res.ok || !data.success) {
        setError(data.error || data.message || "Failed to send reply");
        return;
      }
      const sentMessage = reply.trim();
      setReply("");
      setIsHumanControlled(true);
      // Optimistic: add message to local state
      const newMsg: ConversationMessage = {
        id: data.data?.messageId || `temp-${Date.now()}`,
        role: "staff" as const,
        content: sentMessage,
        language: conversation.language,
        intent: null,
        toolsUsed: [],
        metadata: null,
        timestamp: new Date(),
      };
      setMessages((prev) => [...prev, newMsg]);
      if (onConversationUpdate) {
        onConversationUpdate({
          ...conversation,
          humanControlled: true,
          messages: [...messages, newMsg],
        });
      }
    } catch (err) {
      console.error("Failed to send reply:", err);
      setError("Network error — could not send reply");
    } finally {
      setSending(false);
    }
  };

  // Handoff toggle handler
  const handleHandoffToggle = async () => {
    setTogglingHandoff(true);
    setError(null);
    try {
      const res = await fetchWithCSRF(
        `${apiBasePath}/${conversation.id}/handoff`,
        {
          method: "POST",
          body: JSON.stringify({ humanControlled: !isHumanControlled }),
        },
      );
      const data = await res.json();
      if (!res.ok || !data.success) {
        setError(data.error || "Failed to change mode");
        return;
      }
      const newState = !isHumanControlled;
      setIsHumanControlled(newState);
      if (onConversationUpdate) {
        onConversationUpdate({
          ...conversation,
          humanControlled: newState,
        });
      }
    } catch (err) {
      console.error("Failed to toggle handoff:", err);
      setError("Network error — could not change mode");
    } finally {
      setTogglingHandoff(false);
    }
  };

  // Key press handler for sending with Enter
  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === "Enter" && !e.shiftKey) {
      e.preventDefault();
      handleSendReply();
    }
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50">
      <div className="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-6xl h-[80vh] flex flex-col">
        {/* Header */}
        <div className="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700">
          <div>
            <h3 className="text-xl font-bold text-gray-900 dark:text-white">
              {conversation.userName || "Unknown User"}
            </h3>
            <div className="flex items-center gap-3 mt-1">
              <span className="text-sm text-gray-600 dark:text-gray-400">
                {conversation.userPhone}
              </span>
              <span className="text-xs px-2 py-1 rounded-full bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-400">
                {conversation.language.toUpperCase()}
              </span>
              <span
                className={`text-xs px-2 py-1 rounded-full ${
                  conversation.status === "active"
                    ? "bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-300"
                    : "bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300"
                }`}
              >
                {conversation.status}
              </span>
            </div>
          </div>
          <div className="flex items-center gap-2">
            <button
              onClick={handleHandoffToggle}
              disabled={togglingHandoff}
              className={`px-3 py-1.5 rounded-lg text-sm font-medium transition-colors ${
                isHumanControlled
                  ? "bg-green-100 text-green-700 hover:bg-green-200 dark:bg-green-900 dark:text-green-300"
                  : "bg-orange-100 text-orange-700 hover:bg-orange-200 dark:bg-orange-900 dark:text-orange-300"
              }`}
            >
              {togglingHandoff
                ? "..."
                : isHumanControlled
                  ? "Release to AI"
                  : "Take Over"}
            </button>
            <button
              type="button"
              aria-label="Close conversation detail"
              onClick={onClose}
              className="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
            >
              <svg
                className="w-6 h-6"
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M6 18L18 6M6 6l12 12"
                />
              </svg>
            </button>
          </div>
        </div>

        {/* Error banner */}
        {error && (
          <div className="bg-red-50 dark:bg-red-900/20 px-4 py-2 text-sm text-red-700 dark:text-red-300 flex items-center justify-between">
            <span>{error}</span>
            <button
              onClick={() => setError(null)}
              className="ml-2 text-red-500 hover:text-red-700"
            >
              &times;
            </button>
          </div>
        )}

        {/* Human-controlled banner */}
        {isHumanControlled && (
          <div className="bg-orange-50 dark:bg-orange-900/20 px-4 py-2 text-sm text-orange-700 dark:text-orange-300">
            AI is paused. You are handling this conversation.
          </div>
        )}

        {/* Main content: messages + summary sidebar */}
        <div className="flex-1 flex min-h-0">
          {/* Messages column */}
          <div className="flex-1 flex flex-col min-w-0">
            {/* Messages Container */}
            <div className="flex-1 overflow-y-auto p-4 space-y-4 bg-gray-50 dark:bg-gray-900">
              {messages.length === 0 ? (
                <div className="text-center py-12 text-gray-600 dark:text-gray-400">
                  No messages in this conversation
                </div>
              ) : (
                <>
                  {messages.map((message) => (
                    <div
                      key={message.id}
                      className={`flex ${message.role === "user" ? "justify-end" : "justify-start"}`}
                    >
                      <div
                        className={`max-w-[70%] rounded-lg p-3 ${
                          message.role === "user"
                            ? "bg-green-600 text-white"
                            : message.role === "staff"
                              ? "bg-blue-600 text-white"
                              : "bg-white dark:bg-gray-800 text-gray-900 dark:text-white border border-gray-200 dark:border-gray-700"
                        }`}
                      >
                        {/* Staff label */}
                        {message.role === "staff" && (
                          <div className="text-xs font-semibold mb-1 text-blue-100">
                            Staff
                          </div>
                        )}

                        {/* Message Content */}
                        <div
                          className="text-sm whitespace-pre-wrap break-words"
                          dir={message.language === "ar" ? "rtl" : "ltr"}
                        >
                          {message.content}
                        </div>

                        {/* Timestamp */}
                        <div
                          className={`text-xs mt-1 opacity-70 ${
                            message.role === "user" || message.role === "staff"
                              ? "text-white"
                              : "text-gray-500 dark:text-gray-400"
                          }`}
                        >
                          {new Date(message.timestamp).toLocaleTimeString(
                            "en-US",
                            {
                              hour: "2-digit",
                              minute: "2-digit",
                            },
                          )}
                          {message.role === "staff" && (
                            <span className="ml-1">Staff</span>
                          )}
                          {message.role === "assistant" && (
                            <span className="ml-1">AI</span>
                          )}
                        </div>
                      </div>
                    </div>
                  ))}
                  <div ref={messagesEndRef} />
                </>
              )}
            </div>

            {/* Reply Input */}
            <div className="border-t border-gray-200 dark:border-gray-700 p-3 flex gap-2">
              <textarea
                value={reply}
                onChange={(e) => setReply(e.target.value)}
                onKeyDown={handleKeyDown}
                placeholder="Type a message..."
                rows={1}
                className="flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg resize-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-700 dark:text-white"
              />
              <button
                onClick={handleSendReply}
                disabled={sending || !reply.trim()}
                className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
              >
                {sending ? "..." : "Send"}
              </button>
            </div>
          </div>

          {/* Summary Sidebar */}
          <div className="w-72 border-l border-gray-200 dark:border-gray-700 overflow-y-auto bg-white dark:bg-gray-800 p-4 space-y-5 shrink-0">
            {/* Booking Status */}
            <div>
              <div className="flex items-center gap-2 mb-2">
                <span
                  className={`inline-block w-2.5 h-2.5 rounded-full ${summary.hasBooking ? "bg-green-500" : "bg-gray-400"}`}
                />
                <h4 className="text-sm font-semibold text-gray-900 dark:text-white">
                  Booking Status
                </h4>
              </div>
              {summary.hasBooking ? (
                <div className="space-y-2">
                  {summary.bookings.map((b, i) => (
                    <div
                      key={i}
                      className="bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg p-2.5 text-xs"
                    >
                      <div className="font-medium text-green-800 dark:text-green-300">
                        {b.what}
                      </div>
                      <div className="text-green-700 dark:text-green-400 mt-0.5">
                        {b.who}
                      </div>
                      <div className="text-green-600 dark:text-green-500 mt-0.5">
                        {b.when}
                      </div>
                    </div>
                  ))}
                </div>
              ) : (
                <p className="text-xs text-gray-500 dark:text-gray-400">
                  No appointment booked yet
                </p>
              )}
            </div>

            {/* Topics */}
            {summary.topics.length > 0 && (
              <div>
                <h4 className="text-sm font-semibold text-gray-900 dark:text-white mb-2">
                  Topics Discussed
                </h4>
                <div className="flex flex-wrap gap-1.5">
                  {summary.topics.map((t) => (
                    <span
                      key={t}
                      className="inline-block text-xs px-2 py-1 rounded-full bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-300 border border-blue-200 dark:border-blue-800"
                    >
                      {t}
                    </span>
                  ))}
                </div>
              </div>
            )}

            {/* Stats */}
            <div>
              <h4 className="text-sm font-semibold text-gray-900 dark:text-white mb-2">
                Conversation Info
              </h4>
              <dl className="space-y-1.5 text-xs">
                <div className="flex justify-between">
                  <dt className="text-gray-500 dark:text-gray-400">Messages</dt>
                  <dd className="font-medium text-gray-900 dark:text-white">
                    {summary.messageCount}
                  </dd>
                </div>
                {summary.firstMessageAt && (
                  <div className="flex justify-between">
                    <dt className="text-gray-500 dark:text-gray-400">
                      Started
                    </dt>
                    <dd className="font-medium text-gray-900 dark:text-white">
                      {summary.firstMessageAt.toLocaleDateString("en-US", {
                        month: "short",
                        day: "numeric",
                      })}
                    </dd>
                  </div>
                )}
                {summary.lastMessageAt && (
                  <div className="flex justify-between">
                    <dt className="text-gray-500 dark:text-gray-400">
                      Last msg
                    </dt>
                    <dd className="font-medium text-gray-900 dark:text-white">
                      {summary.lastMessageAt.toLocaleTimeString("en-US", {
                        hour: "2-digit",
                        minute: "2-digit",
                      })}
                    </dd>
                  </div>
                )}
                <div className="flex justify-between">
                  <dt className="text-gray-500 dark:text-gray-400">Language</dt>
                  <dd className="font-medium text-gray-900 dark:text-white">
                    {conversation.language.toUpperCase()}
                  </dd>
                </div>
              </dl>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}
