// Global state
let currentContact = null;
let conversations = [];
let isLoading = false;

const DOM = {
  contactsList: document.getElementById("contactsList"),
  messagesArea: document.getElementById("messagesArea"),
  messageInput: document.getElementById("messageInput"),
  btnSend: document.getElementById("btnSend"),
  chatTitle: document.getElementById("chatTitle"),
  chatSubtitle: document.getElementById("chatSubtitle"),
  myNumberDisplay: document.getElementById("myNumberDisplay"),
  messageInputArea: document.getElementById("messageInputArea"),
  btnNewChat: document.querySelector(".btn-new-chat"),
  btnProvisionNumber: document.getElementById("btnProvisionNumber"),
  modal: document.getElementById("newContactModal"),
  modalOverlay: document.getElementById("modalOverlay"),
  newContactNumber: document.getElementById("newContactNumber"),
  btnCreateContact: document.getElementById("btnCreateContact"),
  closeModal: document.querySelector(".close"),
};

document.addEventListener("DOMContentLoaded", () => {
  setupEventListeners();
  loadConversations();
  setupAutoRefresh();
});

function setupEventListeners() {
  DOM.btnSend.addEventListener("click", sendMessage);
  DOM.messageInput.addEventListener("keydown", (event) => {
    if (event.key === "Enter" && !event.shiftKey) {
      event.preventDefault();
      sendMessage();
    }
  });

  DOM.messageInput.addEventListener("input", () => {
    DOM.messageInput.style.height = "auto";
    DOM.messageInput.style.height =
      Math.min(DOM.messageInput.scrollHeight, 140) + "px";
  });

  DOM.btnNewChat.addEventListener("click", () => showModal(true));
  DOM.modalOverlay.addEventListener("click", () => showModal(false));
  DOM.closeModal.addEventListener("click", () => showModal(false));
  if (DOM.btnProvisionNumber) {
    DOM.btnProvisionNumber.addEventListener("click", provisionNewNumber);
  }
  DOM.btnCreateContact.addEventListener("click", createNewContact);
  DOM.newContactNumber.addEventListener("keydown", (event) => {
    if (event.key === "Enter") {
      createNewContact();
    }
  });
}

async function provisionNewNumber() {
  if (
    !confirm(
      "Are you sure you want to request a new virtual number from Telstra? Your chat history will be kept.",
    )
  ) {
    return;
  }

  try {
    const btn = DOM.btnProvisionNumber;
    btn.innerHTML = "...";
    btn.disabled = true;

    const response = await fetch("api.php?action=provisionNumber", {
      method: "POST",
    });

    const text = await response.text();
    let result;
    try {
      result = JSON.parse(text);
    } catch (err) {
      throw new Error("Provisioning failed with invalid server response.");
    }

    if (!response.ok) {
      throw new Error(
        result.error || `Provisioning failed. HTTP ${response.status}`,
      );
    }

    if (result.success && result.number) {
      if (DOM.myNumberDisplay) {
        DOM.myNumberDisplay.textContent =
          "My Number: " + formatPhoneNumber(result.number);
      }
      alert("Success! Your new Telstra number is: " + result.number);
    } else {
      throw new Error(result.error || "Failed to provision number.");
    }
  } catch (error) {
    alert(error.message || "An error occurred.");
    console.error("Provisioning error:", error);
  } finally {
    if (DOM.btnProvisionNumber) {
      DOM.btnProvisionNumber.innerHTML = `<svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path><line x1="12" y1="2" x2="12" y2="8"></line><line x1="9" y1="5" x2="15" y2="5"></line></svg>`;
      DOM.btnProvisionNumber.disabled = false;
    }
  }
}

function showModal(show) {
  DOM.modal.style.display = show ? "flex" : "none";
  DOM.modalOverlay.style.display = show ? "block" : "none";
  DOM.modal.setAttribute("aria-hidden", show ? "false" : "true");
  if (show) {
    DOM.newContactNumber.value = "";
    DOM.newContactNumber.focus();
  } else {
    DOM.btnNewChat.focus();
  }
}

function createNewContact() {
  const number = DOM.newContactNumber.value.trim();
  if (!number) {
    alert("Please enter a phone number.");
    return;
  }

  const contactNumber = normalizePhoneNumber(number);
  if (!contactNumber) {
    alert(
      "Unable to normalize the phone number. Please try a different format.",
    );
    return;
  }

  if (!conversations.some((conv) => conv.contact === contactNumber)) {
    conversations.unshift({ contact: contactNumber, messages: [] });
    saveConversations();
  }

  showModal(false);
  selectContact(contactNumber);
}

function normalizePhoneNumber(number) {
  let clean = number.replace(/[^0-9\+]/g, "");
  if (clean.startsWith("00")) {
    clean = "+" + clean.slice(2);
  }

  if (!clean.startsWith("+")) {
    if (clean.startsWith("61")) {
      clean = "+" + clean;
    } else if (clean.startsWith("04")) {
      clean = "+61" + clean.slice(1);
    } else {
      clean = "+" + clean;
    }
  }

  return clean;
}

