'use client';

/**
 * Client-side photo filters using CSS filter -> canvas rasterisation.
 * Outputs a Blob/dataURL the caller can upload.
 */

import { useEffect, useRef, useState } from 'react';
import { Sun, Contrast, Droplet, RotateCcw, Check } from 'lucide-react';

export interface FilterPreset {
  id: string;
  name: string;
  cssFilter: string;
}

export const FILTER_PRESETS: FilterPreset[] = [
  { id: 'none',     name: 'Original',  cssFilter: 'none' },
  { id: 'mono',     name: 'B&W',       cssFilter: 'grayscale(1) contrast(1.1)' },
  { id: 'sepia',    name: 'Sepia',     cssFilter: 'sepia(0.7) saturate(1.2)' },
  { id: 'vintage',  name: 'Vintage',   cssFilter: 'sepia(0.3) contrast(1.1) brightness(0.95) saturate(0.9)' },
  { id: 'cool',     name: 'Cool',      cssFilter: 'hue-rotate(-15deg) saturate(1.2)' },
  { id: 'warm',     name: 'Warm',      cssFilter: 'hue-rotate(15deg) saturate(1.3) brightness(1.05)' },
  { id: 'fade',     name: 'Fade',      cssFilter: 'contrast(0.85) brightness(1.05) saturate(0.9)' },
  { id: 'punch',    name: 'Punch',     cssFilter: 'contrast(1.25) saturate(1.4)' },
];

interface Props {
  source: File | string; // File or URL
  onCancel: () => void;
  onConfirm: (blob: Blob, filterId: string) => void;
}

export default function PhotoFilters({ source, onCancel, onConfirm }: Props) {
  const [imgUrl, setImgUrl] = useState<string>('');
  const [filterId, setFilterId] = useState<string>('none');
  const [brightness, setBrightness] = useState(100);
  const [contrast, setContrast] = useState(100);
  const [saturate, setSaturate] = useState(100);
  const canvasRef = useRef<HTMLCanvasElement>(null);

  useEffect(() => {
    if (typeof source === 'string') { setImgUrl(source); return; }
    const u = URL.createObjectURL(source);
    setImgUrl(u);
    return () => URL.revokeObjectURL(u);
  }, [source]);

  const preset = FILTER_PRESETS.find((p) => p.id === filterId) || FILTER_PRESETS[0];
  const compositeFilter = `${preset.cssFilter === 'none' ? '' : preset.cssFilter} brightness(${brightness}%) contrast(${contrast}%) saturate(${saturate}%)`;

  const apply = async () => {
    const img = new Image();
    img.crossOrigin = 'anonymous';
    img.src = imgUrl;
    await new Promise((res, rej) => { img.onload = res; img.onerror = rej; });
    const canvas = canvasRef.current!;
    canvas.width = img.naturalWidth;
    canvas.height = img.naturalHeight;
    const ctx = canvas.getContext('2d')!;
    ctx.filter = compositeFilter;
    ctx.drawImage(img, 0, 0);
    const blob: Blob = await new Promise((resolve) => canvas.toBlob((b) => resolve(b!), 'image/jpeg', 0.92));
    onConfirm(blob, filterId);
  };

  const reset = () => { setFilterId('none'); setBrightness(100); setContrast(100); setSaturate(100); };

  return (
    <div className="fixed inset-0 z-[120] bg-black flex flex-col">
      <div className="flex items-center justify-between p-4 border-b border-zinc-800">
        <button onClick={onCancel} className="text-sm text-zinc-400 hover:text-white">Cancel</button>
        <h3 className="text-sm font-semibold">Filters & Adjust</h3>
        <button
          onClick={apply}
          className="h-9 px-4 rounded-full bg-amber-300 text-zinc-950 text-sm font-medium flex items-center gap-1 hover:bg-amber-200"
        >
          <Check className="h-4 w-4" /> Done
        </button>
      </div>

      <div className="flex-1 flex items-center justify-center p-4 overflow-hidden">
        {imgUrl && (
          <img
            src={imgUrl}
            alt=""
            className="max-h-full max-w-full object-contain"
            style={{ filter: compositeFilter }}
          />
        )}
      </div>

      <div className="border-t border-zinc-800 p-4 space-y-4">
        <div className="flex gap-2 overflow-x-auto pb-2">
          {FILTER_PRESETS.map((p) => (
            <button
              key={p.id}
              onClick={() => setFilterId(p.id)}
              className={`shrink-0 px-3 h-8 rounded-full text-xs border transition-colors ${
                filterId === p.id
                  ? 'bg-amber-300 text-zinc-950 border-amber-300'
                  : 'bg-zinc-900 text-white border-zinc-700 hover:bg-zinc-800'
              }`}
            >
              {p.name}
            </button>
          ))}
        </div>

        <div className="grid grid-cols-3 gap-3 text-xs">
          <Slider icon={<Sun className="h-3 w-3" />} label="Brightness" value={brightness} onChange={setBrightness} />
          <Slider icon={<Contrast className="h-3 w-3" />} label="Contrast" value={contrast} onChange={setContrast} />
          <Slider icon={<Droplet className="h-3 w-3" />} label="Saturation" value={saturate} onChange={setSaturate} />
        </div>

        <button onClick={reset} className="w-full h-8 rounded-lg border border-zinc-700 text-xs flex items-center justify-center gap-1 hover:bg-zinc-900">
          <RotateCcw className="h-3 w-3" /> Reset
        </button>
      </div>

      <canvas ref={canvasRef} className="hidden" />
    </div>
  );
}

function Slider({ icon, label, value, onChange }: { icon: React.ReactNode; label: string; value: number; onChange: (v: number) => void }) {
  return (
    <div>
      <div className="flex items-center justify-between text-zinc-400">
        <span className="flex items-center gap-1">{icon}{label}</span>
        <span>{value}%</span>
      </div>
      <input
        type="range"
        min={50}
        max={200}
        value={value}
        onChange={(e) => onChange(Number(e.target.value))}
        className="w-full mt-1 accent-amber-300"
      />
    </div>
  );
}
