import {
  Stack,
  Text,
  Group,
  Button,
  Textarea,
  Badge,
  ActionIcon,
  Loader,
  Paper,
  Divider,
  Tooltip,
} from "@mantine/core";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import {
  useRowComments,
  useCreateRowComment,
  useResolveRowComment,
  useDeleteRowComment,
} from "../hooks/use-row-comments";
import type { RowComment } from "../services/row-comments-client";

interface RowCommentsPanelProps {
  tableId: string;
  rowId: string;
  /** Current user id — used to show own-comment controls */
  currentUserId: string;
}

/**
 * RowCommentsPanel — threaded comment panel for a Baserow row (R3.8).
 *
 * Shows unresolved threads by default; a "Resolved" tab toggles to archived.
 * Compose area creates root comments; "Reply" button creates a child.
 *
 * Architecture note: content is stored as Tiptap JSON on the server but
 * displayed as plain text here. A future enhancement could plug in a
 * read-only Tiptap renderer — out of scope for R3.8 (Notion-like phase 1).
 */
export function RowCommentsPanel({
  tableId,
  rowId,
  currentUserId,
}: RowCommentsPanelProps) {
  const { t } = useTranslation();
  const [showResolved, setShowResolved] = useState(false);
  const [draft, setDraft] = useState("");
  const [replyTo, setReplyTo] = useState<string | null>(null);

  const { data: comments = [], isLoading } = useRowComments(
    tableId,
    rowId,
    showResolved ? true : false,
  );

  const createMutation = useCreateRowComment();
  const resolveMutation = useResolveRowComment();
  const deleteMutation = useDeleteRowComment();

  function tiptapDocFromText(text: string) {
    return JSON.stringify({
      type: "doc",
      content: [{ type: "paragraph", content: [{ type: "text", text }] }],
    });
  }

  function extractText(content: Record<string, unknown> | string): string {
    if (!content) return "";
    const doc =
      typeof content === "string" ? JSON.parse(content) : content;
    if (!doc?.content) return "";
    const texts: string[] = [];
    function walk(node: Record<string, unknown>) {
      if (node.type === "text" && typeof node.text === "string") {
        texts.push(node.text);
      }
      if (Array.isArray(node.content)) {
        (node.content as Record<string, unknown>[]).forEach(walk);
      }
    }
    (doc.content as Record<string, unknown>[]).forEach(walk);
    return texts.join(" ");
  }

  async function handleSubmit() {
    const text = draft.trim();
    if (!text) return;

    await createMutation.mutateAsync({
      tableId,
      rowId,
      content: tiptapDocFromText(text),
      parentCommentId: replyTo ?? undefined,
    });

    setDraft("");
    setReplyTo(null);
  }

  const rootComments = comments.filter((c) => c.parentCommentId === null);

  return (
    <Stack gap="xs">
      {/* Tab toggle */}
      <Group gap="xs">
        <Button
          size="xs"
          variant={!showResolved ? "filled" : "subtle"}
          onClick={() => setShowResolved(false)}
        >
          {t("acadenice.comments.open")}
        </Button>
        <Button
          size="xs"
          variant={showResolved ? "filled" : "subtle"}
          onClick={() => setShowResolved(true)}
        >
          {t("acadenice.comments.resolved")}
        </Button>
      </Group>

      {isLoading && <Loader size="sm" />}

      {!isLoading && rootComments.length === 0 && (
        <Text size="sm" c="dimmed">
          {t("acadenice.comments.empty")}
        </Text>
      )}

      {/* Thread list */}
      {rootComments.map((root) => {
        const replies = comments.filter((c) => c.parentCommentId === root.id);
        return (
          <Paper key={root.id} p="xs" withBorder radius="sm">
            <CommentItem
              comment={root}
              currentUserId={currentUserId}
              tableId={tableId}
              rowId={rowId}
              extractText={extractText}
              onReply={() => setReplyTo(root.id)}
              onResolve={(resolved) =>
                resolveMutation.mutate({
                  commentId: root.id,
                  resolved,
                  tableId,
                  rowId,
                })
              }
              onDelete={() =>
                deleteMutation.mutate({ commentId: root.id, tableId, rowId })
              }
            />

            {replies.map((reply) => (
              <Paper key={reply.id} ml="md" mt="xs" p="xs" withBorder radius="sm">
                <CommentItem
                  comment={reply}
                  currentUserId={currentUserId}
                  tableId={tableId}
                  rowId={rowId}
                  extractText={extractText}
                  onDelete={() =>
                    deleteMutation.mutate({
                      commentId: reply.id,
                      tableId,
                      rowId,
                    })
                  }
                />
              </Paper>
            ))}

            {replyTo === root.id && (
              <Stack gap="xs" mt="xs">
                <Textarea
                  placeholder={t("acadenice.comments.reply_placeholder")}
                  value={draft}
                  onChange={(e) => setDraft(e.currentTarget.value)}
                  minRows={2}
                  autosize
                />
                <Group gap="xs">
                  <Button
                    size="xs"
                    loading={createMutation.isPending}
                    onClick={handleSubmit}
                  >
                    {t("acadenice.comments.send_reply")}
                  </Button>
                  <Button
                    size="xs"
                    variant="subtle"
                    onClick={() => {
                      setReplyTo(null);
                      setDraft("");
                    }}
                  >
                    {t("acadenice.comments.cancel")}
                  </Button>
                </Group>
              </Stack>
            )}
          </Paper>
        );
      })}

      {/* Compose area — new root comment */}
      {!replyTo && !showResolved && (
        <Stack gap="xs" mt="xs">
          <Textarea
            placeholder={t("acadenice.comments.new_placeholder")}
            value={draft}
            onChange={(e) => setDraft(e.currentTarget.value)}
            minRows={2}
            autosize
          />
          <Button
            size="xs"
            loading={createMutation.isPending}
            onClick={handleSubmit}
            disabled={!draft.trim()}
          >
            {t("acadenice.comments.send")}
          </Button>
        </Stack>
      )}
    </Stack>
  );
}