async function loadConversations() {
  try {
    const response = await fetch("api.php?action=getConversations");
    const text = await response.text();
    let data;

    try {
      data = JSON.parse(text);
    } catch (err) {
      throw new Error("Unable to parse conversations response.");
    }

    if (!response.ok) {
      throw new Error(
        data.error || `Unable to fetch conversations. HTTP ${response.status}`,
      );
    }

    if (DOM.myNumberDisplay) {
      DOM.myNumberDisplay.textContent = data.provisionedNumber
        ? "My Number: " + formatPhoneNumber(data.provisionedNumber)
        : "No number provisioned";
    }

    conversations = Array.isArray(data.conversations) ? data.conversations : [];
    conversations.sort((a, b) => {
      const aTime = a.messages.length
        ? a.messages[a.messages.length - 1].timestamp
        : 0;
      const bTime = b.messages.length
        ? b.messages[b.messages.length - 1].timestamp
        : 0;
      return bTime - aTime;
    });

    if (!currentContact && conversations.length) {
      currentContact = conversations[0].contact;
    }

    renderContactsList();
    if (currentContact) {
      selectContact(currentContact);
    }
  } catch (error) {
    console.error("Error loading conversations:", error);
    DOM.contactsList.innerHTML =
      '<div class="sidebar-empty">Unable to load conversations. Please refresh.</div>';
  }
}

function renderContactsList() {
  DOM.contactsList.innerHTML = "";

  if (conversations.length === 0) {
    DOM.contactsList.innerHTML =
      '<div class="sidebar-empty">No conversations yet. Tap + to start a new chat.</div>';
    return;
  }

  conversations.forEach((conv) => {
    const lastMessage = conv.messages[conv.messages.length - 1];
    const preview = lastMessage
      ? lastMessage.body.substring(0, 48)
      : "Start a new conversation";

    const item = document.createElement("button");
    item.type = "button";
    item.className =
      "contact-item" + (currentContact === conv.contact ? " active" : "");
    item.innerHTML = `
            <span class="contact-avatar">${escapeHtml(conv.contact.slice(-2))}</span>
            <span class="contact-details">
                <span class="contact-name">${escapeHtml(formatPhoneNumber(conv.contact))}</span>
                <span class="contact-preview">${escapeHtml(preview)}</span>
            </span>
        `;
    item.addEventListener("click", () => selectContact(conv.contact));
    DOM.contactsList.appendChild(item);
  });
}

function selectContact(contact) {
  currentContact = contact;
  renderContactsList();
  renderMessages();
  DOM.chatTitle.textContent = formatPhoneNumber(contact);
  DOM.chatSubtitle.textContent = contact;
  DOM.messageInputArea.style.display = "flex";
  DOM.messageInput.focus();
}

function renderMessages() {
  DOM.messagesArea.innerHTML = "";
  const conversation = conversations.find(
    (conv) => conv.contact === currentContact,
  );

  if (!conversation || conversation.messages.length === 0) {
    DOM.messagesArea.innerHTML =
      '<div class="empty-state"><p>Send the first message to begin the conversation.</p></div>';
    return;
  }

  conversation.messages.forEach((message) => {
    const bubble = document.createElement("div");
    bubble.className = `message ${message.direction}`;
    bubble.innerHTML = `
            <div class="message-bubble">
                <p>${escapeHtml(message.body)}</p>
                <span class="message-time">${formatMessageTime(message.timestamp)}</span>
            </div>
        `;
    DOM.messagesArea.appendChild(bubble);
  });

  DOM.messagesArea.scrollTop = DOM.messagesArea.scrollHeight;
}

async function sendMessage() {
  if (!currentContact || isLoading) {
    return;
  }

  const text = DOM.messageInput.value.trim();
  if (!text) {
    return;
  }

  if (text.length > 160) {
    alert("Message too long. Please limit to 160 characters.");
    return;
  }

  isLoading = true;
  DOM.btnSend.disabled = true;

  try {
    const response = await fetch("api.php?action=sendMessage", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ to: currentContact, message: text }),
    });

    const text = await response.text();
    let result;
    try {
      result = JSON.parse(text);
    } catch (err) {
      throw new Error("Failed to send your message. Invalid server response.");
    }

    if (!response.ok) {
      throw new Error(
        result.error || `Failed to send your message. HTTP ${response.status}`,
      );
    }

    if (!result.success) {
      throw new Error(result.error || "Failed to send your message.");
    }

    const newMessage = {
      id: result.messageId || "msg_" + Date.now(),
      from: "me",
      to: currentContact,
      body: text,
      timestamp: Math.floor(Date.now() / 1000),
      direction: "sent",
    };

    const conversation = conversations.find(
      (conv) => conv.contact === currentContact,
    );
    if (conversation) {
      conversation.messages.push(newMessage);
    } else {
      conversations.unshift({
        contact: currentContact,
        messages: [newMessage],
      });
    }

    saveConversations();
    renderMessages();
    renderContactsList();
    DOM.messageInput.value = "";
    DOM.messageInput.style.height = "auto";
  } catch (error) {
    alert(error.message || "Unable to send message.");
    console.error("Send message error:", error);
  } finally {
    isLoading = false;
    DOM.btnSend.disabled = false;
  }
}

function saveConversations() {
  fetch("api.php?action=saveConversations", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ conversations }),
  }).catch((error) => console.error("Save conversations failed:", error));
}

function setupAutoRefresh() {
  setInterval(async () => {
    await loadConversations();
    if (currentContact) {
      renderMessages();
    }
  }, 5000);
}

function formatPhoneNumber(number) {
  const cleaned = number.replace(/\D/g, "");
  if (!cleaned) {
    return number;
  }

  if (cleaned.startsWith("61")) {
    const local = cleaned.substring(2);
    return "+61 " + local.replace(/(\d{1,4})(\d{3})(\d{3})/, "$1 $2 $3").trim();
  }

  if (cleaned.startsWith("04")) {
    return (
      "+61 " + cleaned.substring(1).replace(/(\d{3})(\d{3})(\d{3})/, "$1 $2 $3")
    );
  }

  return number;
}

function formatMessageTime(timestamp) {
  return new Date(timestamp * 1000).toLocaleTimeString([], {
    hour: "2-digit",
    minute: "2-digit",
  });
}

function escapeHtml(text) {
  const div = document.createElement("div");
  div.textContent = text;
  return div.innerHTML;
}
