"use client";

import { useState, useMemo } from "react";
import {
  CalendarIcon,
  ClockIcon,
  TagIcon,
  ArrowLeftIcon,
  PaperAirplaneIcon,
  EnvelopeIcon,
  ChatBubbleLeftIcon,
  PaperClipIcon,
} from "@heroicons/react/24/outline";
import { TicketIcon as TicketIconSolid } from "@heroicons/react/24/solid";
import { PageLayout } from "@/components/templates/PageLayout";
import { AlertBanner } from "@/components/molecules/AlertBanner/AlertBanner";
import { Button, Spinner } from "@/components/atoms";
import { useSupportCase } from "@/features/support/hooks/useSupportCase";
import { useCaseMessages } from "@/features/support/hooks/useCaseMessages";
import { useAddCaseComment } from "@/features/support/hooks/useAddCaseComment";
import {
  getCaseStatusIcon,
  getCaseStatusClasses,
  getCasePriorityClasses,
} from "@/features/support/utils";
import { formatIsoDate, formatIsoRelative } from "@/shared/utils";
import type { CaseMessage } from "@customer-portal/domain/support";
import { CLOSED_STATUSES } from "@customer-portal/domain/support";

const SUPPORT_HREF = "/account/support";

// ============================================================================
// Helper Functions
// ============================================================================

/**
 * Group messages by date for better readability in long conversations
 */
interface MessageGroup {
  date: string;
  dateLabel: string;
  messages: CaseMessage[];
}

function groupMessagesByDate(messages: CaseMessage[]): MessageGroup[] {
  const groups: Map<string, CaseMessage[]> = new Map();

  for (const message of messages) {
    const date = new Date(message.createdAt);
    const dateKey = date.toISOString().split("T")[0]; // YYYY-MM-DD

    if (!dateKey) continue;
    if (!groups.has(dateKey)) {
      groups.set(dateKey, []);
    }
    groups.get(dateKey)?.push(message);
  }

  // Convert to array and add labels
  const today = new Date();
  const yesterday = new Date(today);
  yesterday.setDate(yesterday.getDate() - 1);

  const todayKey = today.toISOString().split("T")[0];
  const yesterdayKey = yesterday.toISOString().split("T")[0];

  return [...groups.entries()].map(([dateKey, msgs]) => {
    let dateLabel: string;
    if (dateKey === todayKey) {
      dateLabel = "Today";
    } else if (dateKey === yesterdayKey) {
      dateLabel = "Yesterday";
    } else {
      // Format as "Mon, Dec 30"
      const date = new Date(dateKey + "T00:00:00");
      dateLabel = date.toLocaleDateString("en-US", {
        weekday: "short",
        month: "short",
        day: "numeric",
      });
    }

    return {
      date: dateKey,
      dateLabel,
      messages: msgs,
    };
  });
}

interface SupportCaseDetailViewProps {
  caseId: string;
}

