'use client';

import { useEffect, useMemo, useState } from 'react';

type FilterMode = 'All' | 'Active' | 'Pending';
type ComposerMode = 'quick-replies' | 'templates';
type ConversationSummary = {
  id: string;
  name: string;
  initials: string;
  time: string;
  status: string;
  tone: string;
  topic: string;
  snippet: string;
  online: boolean;
  location: string;
  email: string;
  phone: string;
  customerSince: string;
  tags: string[];
  lastActivityAt: string;
  unreadCount: number;
  assignedAgentName: string | null;
};
type ConversationDetail = ConversationSummary & {
  activity: Array<{
    title: string;
    meta: string;
    tone: string;
  }>;
  messages: Array<{
    id: string;
    direction: 'incoming' | 'outgoing';
    body: string;
    time: string;
    status?: string;
  }>;
};

const quickReplies = [
  'Checking this for you now.',
  'Could you share your order ID?',
  'I have escalated this to our support team.',
] as const;

const templateReplies = [
  {
    label: 'Activation Follow-up',
    body: 'Your activation request is being processed. We will share the update shortly.',
  },
  {
    label: 'Shipping Update',
    body: 'Your shipment is in transit and the tracking page will refresh within a few minutes.',
  },
  {
    label: 'Discount Clarification',
    body: 'The enterprise discount is still available for qualifying annual plans.',
  },
] as const;

function conversationPillClassName(tone: string) {
  if (tone === 'warning') return 'conversation-list-pill is-warning';
  if (tone === 'success') return 'conversation-list-pill is-success';
  return 'conversation-list-pill is-info';
}

function getFallbackMessage(name: string) {
  return {
    id: `fallback-${name}`,
    direction: 'incoming' as const,
    body: `No active thread loaded for ${name} yet.`,
    time: '',
  };
}

function normalizeFilter(filter: FilterMode) {
  if (filter === 'Pending') return 'pending';
  if (filter === 'Active') return 'active';
  return 'all';
}

