"use client";

import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import Cookies from "js-cookie";
import { io, type Socket } from "socket.io-client";
import { toast } from "sonner";

import DataService from "@/config/axios";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";

type MetaConnection = {
  _id: string;
  facebookPageId: string;
  facebookPageName: string;
  instagramBusinessAccountId?: string;
  instagramUsername?: string;
};

type MetaMessage = {
  _id?: string;
  messageId: string;
  senderName?: string;
  text: string;
  isFromBusiness: boolean;
  sentAt: string;
};

type MetaConversation = {
  _id: string;
  platform: "facebook" | "instagram";
  conversationId: string;
  customerId: string;
  customerName?: string;
  lastMessageText?: string;
  lastMessageAt?: string;
  messages?: MetaMessage[];
};

type Platform = "facebook" | "instagram";

const API_ORIGIN = (process.env.NEXT_PUBLIC_API_URL || "").replace(/\/api\/?$/, "");

export default function MetaInboxClient() {
  const [connections, setConnections] = useState<MetaConnection[]>([]);
  const [connectionId, setConnectionId] = useState("");
  const [platform, setPlatform] = useState<Platform>("facebook");
  const [conversations, setConversations] = useState<MetaConversation[]>([]);
  const [selectedId, setSelectedId] = useState("");
  const [reply, setReply] = useState("");
  const [loading, setLoading] = useState(false);
  const [connecting, setConnecting] = useState(false);

  const selectedConnection = useMemo(
    () => connections.find((item) => item._id === connectionId) || null,
    [connections, connectionId],
  );

  const selectedConversation = useMemo(
    () => conversations.find((item) => item._id === selectedId) || null,
    [conversations, selectedId],
  );

  const setConversationRows = (rows: MetaConversation[]) => {
    setConversations(rows);
    setSelectedId((current) => rows.find((row) => row._id === current)?._id || rows[0]?._id || "");
  };

  const loadConnections = async () => {
    try {
      const res = await DataService.get("/meta/connections");
      const rows = res.data?.data || [];
      setConnections(rows);
      setConnectionId((current) => current || rows[0]?._id || "");
    } catch (error: any) {
      if (error?.response?.status === 403) {
        toast.error("Please login before connecting Meta inbox.");
      } else {
        toast.error(error?.response?.data?.message || "Could not load Meta connections.");
      }
    }
  };

  const loadSavedInbox = async (showError = false) => {
    if (!connectionId) {
      setConversationRows([]);
      return;
    }

    try {
      const res = await DataService.get("/meta/saved-conversations", {
        params: { connectionId, platform },
      });
      setConversationRows(res.data?.data || []);
    } catch (error: any) {
      if (showError) {
        toast.error(error?.response?.data?.message || "Could not load saved Meta messages.");
      }
      setConversationRows([]);
    }
  };

  useEffect(() => {
    void loadConnections();
  }, []);

  useEffect(() => {
    void loadSavedInbox();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [connectionId, platform]);

  useEffect(() => {
    const token = Cookies.get("token");
    if (!token || !API_ORIGIN) return;

    const socket: Socket = io(API_ORIGIN, {
      auth: { token },
      transports: ["websocket", "polling"],
    });
    socket.on("meta-message", () => {
      void loadSavedInbox();
    });
    return () => {
      socket.disconnect();
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [connectionId]);

  const connectMeta = async () => {
    setConnecting(true);
    try {
      const res = await DataService.get("/meta/connect-url");
      const url = res.data?.data?.url;
      if (!url) throw new Error("Meta connect URL missing");
      window.location.href = url;
    } catch (error: any) {
      toast.error(error?.response?.data?.message || error?.message || "Could not start Meta connect.");
      setConnecting(false);
    }
  };

  const loadInbox = async () => {
    if (!connectionId) {
      toast.error("Please connect/select a Facebook Page first.");
      return;
    }
    setLoading(true);
    try {
      const res = await DataService.get(`/meta/${platform}/conversations`, {
        params: { connectionId },
      });
      const rows = res.data?.data || [];
      setConversationRows(rows);
    } catch (error: any) {
      toast.error(error?.response?.data?.message || `Could not load ${platform} conversations.`);
      setConversations([]);
      setSelectedId("");
    } finally {
      setLoading(false);
    }
  };

  const sendReply = async () => {
    if (!selectedConversation?.customerId || !reply.trim()) return;
    try {
      await DataService.post("/meta/reply", {
        connectionId,
        platform,
        recipientId: selectedConversation.customerId,
        message: reply.trim(),
      });
      toast.success("Reply sent.");
      setReply("");
      await loadInbox();
    } catch (error: any) {
      toast.error(error?.response?.data?.message || "Could not send reply.");
    }
  };

  return (
    <section className="bg-slate-50 py-10">
      <div className="container">
        <div className="mb-6 flex flex-col gap-3 rounded-xl border bg-white p-5 shadow-sm md:flex-row md:items-center md:justify-between">
          <div>
            <h1 className="text-2xl font-bold text-slate-900">Meta Inbox</h1>
            <p className="mt-1 text-sm text-slate-600">
              Connect your Facebook Page and linked Instagram account to read DMs and reply from Nizamify.
            </p>
          </div>
          <div className="flex flex-wrap gap-2">
            <Button type="button" onClick={connectMeta} disabled={connecting}>
              {connecting ? "Connecting..." : "Connect Facebook / Instagram"}
            </Button>
            <Button type="button" variant="outline" onClick={loadConnections}>
              Refresh
            </Button>
          </div>
        </div>

        <div className="grid gap-4 lg:grid-cols-[320px_1fr]">
          <aside className="space-y-4">
            <div className="rounded-xl border bg-white p-4 shadow-sm">
              <label className="text-sm font-medium text-slate-700">Connected Page</label>
              <select
                className="mt-2 h-10 w-full rounded-md border bg-white px-3 text-sm"
                value={connectionId}
                onChange={(e) => {
                  setConnectionId(e.target.value);
                  setConversations([]);
                  setSelectedId("");
                }}
              >
                <option value="">No page selected</option>
                {connections.map((item) => (
                  <option key={item._id} value={item._id}>
                    {item.facebookPageName || item.facebookPageId}
                  </option>
                ))}
              </select>
              {selectedConnection?.instagramBusinessAccountId ? (
                <p className="mt-2 text-xs text-emerald-700">
                  Instagram linked: @{selectedConnection.instagramUsername || selectedConnection.instagramBusinessAccountId}
                </p>
              ) : (
                <p className="mt-2 text-xs text-slate-500">No linked Instagram business account found.</p>
              )}
            </div>

            <div className="rounded-xl border bg-white p-4 shadow-sm">
              <div className="grid grid-cols-2 gap-2">
                <Button
                  type="button"
                  variant={platform === "facebook" ? "default" : "outline"}
                  onClick={() => {
                    setPlatform("facebook");
                    setConversations([]);
                    setSelectedId("");
                  }}
                >
                  Facebook
                </Button>
                <Button
                  type="button"
                  variant={platform === "instagram" ? "default" : "outline"}
                  onClick={() => {
                    setPlatform("instagram");
                    setConversations([]);
                    setSelectedId("");
                  }}
                >
                  Instagram
                </Button>
              </div>
              <Button type="button" className="mt-3 w-full" variant="secondary" onClick={loadInbox} disabled={loading}>
                {loading ? "Loading..." : "Sync Conversations"}
              </Button>
              <p className="mt-2 text-xs text-slate-500">
                Saved webhook messages load automatically. Sync fetches latest messages from Meta.
              </p>
            </div>

            <div className="max-h-[520px] overflow-y-auto rounded-xl border bg-white shadow-sm">
              {conversations.length === 0 ? (
                <p className="p-4 text-sm text-slate-500">No saved conversations yet.</p>
              ) : (
                conversations.map((item) => (
                  <button
                    key={item._id}
                    type="button"
                    className={`block w-full border-b p-4 text-left last:border-b-0 ${
                      item._id === selectedId ? "bg-primary/10" : "hover:bg-slate-50"
                    }`}
                    onClick={() => setSelectedId(item._id)}
                  >
                    <p className="font-semibold text-slate-900">{item.customerName || item.customerId || "Customer"}</p>
                    <p className="mt-1 line-clamp-2 text-xs text-slate-500">{item.lastMessageText || "No message text"}</p>
                  </button>
                ))
              )}
            </div>
          </aside>

          <div className="rounded-xl border bg-white shadow-sm">
            {!selectedConversation ? (
              <div className="flex min-h-[520px] items-center justify-center p-8 text-center text-slate-500">
                Select a conversation to view messages.
              </div>
            ) : (
              <div className="flex min-h-[520px] flex-col">
                <div className="border-b p-4">
                  <p className="font-semibold text-slate-900">
                    {selectedConversation.customerName || selectedConversation.customerId || "Customer"}
                  </p>
                  <p className="text-xs capitalize text-slate-500">{platform} conversation</p>
                </div>
                <div className="flex-1 space-y-3 overflow-y-auto p-4">
                  {(selectedConversation.messages || []).map((msg) => (
                    <div key={msg.messageId} className={`flex ${msg.isFromBusiness ? "justify-end" : "justify-start"}`}>
                      <div
                        className={`max-w-[75%] rounded-2xl px-4 py-2 text-sm ${
                          msg.isFromBusiness
                            ? "bg-primary text-white"
                            : "bg-slate-100 text-slate-800"
                        }`}
                      >
                        <p>{msg.text || "(attachment or unsupported message)"}</p>
                        <p className={`mt-1 text-[10px] ${msg.isFromBusiness ? "text-white/70" : "text-slate-500"}`}>
                          {msg.sentAt ? new Date(msg.sentAt).toLocaleString() : ""}
                        </p>
                      </div>
                    </div>
                  ))}
                </div>
                <div className="border-t p-4">
                  <Textarea
                    value={reply}
                    onChange={(e) => setReply(e.target.value)}
                    placeholder="Write a reply..."
                    rows={3}
                  />
                  <div className="mt-3 flex items-center justify-between gap-3">
                    <p className="text-xs text-slate-500">Replies follow Meta's 24-hour messaging policy.</p>
                    <Button type="button" onClick={sendReply} disabled={!reply.trim()}>
                      Send Reply
                    </Button>
                  </div>
                </div>
              </div>
            )}
          </div>
        </div>

        <div className="mt-5 rounded-xl border bg-white p-4 text-sm text-slate-600 shadow-sm">
          Webhook URL for Meta Developer Portal:{" "}
          <code className="rounded bg-slate-100 px-1 py-0.5">https://your-domain.com/api/meta/webhook</code>.
          For local testing, expose backend port <code className="rounded bg-slate-100 px-1 py-0.5">4000</code> with ngrok.
          Need setup help? Open the <Link href="/contact-us" className="text-primary hover:underline">Contact Us</Link> page.
        </div>
      </div>
    </section>
  );
}
