import React, { useState, useEffect, useMemo, useCallback, useRef } from "react";
import { useAppDispatch, useAppSelector } from "../hooks/hooks";
import { formatDateTime } from "../utils/datetime";

import {
    adminSelectConversation,
    approveAdminConversation,
    closeAdminConversation,
    deleteAdminConversation,
    fetchAdminConversations,
    selectAdminConversations,
} from "./features/adminConversationsSlice";

import {
    adminClearMessages,
    fetchChatMessagesForAdmin,
    selectAdminMessages,
    adminSendMessage,
} from "./features/adminMessagesSlice";

import { selectAdminEmailGroups } from "./groupByEmail";


import { MessageList } from "../features/chat/MessageList";
import { MessageInput } from "../features/chat/MessageInput";

import styles from "./AdminApp.module.scss";

export function ChatTab() {
    const dispatch = useAppDispatch();

    const sidebarRef = useRef<HTMLDivElement | null>(null);
    const adminScrollRef = useRef<HTMLDivElement | null>(null);

    const [isScrollLoading, setIsScrollLoading] = useState(false);

    const [emailSearch, setEmailSearch] = useState("");
    const [emailSearchApplied, setEmailSearchApplied] = useState("");
    const isAuthorized = useAppSelector((state) => state.adminConversations.isAuthorized);

    // raw conversations slice – we still use it for selectedId, status, etc.
    const {
        list: conversations,
        selectedId,
        convStatus: convStatus,
        error: convError,
        page,
        perPage,
        total,
    } = useAppSelector(selectAdminConversations);
    console.log("111***111", convError);

    // pre-grouped by email (memoized selector)
    const groups = useAppSelector(selectAdminEmailGroups);

    const filteredGroups = useMemo(() => {
        const q = emailSearchApplied.trim().toLowerCase();
        if (!q) return groups;

        return groups.filter((g) => g.email.toLowerCase().includes(q));
    }, [groups, emailSearchApplied]);


    // admin messages
    const {
        items: messages,
        adminMessagesStatus: msgStatus,
        error: msgError,
    } = useAppSelector(selectAdminMessages);

    const selectedConv = useMemo(
        () => conversations.find((c) => c.id === selectedId) || null,
        [conversations, selectedId]
    );

    const actionButtonLabel = useMemo(() => {
        if (!selectedConv) return "";

        switch (selectedConv.adminConversationStatus) {
            case "pending_approval":
                return "Approve";
            case "approved":
                return "Close";
            case "closed":
                return "Delete";
            default:
                return "Approve";
        }
    }, [selectedConv]);


    const skipNextPollRef = useRef(false);

    const applyEmailSearch = useCallback(() => {
        const q = emailSearch.trim();
        setEmailSearchApplied(q);

        dispatch(fetchAdminConversations({
            page: 1,
            perPage,
            email: q || undefined, // By using undefined, if the string is empty, the email key is effectively removed from the object passed to the thunk.
        }));
    }, [dispatch, emailSearch, perPage]);

    const clearEmailSearch = useCallback(() => {
        setEmailSearch("");
        setEmailSearchApplied("");

        dispatch(fetchAdminConversations({
            page: 1,
            perPage,
            // no email param => full list
        }));
    }, [dispatch, perPage]);

    const sendViaRest = useCallback(
        async (text: string) => {
            if (!selectedConv) return;

            const res = await dispatch(
                adminSendMessage({
                    conversationId: selectedConv.id,
                    content: text,
                })
            );

            // After REST send → refresh messages
            if (adminSendMessage.fulfilled.match(res)) {
                skipNextPollRef.current = true;
                window.setTimeout(() => { skipNextPollRef.current = false; }, 1500);

                dispatch(fetchChatMessagesForAdmin(selectedConv.id));
            }
        },
        [dispatch, selectedConv]
    );


    const onSend = useCallback(
        async (text: string) => {
            if (!selectedConv) return;

            // FREE: always REST
            if (!false) {
                await sendViaRest(text);
                return;
            }

        },
        [
            selectedConv,
            sendViaRest,
            dispatch,
        ]
    );

    useEffect(() => {
        const selectedConvId = selectedConv?.id ?? null;
        if (!selectedConvId || !isAuthorized) return;

        const id = window.setInterval(() => {
            if (skipNextPollRef.current) return;

            dispatch(fetchChatMessagesForAdmin(selectedConvId));
        }, 4000);

        return () => window.clearInterval(id);
    }, [
        selectedConv,
        dispatch,
        isAuthorized
    ]);


    // Load first page on mount
    useEffect(() => {
        dispatch(fetchAdminConversations({
            page: 1,
            perPage,
            email: emailSearchApplied || undefined,
        }));
    }, [dispatch, perPage, emailSearchApplied]);

    // Auto-refresh conversations every 15s
    useEffect(() => {

        if (!isAuthorized) return;

        const id = setInterval(() => {
            // always reload first page so newest convs (like #7) appear
            dispatch(fetchAdminConversations({
                page: 1,
                perPage,
                email: emailSearchApplied || undefined,
            }));
        }, 15000); // every 15s (adjust as you like)

        return () => clearInterval(id);
    }, [
        dispatch,
        perPage,
        emailSearchApplied,
        isAuthorized
    ]);



    useEffect(() => {
        const el = adminScrollRef.current;
        if (!el) return;
        el.scrollTop = el.scrollHeight;
    }, [messages]);

    // Clear messages when no conversation is selected after last conversation is deleted
    useEffect(() => {
        if (!selectedConv) {
            dispatch(adminClearMessages());
        }
    }, [selectedConv, dispatch]);


    const inFlightPageRef = useRef<number | null>(null);

    useEffect(() => {
        inFlightPageRef.current = null;
    }, [page]);

    const loadMore = useCallback(() => {
        const hasMore = conversations.length < total;
        if (!hasMore || convStatus === "loading") return;

        const nextPage = page + 1;

        // prevent duplicate requests for the same nextPage
        if (inFlightPageRef.current === nextPage) return;
        inFlightPageRef.current = nextPage;

        dispatch(fetchAdminConversations({ page: nextPage, perPage, email: emailSearchApplied || undefined, }));
    }, [conversations.length,
        total,
        convStatus,
        page,
        perPage,
        emailSearchApplied,
        dispatch]);

    const handleSidebarScroll = useCallback(
        (e: React.UIEvent<HTMLDivElement>) => {
            const el = e.currentTarget;

            const threshold = 40;
            const isNearBottom =
                el.scrollTop + el.clientHeight >= el.scrollHeight - threshold;

            if (isNearBottom) {
                loadMore();
            }
        },
        [loadMore]
    );

    const autoFillRunsRef = useRef(0);
    const AUTO_FILL_MAX = 20;
    useEffect(() => {
        const el = sidebarRef.current;
        if (!el) return;

        if (autoFillRunsRef.current >= AUTO_FILL_MAX) return;
        if (convStatus === "loading") return;
        if (conversations.length >= total) return;

        const threshold = 40;
        const isScrollable = el.scrollHeight > el.clientHeight + threshold;

        if (!isScrollable) {
            autoFillRunsRef.current += 1;
            loadMore();
        }
    }, [conversations.length, total, convStatus, loadMore]);

    const handleSelectConv = useCallback(
        (id: number) => {
            //console.log("[ADMIN] msgStatus ***", msgStatus);
            dispatch(adminSelectConversation(id));

            // For now we still fetch via REST for admin:
            dispatch(fetchChatMessagesForAdmin(id));
        },
        [dispatch]
    );

    // Auto-select newest conversation (by created_at) if nothing selected
    useEffect(() => {
        if (!selectedId && conversations.length > 0) {
            const newest = [...conversations].sort(
                (a, b) =>
                    new Date(b.created_at).getTime() -
                    new Date(a.created_at).getTime()
            )[0];
            if (newest) {
                handleSelectConv(newest.id);
            }
        }
    }, [selectedId, conversations, handleSelectConv]);

    const handleActionButtonToggle = useCallback(() => {
        if (!selectedConv) return;

        const { adminConversationStatus, id } = selectedConv;

        if (adminConversationStatus === "pending_approval") {
            // 1) Update DB via REST
            dispatch(approveAdminConversation(id));

            return;
        }

        if (adminConversationStatus === "approved") {
            // Close via REST
            dispatch(closeAdminConversation(id));

            return;
        }

        if (adminConversationStatus === "closed") {
            if (!window.confirm("Delete this conversation permanently?")) return;
            dispatch(deleteAdminConversation(id));
        }
    }, [
        dispatch,
        selectedConv,
    ]);


    if (!isAuthorized) {
        return (
            <div className={styles.sessionErrorOverlay}>
                <div className={styles.sessionErrorBox}>
                    <h3>Session Expired</h3>
                    <p>Your WordPress security nonce has expired (likely due to logout or inactivity).</p>
                    <button
                        onClick={() => window.location.reload()}
                        className={styles.refreshButton}
                    >
                        Refresh Page to Login
                    </button>
                </div>
            </div>
        );
    }

    return (
        <div className={styles.zozoChatGlobalClass}>
            <div className={styles.adminHeader}>
                <h1>Zozo Chat Conversations</h1>

                {/* EMAIL SEARCH (always visible) */}
                <div className={styles.emailSearchBar}>
                    <div className={styles.searchInputWrap}>
                        <input
                            type="text"
                            data-test="email-search-input"
                            placeholder="Search email…"
                            value={emailSearch}
                            onChange={(e) => setEmailSearch(e.target.value)}
                            onKeyDown={(e) => {
                                if (e.key === "Enter") applyEmailSearch();
                                if (e.key === "Escape") clearEmailSearch();
                            }}
                        />
                        {emailSearch.length > 0 && (
                            <button
                                type="button"
                                data-test="email-search-clear"
                                className={styles.searchClear}
                                aria-label="Clear search"
                                onClick={clearEmailSearch}
                            >
                                ×
                            </button>
                        )}
                    </div>

                    <button
                        type="button"
                        data-test="email-search-btn"
                        className={styles.searchButton}
                        onClick={applyEmailSearch}
                        disabled={emailSearch.trim().length === 0}
                    >
                        Search
                    </button>
                </div>

                {convError && (
                    <div className={styles.errorText}>
                        <span style={{ fontWeight: 700 }}>{convError.message}</span>

                        {(
                            convError.code === 'rest_cookie_invalid_nonce' ||
                            convError.message === 'Cookie check failed' ||
                            convError.message.toLowerCase().includes('nonce') ||
                            convError.message.toLowerCase().includes('cookie')
                        ) && (
                                <div style={{ marginTop: 8, color: '#d63638' }}>
                                    <strong>Security check expired.</strong> Please refresh the page and try again.
                                    <button
                                        onClick={() => window.location.reload()}
                                        style={{ marginLeft: '10px', cursor: 'pointer' }}
                                    >
                                        Refresh Now
                                    </button>
                                </div>
                            )}

                    </div>
                )}

            </div>
            <div className={styles.adminShell}>

                {/* LEFT: grouped conversations */}
                <aside className={styles.sidebar}>
                    <div className={styles.sidebarHeader}>
                        <h2>Conversations</h2>
                        <button
                            type="button"
                            onClick={() => {
                                dispatch(fetchAdminConversations({
                                    page: 1,
                                    perPage,
                                    email: emailSearchApplied || undefined,
                                }));
                            }}
                        >
                            Refresh
                        </button>
                    </div>

                    <div
                        data-test="conv-list"
                        className={styles.emailGroupList}
                        ref={sidebarRef}
                        onScroll={handleSidebarScroll}
                    >
                        {isScrollLoading && <div className={styles.sideLoader} />}
                        {filteredGroups.map((group) => (
                            <div key={group.email} className={styles.emailGroup}>
                                <div className={styles.emailHeader}>
                                    <div className={styles.emailTitle}>
                                        {convStatus === "loading" && (
                                            <div className={styles.hLoader}><div></div></div>
                                        )}
                                        {group.email}
                                    </div>
                                </div>



                                <div className={styles.emailConversations}>
                                    {group.conversations.map((conv) => {
                                        const isSelected =
                                            conv.id === selectedId;
                                        return (
                                            <button
                                                data-test="conv-item"
                                                key={conv.id}
                                                type="button"
                                                onClick={() =>
                                                    handleSelectConv(conv.id)
                                                }
                                                className={`${styles.conversationItem} ${isSelected
                                                    ? styles.conversationItemSelected
                                                    : ""
                                                    }`}
                                            >
                                                <div
                                                    className={
                                                        styles.conversationTopRow
                                                    }
                                                >
                                                    <span>
                                                        Conversation #{conv.id}
                                                    </span>
                                                    <span
                                                        className={`${styles.statusBadge} ${conv.adminConversationStatus ===
                                                            "approved"
                                                            ? styles.badgeApproved
                                                            : conv.adminConversationStatus ===
                                                                "closed"
                                                                ? styles.badgeClosed
                                                                : styles.badgePending
                                                            }`}
                                                    >
                                                        {conv.adminConversationStatus}
                                                    </span>
                                                </div>
                                                <div
                                                    className={
                                                        styles.conversationMeta
                                                    }
                                                >
                                                    {formatDateTime(
                                                        conv.created_at
                                                    )}
                                                </div>
                                            </button>
                                        );
                                    })}
                                </div>
                            </div>
                        ))}
                        {filteredGroups.length === 0 && (
                            <div className={styles.infoText}>
                                No conversations yet.
                            </div>
                        )}
                    </div>
                </aside>

                <main className={styles.mainPanel}>
                    <header className={styles.mainHeader}>
                        {selectedConv && (
                            <div className={styles.selectedMeta}>
                                <h2>
                                    {selectedConv
                                        ? selectedConv.email
                                        : "Select a conversation"}
                                    <span>Conversation #{selectedConv.id}</span>
                                </h2>

                                <div className={styles.headerButtons}>
                                    <button
                                        data-test="conv-primary-action"
                                        type="button"
                                        className={styles.primaryButton}
                                        onClick={handleActionButtonToggle}
                                    >
                                        {actionButtonLabel}
                                    </button>
                                </div>
                            </div>
                        )}

                        {msgStatus === "loading" && (
                            <span className={styles.refreshing}>Loading…</span>
                        )}
                    </header>

                    <div className={styles.messagesPane}>
                        <div className={styles.messagesScroll} ref={adminScrollRef}>
                            <MessageList
                                messages={messages}
                                error={msgError}
                            />
                        </div>


                        <MessageInput
                            onSend={onSend}
                            {...({
                            })}
                            disabled={!selectedConv}
                        />
                    </div>
                </main>


                {/* RIGHT: details */}
                <section className={styles.sidePanel} data-test="conv-details">

                    <div className={styles.sidebarHeader}>
                        <h3>Details</h3>
                    </div>

                    <div className={styles.detailsBody}>
                        {selectedConv ? (
                            <ul className={styles.detailsList}>
                                <li>
                                    <strong>Email:</strong> {selectedConv.email}
                                </li>
                                <li>
                                    <strong>Status:</strong> {selectedConv.adminConversationStatus}
                                </li>
                                <li>
                                    <strong>Created:</strong>{" "}
                                    {formatDateTime(selectedConv.created_at)}
                                </li>

                                {(selectedConv as any).approved_by_name && (
                                    <li>
                                        <strong>Approved by:</strong>{" "}
                                        {(selectedConv as any).approved_by_name}
                                    </li>
                                )}

                                {selectedConv.approved_at && (
                                    <li>
                                        <strong>Approved:</strong>{" "}
                                        {formatDateTime(selectedConv.approved_at)}
                                    </li>
                                )}

                                {(selectedConv as any).closed_at && (
                                    <li>
                                        <strong>Closed:</strong>{" "}
                                        {formatDateTime((selectedConv as any).closed_at)}
                                    </li>
                                )}

                                {((selectedConv as any).closed_by_name || (selectedConv as any).closed_by) && (
                                    <li>
                                        <strong>Closed by:</strong>{" "}
                                        {(selectedConv as any).closed_by_name ?? (selectedConv as any).closed_by}
                                    </li>
                                )}

                                {(selectedConv as any).closed_source && (
                                    <li>
                                        <strong>Closed source:</strong>{" "}
                                        {(selectedConv as any).closed_source}
                                    </li>
                                )}

                                {(selectedConv as any).closed_outcome && (
                                    <li>
                                        <strong>Closed outcome:</strong>{" "}
                                        {(selectedConv as any).closed_outcome}
                                    </li>
                                )}

                            </ul>
                        ) : (
                            <p className={styles.infoText}>
                                Select a conversation to see details.
                            </p>
                        )}
                    </div>
                </section>
            </div>
        </div>
    );
}