// ---------------------------------------------------------------------------
// Internal: single comment display
// ---------------------------------------------------------------------------

interface CommentItemProps {
  comment: RowComment;
  currentUserId: string;
  tableId: string;
  rowId: string;
  extractText: (content: Record<string, unknown> | string) => string;
  onReply?: () => void;
  onResolve?: (resolved: boolean) => void;
  onDelete?: () => void;
}

function CommentItem({
  comment,
  currentUserId,
  extractText,
  onReply,
  onResolve,
  onDelete,
}: CommentItemProps) {
  const { t } = useTranslation();
  const isOwn = comment.authorUserId === currentUserId;
  const text = extractText(comment.content as Record<string, unknown>);

  return (
    <Stack gap={4}>
      <Group justify="space-between" align="flex-start">
        <Text size="xs" fw={600}>
          {comment.author?.name ?? t("acadenice.comments.unknown_user")}
        </Text>
        <Group gap={4}>
          {comment.isResolved && (
            <Badge size="xs" color="green" variant="light">
              {t("acadenice.comments.resolved_badge")}
            </Badge>
          )}
          {onResolve && !comment.isResolved && (
            <Tooltip label={t("acadenice.comments.resolve_action")}>
              <ActionIcon
                size="xs"
                variant="subtle"
                color="green"
                onClick={() => onResolve(true)}
                aria-label={t("acadenice.comments.resolve_action")}
              >
                &#10003;
              </ActionIcon>
            </Tooltip>
          )}
          {onResolve && comment.isResolved && (
            <Tooltip label={t("acadenice.comments.reopen_action")}>
              <ActionIcon
                size="xs"
                variant="subtle"
                color="gray"
                onClick={() => onResolve(false)}
                aria-label={t("acadenice.comments.reopen_action")}
              >
                &#8635;
              </ActionIcon>
            </Tooltip>
          )}
          {isOwn && onDelete && (
            <Tooltip label={t("acadenice.comments.delete_action")}>
              <ActionIcon
                size="xs"
                variant="subtle"
                color="red"
                onClick={onDelete}
                aria-label={t("acadenice.comments.delete_action")}
              >
                &#10005;
              </ActionIcon>
            </Tooltip>
          )}
        </Group>
      </Group>

      <Text size="sm">{text}</Text>

      {onReply && (
        <Button
          size="xs"
          variant="subtle"
          onClick={onReply}
          mt={2}
        >
          {t("acadenice.comments.reply")}
        </Button>
      )}
    </Stack>
  );
}