export function SupportCaseDetailView({ caseId }: SupportCaseDetailViewProps) {
  const { data: supportCase, error, refetch } = useSupportCase(caseId);

  // Show loading until we have data or an error
  const showLoading = !supportCase && !error;
  const {
    data: messagesData,
    isLoading: messagesLoading,
    refetch: refetchMessages,
  } = useCaseMessages(caseId);
  const addCommentMutation = useAddCaseComment(caseId);

  const [replyText, setReplyText] = useState("");

  const pageError =
    error && process.env.NODE_ENV !== "development"
      ? "Unable to load this case right now. Please try again."
      : error;

  const isCaseClosed = supportCase
    ? CLOSED_STATUSES.includes(supportCase.status as (typeof CLOSED_STATUSES)[number])
    : false;

  const handleSubmitReply = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!replyText.trim() || addCommentMutation.isPending) return;

    try {
      await addCommentMutation.mutateAsync({ body: replyText.trim() });
      setReplyText("");
    } catch {
      // Error is handled by the mutation
    }
  };

  // Case not found - only show after loading is complete
  if (!showLoading && !supportCase) {
    return (
      <PageLayout
        icon={<TicketIconSolid />}
        title="Case Not Found"
        breadcrumbs={[
          { label: "Support", href: "/account/support" },
          { label: "Cases", href: "/account/support" },
          { label: "Not Found" },
        ]}
      >
        <AlertBanner variant="error" title="Case not found">
          The support case you&apos;re looking for could not be found or you don&apos;t have
          permission to view it.
        </AlertBanner>
      </PageLayout>
    );
  }

  return (
    <PageLayout
      icon={<TicketIconSolid />}
      title={supportCase ? `Case #${supportCase.caseNumber}` : "Loading..."}
      description={supportCase?.subject}
      loading={showLoading}
      error={pageError}
      onRetry={() => void refetch()}
      breadcrumbs={[
        { label: "Support", href: "/account/support" },
        { label: "Cases", href: "/account/support" },
        { label: supportCase ? `#${supportCase.caseNumber}` : "..." },
      ]}
      actions={
        <Button
          as="a"
          href={SUPPORT_HREF}
          variant="outline"
          leftIcon={<ArrowLeftIcon className="h-4 w-4" />}
        >
          All Cases
        </Button>
      }
    >
      {supportCase && (
        <div className="space-y-6">
          {/* Header Card - Status & Key Info */}
          <div className="border border-border rounded-xl bg-card overflow-hidden shadow-[var(--cp-shadow-1)]">
            {/* Top Section - Status and Priority */}
            <div className="p-5 border-b border-border">
              <div className="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-4">
                <div className="flex items-start gap-3">
                  <div className="mt-0.5">{getCaseStatusIcon(supportCase.status, "md")}</div>
                  <div>
                    <h2 className="text-lg font-semibold text-foreground leading-snug">
                      {supportCase.subject}
                    </h2>
                    <p className="text-sm text-muted-foreground mt-0.5">
                      Case #{supportCase.caseNumber}
                    </p>
                  </div>
                </div>
                <div className="flex flex-wrap gap-2">
                  <span
                    className={`inline-flex items-center px-3 py-1 rounded-lg text-sm font-medium ${getCaseStatusClasses(supportCase.status)}`}
                  >
                    {supportCase.status}
                  </span>
                  <span
                    className={`inline-flex items-center px-3 py-1 rounded-lg text-sm font-medium ${getCasePriorityClasses(supportCase.priority)}`}
                  >
                    {supportCase.priority}
                  </span>
                </div>
              </div>
            </div>

            {/* Meta Info Row */}
            <div className="px-5 py-3 bg-muted/40 flex flex-wrap items-center gap-x-6 gap-y-2 text-sm">
              <div className="flex items-center gap-2 text-muted-foreground">
                <CalendarIcon className="h-4 w-4 text-muted-foreground/70" />
                <span>Created {formatIsoDate(supportCase.createdAt)}</span>
              </div>
              <div className="flex items-center gap-2 text-muted-foreground">
                <ClockIcon className="h-4 w-4 text-muted-foreground/70" />
                <span>Updated {formatIsoRelative(supportCase.updatedAt)}</span>
              </div>
              {supportCase.category && (
                <div className="flex items-center gap-2 text-muted-foreground">
                  <TagIcon className="h-4 w-4 text-muted-foreground/70" />
                  <span>{supportCase.category}</span>
                </div>
              )}
              {supportCase.closedAt && (
                <div className="flex items-center gap-2 text-success">
                  <span>✓ Closed {formatIsoDate(supportCase.closedAt)}</span>
                </div>
              )}
            </div>
          </div>

          {/* Conversation Section */}
          <div className="border border-border rounded-xl bg-card overflow-hidden shadow-[var(--cp-shadow-1)]">
            <div className="px-5 py-3 border-b border-border flex items-center justify-between">
              <h3 className="text-sm font-semibold text-foreground">Conversation</h3>
              <button
                type="button"
                onClick={() => void refetchMessages()}
                className="text-xs text-muted-foreground hover:text-foreground transition-colors"
              >
                Refresh
              </button>
            </div>

            <ConversationThread
              supportCase={supportCase}
              messagesData={messagesData}
              messagesLoading={messagesLoading}
            />

            {/* Reply Form */}
            {!isCaseClosed && (
              <div className="px-5 py-4 border-t border-border bg-muted/20">
                <form onSubmit={handleSubmitReply}>
                  <div className="space-y-3">
                    <textarea
                      value={replyText}
                      onChange={e => setReplyText(e.target.value)}
                      placeholder="Type your reply..."
                      rows={3}
                      className="w-full px-4 py-3 rounded-lg border border-border bg-background text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary resize-none"
                      disabled={addCommentMutation.isPending}
                    />
                    <div className="flex items-center justify-between">
                      <p className="text-xs text-muted-foreground">
                        Your reply will be visible to our support team.
                      </p>
                      <Button
                        type="submit"
                        disabled={!replyText.trim() || addCommentMutation.isPending}
                        leftIcon={
                          addCommentMutation.isPending ? (
                            <Spinner size="sm" />
                          ) : (
                            <PaperAirplaneIcon className="h-4 w-4" />
                          )
                        }
                      >
                        {addCommentMutation.isPending ? "Sending..." : "Send Reply"}
                      </Button>
                    </div>
                    {addCommentMutation.isError && (
                      <p className="text-sm text-destructive">
                        Failed to send reply. Please try again.
                      </p>
                    )}
                  </div>
                </form>
              </div>
            )}

            {/* Closed case notice */}
            {isCaseClosed && (
              <div className="px-5 py-4 border-t border-border bg-muted/20">
                <p className="text-sm text-muted-foreground text-center">
                  This case is closed. If you need further assistance, please{" "}
                  <a href="/account/support/new" className="text-primary hover:underline">
                    create a new case
                  </a>
                  .
                </p>
              </div>
            )}
          </div>
        </div>
      )}
    </PageLayout>
  );
}

