"use client";

import React, { useEffect, useRef, useState } from "react";
import * as d3 from "d3";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "~/components/ui/dialog";

export type D3ImageInfoProps = {
  imageUrl?: string;
  title?: string;
  description?: string;
  width?: number; // fallback width if container size not measured yet
  height?: number; // fallback height
};

/**
 * D3ImageInfo
 * - Renders an image and an information box beside it using D3 within an SVG.
 * - Includes a clickable "show" chip that opens a popup dialog with more details.
 */
export function D3ImageInfo({
  imageUrl = "/placeholder.svg",
  title = "عنوان آیتم",
  description = "توضیحات تکمیلی در مورد این آیتم در این قسمت نمایش داده می‌شود.",
  width = 800,
  height = 360,
}: D3ImageInfoProps) {
  const containerRef = useRef<HTMLDivElement | null>(null);
  const svgRef = useRef<SVGSVGElement | null>(null);
  const [open, setOpen] = useState(false);

  // Redraw helper
  const draw = () => {
    if (!containerRef.current || !svgRef.current) return;

    const container = containerRef.current;
    const svg = d3.select(svgRef.current);

    const W = Math.max(480, container.clientWidth || width);
    const H = Math.max(260, height);

    svg.attr("width", W).attr("height", H);

    // Clear previous content
    svg.selectAll("*").remove();

    // Layout
    const padding = 16;
    const imageAreaWidth = Math.min(300, Math.max(220, W * 0.35));
    const infoAreaX = padding + imageAreaWidth + padding;
    const infoAreaWidth = W - infoAreaX - padding;

    // Image area (with rounded border)
    const imgGroup = svg
      .append("g")
      .attr("transform", `translate(${padding}, ${padding})`);

    const imgW = imageAreaWidth;
    const imgH = H - 2 * padding;

    // Frame
    imgGroup
      .append("rect")
      .attr("width", imgW)
      .attr("height", imgH)
      .attr("rx", 10)
      .attr("ry", 10)
      .attr("fill", "#1F2937") // gray-800
      .attr("stroke", "#4B5563") // gray-600
      .attr("stroke-width", 1.5);

    // Image
    imgGroup
      .append("image")
      .attr("href", imageUrl)
      .attr("x", 4)
      .attr("y", 4)
      .attr("width", imgW - 8)
      .attr("height", imgH - 8)
      .attr("preserveAspectRatio", "xMidYMid slice")
      .attr("clip-path", null);

    // Info area
    const infoGroup = svg
      .append("g")
      .attr("transform", `translate(${infoAreaX}, ${padding})`);

    // Info container
    infoGroup
      .append("rect")
      .attr("width", Math.max(220, infoAreaWidth))
      .attr("height", imgH)
      .attr("rx", 12)
      .attr("ry", 12)
      .attr("fill", "url(#infoGradient)")
      .attr("stroke", "#6B7280") // gray-500
      .attr("stroke-width", 1);

    // Background gradient
    const defs = svg.append("defs");
    const gradient = defs
      .append("linearGradient")
      .attr("id", "infoGradient")
      .attr("x1", "0%")
      .attr("y1", "0%")
      .attr("x2", "0%")
      .attr("y2", "100%");

    gradient.append("stop").attr("offset", "0%").attr("stop-color", "#111827"); // gray-900
    gradient
      .append("stop")
      .attr("offset", "100%")
      .attr("stop-color", "#374151"); // gray-700

    // Title
    infoGroup
      .append("text")
      .attr("x", 16)
      .attr("y", 36)
      .attr("fill", "#F9FAFB") // gray-50
      .attr("font-weight", 700)
      .attr("font-size", 18)
      .text(title);

    // Description (wrapped)
    const wrapText = (text: string, maxWidth: number) => {
      const words = text.split(/\s+/).reverse();
      const lines: string[] = [];
      let line: string[] = [];
      let t = "";
      while (words.length) {
        const word = words.pop()!;
        const test = (t + " " + word).trim();
        // Approximate measure using character count
        const tooLong = test.length * 8 > maxWidth; // 8px avg char width
        if (tooLong && t.length) {
          lines.push(t);
          t = word;
        } else {
          t = test;
        }
      }
      if (t) lines.push(t);
      return lines;
    };

    const descMaxWidth = Math.max(200, infoAreaWidth - 32);
    const descLines = wrapText(description, descMaxWidth);

    descLines.forEach((line, i) => {
      infoGroup
        .append("text")
        .attr("x", 16)
        .attr("y", 70 + i * 22)
        .attr("fill", "#E5E7EB") // gray-200
        .attr("font-size", 14)
        .text(line);
    });

    // Show button-like chip
    const chipY = Math.min(imgH - 48, 70 + descLines.length * 22 + 16);
    const chip = infoGroup
      .append("g")
      .attr("class", "show-chip")
      .style("cursor", "pointer");

    const chipW = 120;
    const chipH = 36;

    chip
      .append("rect")
      .attr("x", 16)
      .attr("y", chipY)
      .attr("width", chipW)
      .attr("height", chipH)
      .attr("rx", 8)
      .attr("ry", 8)
      .attr("fill", "#3B82F6") // blue-500
      .attr("stroke", "#60A5FA")
      .attr("stroke-width", 1.5)
      .attr("opacity", 0.95);

    chip
      .append("text")
      .attr("x", 16 + chipW / 2)
      .attr("y", chipY + chipH / 2 + 5)
      .attr("text-anchor", "middle")
      .attr("fill", "#FFFFFF")
      .attr("font-weight", 700)
      .text("نمایش");

    // Hover & click
    chip
      .on("mouseenter", function () {
        d3.select(this).select("rect").attr("fill", "#2563EB"); // blue-600
      })
      .on("mouseleave", function () {
        d3.select(this).select("rect").attr("fill", "#3B82F6"); // blue-500
      })
      .on("click", () => setOpen(true));
  };

  useEffect(() => {
    const ro = new ResizeObserver(() => draw());
    if (containerRef.current) ro.observe(containerRef.current);
    draw();
    return () => ro.disconnect();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [imageUrl, title, description]);

  return (
    <div className="w-full h-full">
      <div ref={containerRef} className="w-full h-[380px]">
        <svg ref={svgRef} className="block w-full h-full"></svg>
      </div>

      <Dialog open={open} onOpenChange={setOpen}>
        <DialogContent className="sm:max-w-[520px]">
          <DialogHeader>
            <DialogTitle className="font-persian">{title}</DialogTitle>
            <DialogDescription className="font-persian">
              {description}
            </DialogDescription>
          </DialogHeader>
          <div className="mt-4">
            <img
              src={imageUrl}
              alt={title}
              className="w-full h-60 object-cover rounded-md border border-gray-700"
            />
          </div>
        </DialogContent>
      </Dialog>
    </div>
  );
}
