'use client';

import { useEffect, useRef, useState } from 'react';
import { fabric } from 'fabric';
import { useSearchParams } from 'next/navigation';
import { BaseURL } from '../../../../utils/BaseUrl';

export default function TshirtCustomizer() {
  const searchParams = useSearchParams();
  const productSlug = searchParams.get('slug');

  const canvasRef = useRef<fabric.Canvas | null>(null);
  const [shirtColor, setShirtColor] = useState('#ffffff');
  const [textInput, setTextInput] = useState('');
  const [fontFamily, setFontFamily] = useState('Arial');
  const [layers, setLayers] = useState<{ name: string; id: number }[]>([]);
  const [history, setHistory] = useState<any[]>([]);
  const [redoStack, setRedoStack] = useState<any[]>([]);
  const [products, setProducts] = useState<any>(null);
  const [loading, setLoading] = useState(true);
  const [shirtImageObject, setShirtImageObject] = useState<fabric.Image | null>(null);

  useEffect(() => {
    if (productSlug) fetchProducts();
  }, [productSlug]);

  const fetchProducts = async () => {
    try {
      const response = await fetch(`${BaseURL}/products/slug/${productSlug}`);
      const data = await response.json();
      setProducts(data?.data);
      setLoading(false);
    } catch (error) {
      console.error('Error fetching product:', error);
      setLoading(false);
    }
  };

  useEffect(() => {
    const canvas = new fabric.Canvas('tshirt-canvas', {
      width: window.innerWidth < 500 ? 300 : 500,
      height: 600,
    });

    canvasRef.current = canvas;
    saveHistory();
    updateLayers();

    canvas.on('mouse:wheel', (opt) => {
      const delta = opt.e.deltaY;
      let zoom = canvas.getZoom();
      zoom *= 0.999 ** delta;
      zoom = Math.min(Math.max(zoom, 0.5), 2);
      canvas.zoomToPoint({ x: opt.e.offsetX, y: opt.e.offsetY }, zoom);
      opt.e.preventDefault();
      opt.e.stopPropagation();
    });

    canvas.on('object:added', updateLayers);
    canvas.on('object:removed', updateLayers);
    canvas.on('object:modified', saveHistory);
    canvas.on('selection:created', updateLayers);
    canvas.on('selection:updated', updateLayers);

    return () => canvas.dispose();
  }, []);

  useEffect(() => {
    if (products && canvasRef.current) {
      const imageUrl = products?.thumbImage?.[0];

      if (imageUrl) {
        const existing = canvasRef.current
          .getObjects('image')
          .find((img) => (img as fabric.Image).getSrc?.() === imageUrl);

        if (!existing) {
          fabric.Image.fromURL(
            imageUrl,
            (img) => {
              img.set({
                left: 50,
                top: 50,
                scaleX: 0.5,
                scaleY: 0.5,
                selectable: false,
              });
              setShirtImageObject(img);
              canvasRef.current?.add(img);
              canvasRef.current?.sendToBack(img);
              canvasRef.current?.renderAll();
              saveHistory();
            },
            { crossOrigin: 'anonymous' } // ✅ FIXED HERE
          );
        }
      }
    }
  }, [products]);

  const applyColorFilter = (color: string) => {
    const canvas = canvasRef.current;
    if (!canvas || !shirtImageObject) return;

    try {
      const blendColorFilter = new (fabric as any).Image.filters.BlendColor({
        color,
        mode: 'tint',
        alpha: 0.5,
      });

      shirtImageObject.filters = [blendColorFilter];
      shirtImageObject.applyFilters();
      canvas.renderAll();
      saveHistory();
    } catch (err) {
      console.error('Color filter failed:', err);
      alert('Failed to apply color filter. Make sure image is CORS-enabled.');
    }
  };

  const updateLayers = () => {
    const objs = canvasRef.current?.getObjects() || [];
    setLayers(objs.map((obj, i) => ({ name: obj.type + ' ' + (i + 1), id: i })));
  };

  const saveHistory = () => {
    const json = canvasRef.current?.toJSON();
    if (json) setHistory((prev) => [...prev, json.objects]);
    setRedoStack([]);
  };

  const handleUndo = () => {
    if (!canvasRef.current || history.length <= 1) return;
    const last = history[history.length - 2];
    setRedoStack((r) => [canvasRef.current?.toJSON().objects, ...r]);
    canvasRef.current.clear();
    canvasRef.current.loadFromJSON(
      { objects: last },
      canvasRef.current.renderAll.bind(canvasRef.current)
    );
    setHistory((h) => h.slice(0, -1));
  };

  const handleRedo = () => {
    if (!canvasRef.current || redoStack.length === 0) return;
    const next = redoStack[0];
    setRedoStack((r) => r.slice(1));
    setHistory((h) => [...h, next]);
    canvasRef.current.clear();
    canvasRef.current.loadFromJSON(
      { objects: next },
      canvasRef.current.renderAll.bind(canvasRef.current)
    );
  };

  const handleUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files;
    if (!files || !canvasRef.current) return;

    Array.from(files).forEach((file) => {
      const reader = new FileReader();
      reader.onload = () => {
        if (typeof reader.result === 'string') {
          fabric.Image.fromURL(reader.result, (img) => {
            img.scale(0.4).set({ left: 50, top: 50 });
            canvasRef.current?.add(img);
            saveHistory();
          });
        }
      };
      reader.readAsDataURL(file);
    });
  };

  const addText = () => {
    if (!textInput.trim() || !canvasRef.current) return;
    const text = new fabric.Textbox(textInput, {
      left: 100,
      top: 100,
      fontFamily,
      fill: '#000',
      fontSize: 30,
    });
    canvasRef.current.add(text);
    saveHistory();
  };

  const loadTemplate = async () => {
    const res = await fetch('/api/designs/my-template');
    const data = await res.json();
    if (canvasRef.current && data?.json) {
      canvasRef.current.loadFromJSON(
        data.json,
        canvasRef.current.renderAll.bind(canvasRef.current)
      );
    }
  };

  const downloadImage = () => {
    const dataURL = canvasRef.current?.toDataURL({ format: 'png', quality: 1 });
    const link = document.createElement('a');
    link.href = dataURL!;
    link.download = 'tshirt-design.png';
    link.click();
  };

  const deleteObject = (index: number) => {
    const obj = canvasRef.current?.getObjects()[index];
    if (obj) {
      canvasRef.current?.remove(obj);
      updateLayers();
      saveHistory();
    }
  };

  return (
    <div className="product-detail sale sidebar">
      <div className="featured-product underwear md:py-20 py-10">
        <div className="container flex justify-between gap-y-6 flex-wrap max-sm:flex-col-reverse">
          <div className="sidebar lg:w-1/4 sm:w-[40%] lg:pr-12 sm:pr-10 w-full">
            <div className="filter-type pb-8 border-b border-line">
              <div className="heading6">Products Type</div>
            </div>

            <div className="benefit pb-3 border-b border-line mt-3">
              <div className="heading6">T-shirt Color</div>
              <input type="color" value={shirtColor} onChange={(e) => { setShirtColor(e.target.value); applyColorFilter(e.target.value); }} className="w-full h-10 border mb-4" />
            </div>

            <div className="benefit pb-3 border-b border-line mt-3">
              <div className="heading6">Add Text</div>
              <input type="text" value={textInput} onChange={(e) => setTextInput(e.target.value)} className="w-full border mb-2" placeholder="Type text" />
              <select value={fontFamily} onChange={(e) => setFontFamily(e.target.value)} className="w-full p-2 border">
                <option value="Arial">Arial</option>
                <option value="Courier New">Courier New</option>
                <option value="Georgia">Georgia</option>
                <option value="Comic Sans MS">Comic Sans</option>
                <option value="Impact">Impact</option>
              </select>
              <button onClick={addText} className="w-full p-2 bg-black text-white">Add Text</button>
            </div>

            <div className="benefit pb-3 border-b border-line mt-3">
              <div className="heading6">Upload Images</div>
              <input type="file" accept="image/*" onChange={handleUpload} className="mb-2" />
            </div>

            <div className="benefit pb-3 border-b border-line mt-3">
              <div className="heading6">History</div>
              <div className="flex justify-center mt-2 gap-2">
                <button onClick={handleUndo} className="w-full bg-black text-white p-2 mb-2 rounded">Undo</button>
                <button onClick={handleRedo} className="w-full bg-black text-white p-2 mb-2 rounded">Redo</button>
              </div>
            </div>

            <div className="benefit pb-3 border-b border-line mt-3">
              <div className="heading6">Sample</div>
              <div className="flex justify-center mt-2 gap-2">
                <button onClick={loadTemplate} className="w-full p-2 bg-black text-white">Load Sample</button>
                <button onClick={downloadImage} className="w-full p-2 bg-black text-white">Download</button>
              </div>
            </div>

            <div className="benefit pb-3 border-b border-line mt-3 ">
              <div className="heading6">Canvas Controls</div>
              <div className="flex gap-2 mt-2">
                <button onClick={() => canvasRef.current?.setZoom(canvasRef.current.getZoom() + 0.1)} className="w-full p-2 bg-black text-white">Zoom In</button>
                <button onClick={() => canvasRef.current?.setZoom(canvasRef.current.getZoom() - 0.1)} className="w-full p-2 bg-black text-white">Zoom Out</button>
              </div>
              <button
                onClick={() => {
                  if (!canvasRef.current) return;
                  const canvas = canvasRef.current;
                  let isDragging = false;
                  let lastPosX = 0;
                  let lastPosY = 0;

                  canvas.on('mouse:down', function (opt) {
                    const evt = opt.e;
                    isDragging = true;
                    lastPosX = evt.clientX;
                    lastPosY = evt.clientY;
                    canvas.setCursor('grab');
                  });

                  canvas.on('mouse:move', function (opt) {
                    if (isDragging) {
                      const e = opt.e;
                      const vpt = canvas.viewportTransform!;
                      vpt[4] += e.clientX - lastPosX;
                      vpt[5] += e.clientY - lastPosY;
                      canvas.requestRenderAll();
                      lastPosX = e.clientX;
                      lastPosY = e.clientY;
                    }
                  });

                  canvas.on('mouse:up', function () {
                    isDragging = false;
                    canvas.setCursor('default');
                  });
                }}
                className="w-full p-2 bg-yellow-500 text-black mt-2 bg-black text-white"
              >
                Enable Pan
              </button>
            </div>

            <div className="benefit pb-3 border-b border-line mt-3">
              <div className="heading6">Object Tools</div>
              <button onClick={() => {
                const obj = canvasRef.current?.getActiveObject();
                if (obj) {
                  canvasRef.current.remove(obj);
                  updateLayers();
                  saveHistory();
                }
              }} className="w-full p-2 mt-2 bg-black text-white">Delete Selected</button>
              <button onClick={() => canvasRef.current?.clear()} className="w-full p-2  mt-2 bg-black text-white">Clear Canvas</button>
              <button onClick={() => {
                const obj = canvasRef.current?.getActiveObject();
                if (obj) canvasRef.current.bringForward(obj);
              }} className="w-full p-2 mt-2 bg-black text-white">Bring Forward</button>
              <button onClick={() => {
                const obj = canvasRef.current?.getActiveObject();
                if (obj) canvasRef.current.sendBackwards(obj);
              }} className="w-full p-2 mt-2 bg-black text-white">Send Backward</button>
            </div>

            <div className="heading6 mt-4">Layers</div>
            <ul className="list-disc list-inside text-sm mt-2">
              {layers.map((layer, index) => (
                <li key={layer.id} className="flex justify-between">
                  <span>{layer.name}</span>
                  <button
                    onClick={() => {
                      const obj = canvasRef.current?.getObjects()[layer.id];
                      if (obj) {
                        canvasRef.current?.remove(obj);
                        updateLayers();
                        saveHistory();
                      }
                    }}
                    className="bg-black text-white"
                  >
                    Delete
                  </button>
                </li>
              ))}
            </ul>
          </div>


          <div className="right lg:w-3/4 sm:w-[60%] sm:pl-3 w-full">
            <canvas id="tshirt-canvas" className="border w-full w-100" />
          </div>
        </div>
      </div>
    </div>
  );
}