export function ConversationsInbox({
  initialConversations,
  initialConversationDetail,
  initialSearch,
}: {
  initialConversations: ConversationSummary[];
  initialConversationDetail: ConversationDetail | null;
  initialSearch: string;
}) {
  const [items, setItems] = useState<ConversationSummary[]>(initialConversations);
  const [filter, setFilter] = useState<FilterMode>('All');
  const [activeConversationId, setActiveConversationId] = useState<string>(initialConversationDetail?.id ?? initialConversations[0]?.id ?? '');
  const [composerMode, setComposerMode] = useState<ComposerMode>('templates');
  const [composerText, setComposerText] = useState('');
  const [searchTerm] = useState(initialSearch);
  const [activeConversation, setActiveConversation] = useState<ConversationDetail | null>(initialConversationDetail);
  const [isThreadLoading, setIsThreadLoading] = useState(false);
  const [isSending, setIsSending] = useState(false);
  const [isAssigning, setIsAssigning] = useState(false);

  const filteredConversations = useMemo(
    () =>
      items.filter((conversation) =>
        filter === 'All'
          ? true
          : filter === 'Pending'
            ? conversation.status === 'PENDING'
            : conversation.status === 'ACTIVE' || conversation.status === 'NEW',
      ),
    [filter, items],
  );

  useEffect(() => {
    const controller = new AbortController();
    const timeout = window.setTimeout(async () => {
      try {
        const params = new URLSearchParams({ filter: normalizeFilter(filter) });
        if (searchTerm) params.set('search', searchTerm);
        const response = await fetch(`/api/conversations?${params.toString()}`, {
          signal: controller.signal,
          cache: 'no-store',
        });

        if (!response.ok) {
          return;
        }

        const payload = (await response.json()) as ConversationSummary[];
        setItems(payload);
      } catch (error) {
        if ((error as Error).name !== 'AbortError') {
          console.error(error);
        }
      }
    }, 150);

    return () => {
      controller.abort();
      window.clearTimeout(timeout);
    };
  }, [filter, searchTerm]);

  useEffect(() => {
    const nextActiveId =
      filteredConversations.find((conversation) => conversation.id === activeConversationId)?.id
      ?? filteredConversations[0]?.id
      ?? '';

    if (nextActiveId && nextActiveId !== activeConversationId) {
      setActiveConversationId(nextActiveId);
    }
    if (!nextActiveId) {
      setActiveConversationId('');
      setActiveConversation(null);
    }
  }, [activeConversationId, filteredConversations]);

  useEffect(() => {
    if (!activeConversationId) {
      setActiveConversation(null);
      return;
    }

    const controller = new AbortController();
    void (async () => {
      try {
        setIsThreadLoading(true);
        const response = await fetch(`/api/conversations/${activeConversationId}`, {
          signal: controller.signal,
          cache: 'no-store',
        });

        if (!response.ok) {
          return;
        }

        const payload = (await response.json()) as ConversationDetail;
        setActiveConversation(payload);
        setItems((current) =>
          current.map((item) => (item.id === payload.id ? { ...item, ...payload } : item)),
        );
      } catch (error) {
        if ((error as Error).name !== 'AbortError') {
          console.error(error);
        }
      } finally {
        setIsThreadLoading(false);
      }
    })();

    return () => controller.abort();
  }, [activeConversationId]);

  function applySuggestion(text: string) {
    setComposerText(text);
  }

  async function refreshSummaries(nextActiveId?: string) {
    const params = new URLSearchParams({ filter: normalizeFilter(filter) });
    if (searchTerm) params.set('search', searchTerm);
    const response = await fetch(`/api/conversations?${params.toString()}`, {
      cache: 'no-store',
    });

    if (!response.ok) {
      return;
    }

    const payload = (await response.json()) as ConversationSummary[];
    setItems(payload);
    if (nextActiveId && !payload.some((item) => item.id === nextActiveId) && payload[0]?.id) {
      setActiveConversationId(payload[0].id);
    }
  }

  async function assignToMe() {
    if (!activeConversation || isAssigning) {
      return;
    }

    try {
      setIsAssigning(true);
      const response = await fetch(`/api/conversations/${activeConversation.id}/assign`, {
        method: 'POST',
      });
      if (!response.ok) {
        return;
      }

      await refreshSummaries(activeConversation.id);
      const detailResponse = await fetch(`/api/conversations/${activeConversation.id}`, {
        cache: 'no-store',
      });
      if (!detailResponse.ok) {
        return;
      }
      const payload = (await detailResponse.json()) as ConversationDetail;
      setActiveConversation(payload);
    } catch (error) {
      console.error(error);
    } finally {
      setIsAssigning(false);
    }
  }

  function renderOutgoingStatus(status?: string) {
    if (status === 'failed') {
      return <span className="material-symbols-outlined">error</span>;
    }
    if (status === 'read' || status === 'delivered') {
      return <span className="material-symbols-outlined">done_all</span>;
    }
    return <span className="material-symbols-outlined">done</span>;
  }

  async function sendMessage() {
    const nextBody = composerText.trim();
    if (!nextBody || !activeConversation || isSending) {
      return;
    }

    try {
      setIsSending(true);
      const response = await fetch(`/api/conversations/${activeConversation.id}/messages`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ body: nextBody }),
      });

      const payload = await response.json();
      if (!response.ok) {
        throw new Error(payload.message || 'Failed to send message');
      }

      setActiveConversation((current) =>
        current
          ? {
              ...current,
              snippet: nextBody,
              time: 'Just now',
              status: 'ACTIVE',
              tone: 'success',
              messages: [...current.messages, payload.message],
            }
          : current,
      );
      setItems((current) =>
        current.map((conversation) =>
          conversation.id === activeConversation.id
            ? {
                ...conversation,
                snippet: nextBody,
                time: 'Just now',
                status: 'ACTIVE',
                tone: 'success',
              }
            : conversation,
        ),
      );
      setComposerText('');
      setFilter('All');
      await refreshSummaries(activeConversation.id);
    } catch (error) {
      console.error(error);
    } finally {
      setIsSending(false);
    }
  }

  return (
    <section className="conversations-page">
      <div className="conversations-layout">
        <aside className="conversations-sidebar surface-card">
          <div className="conversations-filter-tabs">
            {(['All', 'Active', 'Pending'] as const).map((item) => (
              <button
                key={item}
                type="button"
                className={filter === item ? 'is-active' : undefined}
                onClick={() => setFilter(item)}
              >
                {item}
              </button>
            ))}
          </div>

          <div className="conversations-list custom-scrollbar">
            {filteredConversations.map((conversation) => {
              const isActive = conversation.id === activeConversation?.id;

              return (
                <article
                  key={conversation.id}
                  className={isActive ? 'conversation-list-item is-active' : 'conversation-list-item'}
                  onClick={() => setActiveConversationId(conversation.id)}
                >
                  {isActive ? <span className="conversation-active-rail" /> : null}
                  <div className="conversation-avatar">{conversation.initials}</div>
                  <div className="conversation-list-main">
                    <div className="conversation-list-topline">
                      <h3>{conversation.name}</h3>
                      <span className={isActive ? 'is-recent' : ''}>{conversation.time}</span>
                    </div>
                    <p>{conversation.snippet}</p>
                    <div className="conversation-list-tags">
                      <span className={conversationPillClassName(conversation.tone)}>{conversation.status}</span>
                      {conversation.topic ? <span className="conversation-list-pill is-muted">{conversation.topic}</span> : null}
                      {conversation.unreadCount > 0 ? <span className="conversation-list-pill is-info">{conversation.unreadCount} unread</span> : null}
                    </div>
                  </div>
                </article>
              );
            })}

            {filteredConversations.length === 0 ? (
              <div className="conversations-empty-state">
                <span className="material-symbols-outlined">forum</span>
                <p>No conversations match this filter.</p>
              </div>
            ) : null}
          </div>
        </aside>

        <section className="conversations-thread surface-card">
          <header className="conversations-thread-head">
            <div className="conversations-thread-contact">
              <div className="conversation-avatar is-large">{activeConversation?.initials ?? '--'}</div>
                <div>
                  <h2>{activeConversation?.name ?? 'No conversation selected'}</h2>
                  <div className="conversations-online-row">
                    <span className={`conversations-online-dot ${activeConversation?.online ? 'is-online' : 'is-offline'}`} />
                    <span>{activeConversation?.online ? 'Online' : 'Offline'}</span>
                    {activeConversation?.assignedAgentName ? <span>• {activeConversation.assignedAgentName}</span> : null}
                  </div>
                </div>
              </div>
            <div className="conversations-thread-actions">
              <button type="button" aria-label="Start video call">
                <span className="material-symbols-outlined">videocam</span>
              </button>
              <button type="button" aria-label="Start call">
                <span className="material-symbols-outlined">call</span>
              </button>
              <button type="button" aria-label="More actions">
                <span className="material-symbols-outlined">more_vert</span>
              </button>
            </div>
          </header>

          <div className="conversations-thread-body custom-scrollbar">
            {isThreadLoading ? (
              <div className="conversations-empty-state">
                <span className="material-symbols-outlined">hourglass_top</span>
                <p>Loading conversation...</p>
              </div>
            ) : (
              (activeConversation?.messages.length ? activeConversation.messages : activeConversation ? [getFallbackMessage(activeConversation.name)] : []).map(
                (message) => (
                  <div
                    key={message.id}
                    className={`conversation-message-wrap ${message.direction === 'outgoing' ? 'is-outgoing' : 'is-incoming'}`}
                  >
                    <div className={`conversation-bubble ${message.direction === 'outgoing' ? 'is-outgoing' : 'is-incoming'}`}>
                      <p>{message.body}</p>
                    </div>
                    <div className={`conversation-meta ${message.direction === 'outgoing' ? 'is-outgoing' : 'is-incoming'}`}>
                      <span>{message.time}</span>
                      {message.direction === 'outgoing' ? renderOutgoingStatus(message.status) : null}
                    </div>
                  </div>
                ),
              )
            )}
          </div>

          <footer className="conversations-composer">
            <div className="conversations-composer-tools">
              <button
                type="button"
                className={composerMode === 'quick-replies' ? 'is-active' : undefined}
                onClick={() => setComposerMode('quick-replies')}
              >
                <span className="material-symbols-outlined">auto_awesome</span>
                Quick Replies
              </button>
              <button
                type="button"
                className={composerMode === 'templates' ? 'is-active' : undefined}
                onClick={() => setComposerMode('templates')}
              >
                <span className="material-symbols-outlined">description</span>
                Templates
              </button>
            </div>

            <div className="conversations-composer-suggestions">
              {(composerMode === 'quick-replies' ? quickReplies : templateReplies.map((template) => template.label)).map((item) => (
                <button
                  key={item}
                  type="button"
                  className="conversation-suggestion-chip"
                  onClick={() =>
                    applySuggestion(
                      composerMode === 'quick-replies'
                        ? item
                        : templateReplies.find((template) => template.label === item)?.body ?? item,
                    )
                  }
                >
                  {item}
                </button>
              ))}
            </div>

            <div className="conversations-composer-shell">
              <button type="button" aria-label="Emoji">
                <span className="material-symbols-outlined">sentiment_satisfied</span>
              </button>
              <button type="button" aria-label="Attach file">
                <span className="material-symbols-outlined">attach_file</span>
              </button>
              <textarea
                rows={1}
                placeholder="Type a message..."
                value={composerText}
                onChange={(event) => setComposerText(event.target.value)}
                onKeyDown={(event) => {
                  if (event.key === 'Enter' && !event.shiftKey) {
                    event.preventDefault();
                    void sendMessage();
                  }
                }}
              />
              <button
                type="button"
                className="conversations-send-button"
                aria-label="Send message"
                onClick={() => void sendMessage()}
                disabled={isSending}
              >
                <span className="material-symbols-outlined">send</span>
              </button>
            </div>
          </footer>
        </section>

        <aside className="conversations-profile surface-card">
          <div className="conversations-profile-top">
            <div className="conversation-avatar is-profile">{activeConversation?.initials ?? '--'}</div>
            <h3>{activeConversation?.name ?? 'No conversation selected'}</h3>
            <p>{activeConversation?.location ?? 'Unavailable'}</p>
            <p>{activeConversation?.assignedAgentName ? `Assigned to ${activeConversation.assignedAgentName}` : 'Unassigned conversation'}</p>
            <div className="conversations-profile-actions">
              <button type="button" aria-label="Assign conversation" onClick={() => void assignToMe()} disabled={isAssigning}>
                <span className="material-symbols-outlined">assignment_ind</span>
              </button>
              <button type="button" aria-label="Edit contact">
                <span className="material-symbols-outlined">edit</span>
              </button>
              <button type="button" aria-label="Favorite contact">
                <span className="material-symbols-outlined">star</span>
              </button>
              <button type="button" aria-label="Block contact">
                <span className="material-symbols-outlined">block</span>
              </button>
            </div>
          </div>

          <div className="conversations-profile-scroll custom-scrollbar">
            <section className="conversations-profile-section">
              <h4>Contact Details</h4>
              <div className="conversations-detail-list">
                <div>
                  <span className="material-symbols-outlined">mail</span>
                  <p>{activeConversation?.email ?? 'N/A'}</p>
                </div>
                <div>
                  <span className="material-symbols-outlined">call</span>
                  <p>{activeConversation?.phone ?? 'N/A'}</p>
                </div>
                <div>
                  <span className="material-symbols-outlined">calendar_today</span>
                  <p>{activeConversation?.customerSince ?? 'N/A'}</p>
                </div>
              </div>
            </section>

            <section className="conversations-profile-section">
              <h4>Tags</h4>
              <div className="conversations-tags">
                {activeConversation?.tags.map((tag) => <span key={tag}>{tag}</span>)}
                <button type="button">+ Add Tag</button>
              </div>
            </section>

            <section className="conversations-profile-section">
              <h4>Recent Activity</h4>
              <div className="conversations-activity-list">
                {activeConversation?.activity.map((item) => (
                  <article key={`${item.title}-${item.meta}`} className="conversations-activity-item">
                    <i className={item.tone === 'primary' ? 'is-primary' : 'is-muted'} />
                    <div>
                      <strong>{item.title}</strong>
                      <p>{item.meta}</p>
                    </div>
                  </article>
                ))}
              </div>
            </section>
          </div>

          <div className="conversations-profile-footer">
            <button type="button">View Full CRM Profile</button>
          </div>
        </aside>
      </div>
    </section>
  );
}
