"use client";

import React, { useEffect, useMemo, useState } from "react";
import Cookies from "js-cookie";
import { io, type Socket } from "socket.io-client";
import MainTitle from "@/components/layout/dashboard/main-title";
import { useRequireSuperAdmin } from "@/hooks/use-require-super-admin";
import { getApiErrorMessage } from "@/lib/api-error";
import DataService from "@/config/axios";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { Card, CardContent } from "@/components/ui/card";

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 SocialInboxAdmin() {
  const ready = useRequireSuperAdmin();
  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) {
      toast.error(getApiErrorMessage(error, "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) {
      if (showError) toast.error(getApiErrorMessage(error, "Could not load saved Meta messages."));
      setConversationRows([]);
    }
  };

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

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

  useEffect(() => {
    if (!ready) return;
    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
  }, [ready, connectionId, platform]);

  useEffect(() => {
    if (!ready || !connectionId) return;
    const timer = window.setInterval(() => {
      if (document.visibilityState === "visible") {
        void loadSavedInbox(false);
        void loadInbox({ showError: false, withLoading: false });
      }
    }, 15000);
    return () => window.clearInterval(timer);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [ready, connectionId, platform]);

  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) {
      toast.error(getApiErrorMessage(error, "Could not start Meta connect."));
      setConnecting(false);
    }
  };

  const loadInbox = async (opts?: { showError?: boolean; withLoading?: boolean }) => {
    const showError = opts?.showError ?? true;
    const withLoading = opts?.withLoading ?? true;
    if (!connectionId) {
      if (showError) toast.error("Please connect/select a Facebook page first.");
      return;
    }
    if (withLoading) setLoading(true);
    try {
      const res = await DataService.get(`/meta/${platform}/conversations`, {
        params: { connectionId, _ts: Date.now() },
        headers: { "Cache-Control": "no-cache", Pragma: "no-cache" },
      });
      setConversationRows(res.data?.data || []);
    } catch (error) {
      if (showError) {
        toast.error(getApiErrorMessage(error, `Could not load ${platform} conversations.`));
      }
      setConversationRows([]);
    } finally {
      if (withLoading) 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({ withLoading: true });
    } catch (error) {
      toast.error(getApiErrorMessage(error, "Could not send reply."));
    }
  };

  if (!ready) {
    return (
      <div className="rounded-md border bg-white p-8 text-center text-gray-500">Loading...</div>
    );
  }

  return (
    <div className="space-y-6">
      <MainTitle title="Social inbox (Facebook + Instagram)" />

      <Card className="bg-white">
        <CardContent className="space-y-4 p-4">
          <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 connections
            </Button>
            <Button
              type="button"
              variant="secondary"
              onClick={() => {
                void loadInbox();
              }}
              disabled={loading}
            >
              {loading ? "Syncing..." : "Sync conversations"}
            </Button>
          </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">
                <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">
                <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>
                <p className="mt-2 text-xs text-slate-500">
                  Saved webhook messages auto-load. Sync fetches latest from Meta.
                </p>
              </div>

              <div className="max-h-[520px] overflow-y-auto rounded-xl border bg-white">
                {conversations.length === 0 ? (
                  <p className="p-4 text-sm text-slate-500">No messages 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 transition-colors ${
                        item._id === selectedId
                          ? "bg-primary text-white"
                          : "hover:bg-slate-50 text-slate-900"
                      }`}
                      onClick={() => setSelectedId(item._id)}
                    >
                      <p className="font-semibold">
                        {item.customerName || item.customerId || "Customer"}
                      </p>
                      <p
                        className={`mt-1 line-clamp-2 text-xs ${
                          item._id === selectedId ? "text-white/80" : "text-slate-500"
                        }`}
                      >
                        {item.lastMessageText || "No message text"}
                      </p>
                    </button>
                  ))
                )}
              </div>
            </aside>

            <div className="rounded-xl border bg-white">
              {!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>
        </CardContent>
      </Card>
    </div>
  );
}