// ============================================================================
// Conversation Components
// ============================================================================

interface ConversationThreadProps {
  supportCase: {
    description: string;
    createdAt: string;
  };
  messagesData: { messages: CaseMessage[] } | undefined;
  messagesLoading: boolean;
}

/**
 * Conversation thread with date grouping
 */
function ConversationThread({
  supportCase,
  messagesData,
  messagesLoading,
}: ConversationThreadProps) {
  // Create initial description message
  const descriptionMessage: CaseMessage = useMemo(
    () => ({
      id: "description",
      type: "comment",
      body: supportCase.description,
      author: { name: "You", email: null, isCustomer: true },
      createdAt: supportCase.createdAt,
      direction: null,
    }),
    [supportCase.description, supportCase.createdAt]
  );

  // Combine description with messages and group by date
  const messageGroups = useMemo(() => {
    const allMessages = [descriptionMessage, ...(messagesData?.messages ?? [])];
    return groupMessagesByDate(allMessages);
  }, [descriptionMessage, messagesData?.messages]);

  if (messagesLoading) {
    return (
      <div className="p-5 flex items-center justify-center py-8">
        <Spinner size="md" />
      </div>
    );
  }

  const hasReplies = (messagesData?.messages?.length ?? 0) > 0;

  return (
    <div className="p-5">
      <div className="space-y-6">
        {messageGroups.map(group => (
          <div key={group.date}>
            {/* Date separator */}
            <div className="flex items-center gap-3 mb-4">
              <div className="flex-1 h-px bg-border" />
              <span className="text-xs font-medium text-muted-foreground px-2">
                {group.dateLabel}
              </span>
              <div className="flex-1 h-px bg-border" />
            </div>

            {/* Messages for this date */}
            <div className="space-y-4">
              {group.messages.map(message => (
                <MessageBubble key={message.id} message={message} />
              ))}
            </div>
          </div>
        ))}

        {/* No replies yet message */}
        {!hasReplies && (
          <p className="text-center text-sm text-muted-foreground py-4">
            No replies yet. Our team will respond shortly.
          </p>
        )}
      </div>
    </div>
  );
}

/**
 * Message bubble component for displaying individual messages
 */
function MessageBubble({ message }: { message: CaseMessage }) {
  const isCustomer = message.author.isCustomer;
  const isEmail = message.type === "email";
  const hasAttachment = message.hasAttachment === true;

  return (
    <div className={`flex ${isCustomer ? "justify-end" : "justify-start"}`}>
      <div
        className={`max-w-[85%] rounded-2xl px-4 py-3 ${
          isCustomer
            ? "bg-primary text-primary-foreground rounded-br-md"
            : "bg-muted text-foreground rounded-bl-md"
        }`}
      >
        {/* Author and type indicator */}
        <div
          className={`flex items-center gap-2 mb-1 text-xs ${
            isCustomer ? "text-primary-foreground/70" : "text-muted-foreground"
          }`}
        >
          {isEmail ? (
            <EnvelopeIcon className="h-3 w-3" />
          ) : (
            <ChatBubbleLeftIcon className="h-3 w-3" />
          )}
          <span className="font-medium">{message.author.name}</span>
          <span>•</span>
          <span>{formatIsoRelative(message.createdAt)}</span>
          {hasAttachment && (
            <>
              <span>•</span>
              <span className="inline-flex items-center gap-1">
                <PaperClipIcon className="h-3 w-3" />
                Attachment
              </span>
            </>
          )}
        </div>

        {/* Message body */}
        <p className="whitespace-pre-wrap text-sm leading-relaxed">{message.body}</p>
      </div>
    </div>
  );
}
