"use client";

// Plain, static renderer for printing/exporting a note — always white paper,
// never the note's on-screen cover theme. Mirrors the same safe approach as
// TemplateContentPreview (inert JSON walk, no live NodeViews) since nothing
// here should be interactive or trigger side effects.
//
// Text never gets its own color class here — it all inherits the chosen
// print color from the wrapper via `color: inherit`, with opacity classes
// only (never a competing color) for secondary/muted elements.

import type { ReactNode } from "react";
import { getSticker } from "@/lib/notes/note-stickers";

interface TiptapNode {
  type?: string;
  attrs?: Record<string, unknown>;
  content?: TiptapNode[];
  text?: string;
  marks?: Array<{ type: string }>;
}

function renderText(node: TiptapNode, key: number): ReactNode {
  let el: ReactNode = node.text ?? "";
  for (const mark of node.marks || []) {
    if (mark.type === "bold") el = <strong key={key}>{el}</strong>;
    if (mark.type === "italic") el = <em key={key}>{el}</em>;
  }
  return el;
}

function renderInline(nodes: TiptapNode[] | undefined): ReactNode {
  return (nodes || []).map((n, i) => (n.type === "text" ? <span key={i}>{renderText(n, i)}</span> : null));
}

function renderBlock(node: TiptapNode, key: string): ReactNode {
  switch (node.type) {
    case "heading": {
      const level = Math.min((node.attrs?.level as number) || 2, 3);
      return (
        <div
          key={key}
          className={
            "mt-5 first:mt-0 font-bold text-inherit " +
            (level === 1 ? "text-[22px]" : level === 2 ? "text-[17px]" : "text-[14px]")
          }
        >
          {renderInline(node.content)}
        </div>
      );
    }
    case "paragraph":
      return (
        <p key={key} className="text-[13px] leading-relaxed text-inherit opacity-85">
          {renderInline(node.content)}
        </p>
      );
    case "bulletList":
    case "orderedList":
      return (
        <ul key={key} className="list-disc space-y-1 pl-5 text-[13px] text-inherit opacity-85">
          {(node.content || []).map((item, i) => (
            <li key={i}>{renderInline(item.content?.[0]?.content)}</li>
          ))}
        </ul>
      );
    case "taskList":
      return (
        <div key={key} className="space-y-1">
          {(node.content || []).map((item, i) => (
            <div key={i} className="flex items-center gap-2 text-[13px] text-inherit opacity-85">
              <span className="inline-block h-3.5 w-3.5 shrink-0 rounded-sm border border-current text-center text-[10px] leading-[13px] opacity-60">
                {item.attrs?.checked ? "✓" : ""}
              </span>
              {renderInline(item.content?.[0]?.content)}
            </div>
          ))}
        </div>
      );
    case "actionChecklist": {
      const items = (node.attrs?.items as Array<{ text: string; done: boolean }>) || [];
      return (
        <div key={key} className="space-y-1">
          {items.map((item, i) => (
            <div key={i} className="flex items-center gap-2 text-[13px] text-inherit opacity-85">
              <span className="inline-block h-3.5 w-3.5 shrink-0 rounded-sm border border-current text-center text-[10px] leading-[13px] opacity-60">
                {item.done ? "✓" : ""}
              </span>
              {item.text}
            </div>
          ))}
        </div>
      );
    }
    case "blockquote":
      return (
        <blockquote key={key} className="border-l-2 border-current pl-3 text-[13px] italic text-inherit opacity-70">
          {(node.content || []).map((p, i) => renderBlock(p, `${key}-${i}`))}
        </blockquote>
      );
    case "table":
      return (
        <table key={key} className="w-full border-collapse text-[12px] text-inherit">
          <tbody>
            {(node.content || []).map((row, ri) => (
              <tr key={ri}>
                {(row.content || []).map((cell, ci) => {
                  const Tag = cell.type === "tableHeader" ? "th" : "td";
                  return (
                    <Tag
                      key={ci}
                      className={
                        "border border-current/20 px-2 py-1 text-left align-top opacity-85 " +
                        (cell.type === "tableHeader" ? "font-semibold" : "")
                      }
                    >
                      {renderInline(cell.content?.[0]?.content)}
                    </Tag>
                  );
                })}
              </tr>
            ))}
          </tbody>
        </table>
      );
    case "chartBlock": {
      const dataSource = node.attrs?.dataSource as { type?: string } | null;
      const data = (node.attrs?.data as Array<{ label: string; value: number }>) || [];
      const max = Math.max(1, ...data.map((d) => d.value));
      return (
        <div key={key} className="rounded border border-current/15 p-3 text-inherit">
          <p className="mb-2 text-[11.5px] font-semibold opacity-80">{String(node.attrs?.title || "Chart")}</p>
          {dataSource ? (
            <p className="text-[11px] opacity-50">Live chart — open the note to see current values.</p>
          ) : (
            <div className="flex h-14 items-end gap-1.5">
              {data.map((d, i) => (
                <div
                  key={i}
                  className="flex-1 rounded-t bg-current opacity-60"
                  style={{ height: `${(d.value / max) * 100}%` }}
                />
              ))}
            </div>
          )}
        </div>
      );
    }
    case "noteImage": {
      const src = node.attrs?.src as string | null;
      if (!src) return null;
      // eslint-disable-next-line @next/next/no-img-element
      return <img key={key} src={src} alt={(node.attrs?.alt as string) || ""} className="max-h-72 w-full rounded object-cover" />;
    }
    case "stickerBlock": {
      const sticker = getSticker(node.attrs?.stickerId as string);
      return (
        <span key={key} className="inline-block text-xl">
          {sticker.emoji}
        </span>
      );
    }
    case "noteLink":
      return (
        <p key={key} className="text-[12.5px] text-inherit opacity-50">
          🔗 Linked sub-page
        </p>
      );
    case "reminderBlock":
      return (
        <p key={key} className="text-[12.5px] text-inherit opacity-50">
          ⏰ Reminder
        </p>
      );
    default:
      return null;
  }
}

interface NotePrintContentProps {
  title: string;
  content: Record<string, unknown>;
  textColor: string;
  grayscale: boolean;
}

export function NotePrintContent({ title, content, textColor, grayscale }: NotePrintContentProps) {
  const nodes = (content?.content as TiptapNode[]) || [];
  return (
    <div className="note-print-area" style={{ filter: grayscale ? "grayscale(1)" : undefined, background: "#ffffff" }}>
      <div className="mx-auto max-w-[720px] px-10 py-12" style={{ color: textColor }}>
        <h1 className="mb-6 text-[26px] font-bold text-inherit">{title || "Untitled"}</h1>
        <div className="space-y-3">{nodes.map((node, i) => renderBlock(node, `n-${i}`))}</div>
      </div>
    </div>
  );
}
