﻿"use client";

import {
  AlignCenter,
  AlignLeft,
  AlignRight,
  Bold,
  Copy,
  Italic,
  RotateCw,
  Trash2,
  Underline,
} from "lucide-react";
import type { FabricObject } from "fabric";
import { Button } from "@/components/ui/button";
import { FONT_FAMILIES, isTextObject } from "@/lib/editor/objects";

export interface PagePanelInfo {
  pageNo: number;
  pageCount: number;
  width: number;
  height: number;
}

interface PropertiesPanelProps {
  selected: FabricObject | null;
  selectedCount: number;
  /** Bumped by the shell on object:modified so the panel re-reads values. */
  version: number;
  page: PagePanelInfo | null;
  onChange: () => void;
  onDelete: () => void;
  onDuplicate: () => void;
  onRotatePage: () => void;
  onDuplicatePage: () => void;
  onDeletePage: () => void;
}

const labelCls = "mb-1 block text-xs font-medium text-slate-500 dark:text-slate-400";
const fieldCls =
  "h-9 w-full rounded-md border border-slate-300 bg-white px-2 text-sm text-slate-900 dark:border-slate-600 dark:bg-slate-800 dark:text-slate-100";

function ToggleButton({
  icon: Icon,
  active,
  label,
  onClick,
}: {
  icon: React.ComponentType<{ className?: string }>;
  active: boolean;
  label: string;
  onClick: () => void;
}) {
  return (
    <button
      type="button"
      aria-label={label}
      aria-pressed={active}
      onClick={onClick}
      className={`flex h-8 w-8 items-center justify-center rounded-md border transition-colors ${
        active
          ? "border-brand-600 bg-brand-600 text-white"
          : "border-slate-300 text-slate-600 hover:bg-slate-100 dark:border-slate-600 dark:text-slate-300 dark:hover:bg-slate-700"
      }`}
    >
      <Icon className="h-4 w-4" />
    </button>
  );
}

export function PropertiesPanel(props: PropertiesPanelProps) {
  const { selected, selectedCount, page, onChange } = props;

  function set(values: Record<string, unknown>) {
    if (!selected) return;
    selected.set(values);
    selected.setCoords();
    onChange();
  }

  function header(title: string) {
    return (
      <div className="flex items-center justify-between border-b border-slate-200 px-3 py-2.5 dark:border-slate-700">
        <span className="text-sm font-semibold text-slate-800 dark:text-slate-200">{title}</span>
        {selected && (
          <div className="flex gap-1">
            <ToggleButton icon={Copy} active={false} label="Duplicate" onClick={props.onDuplicate} />
            <ToggleButton icon={Trash2} active={false} label="Delete" onClick={props.onDelete} />
          </div>
        )}
      </div>
    );
  }

  // ---------- nothing / multi selection ----------

  if (!selected || selectedCount > 1) {
    return (
      <aside className="flex w-60 shrink-0 flex-col overflow-y-auto border-l border-slate-200 bg-white dark:border-slate-700 dark:bg-slate-800">
        {header(selectedCount > 1 ? `${selectedCount} objects` : "Page")}
        <div className="space-y-4 p-3">
          {selectedCount > 1 ? (
            <div className="flex gap-2">
              <Button variant="secondary" size="sm" className="flex-1" onClick={props.onDuplicate}>
                <Copy className="h-4 w-4" /> Duplicate
              </Button>
              <Button variant="destructive" size="sm" className="flex-1" onClick={props.onDelete}>
                <Trash2 className="h-4 w-4" /> Delete
              </Button>
            </div>
          ) : page ? (
            <>
              <p className="text-xs text-slate-500 dark:text-slate-400">
                Page {page.pageNo} of {page.pageCount} — {Math.round(page.width)} × {Math.round(page.height)} pt
              </p>
              <div className="space-y-2">
                <Button variant="secondary" size="sm" className="w-full" onClick={props.onRotatePage}>
                  <RotateCw className="h-4 w-4" /> Rotate page 90°
                </Button>
                <Button variant="secondary" size="sm" className="w-full" onClick={props.onDuplicatePage}>
                  <Copy className="h-4 w-4" /> Duplicate page
                </Button>
                <Button
                  variant="destructive"
                  size="sm"
                  className="w-full"
                  disabled={page.pageCount <= 1}
                  onClick={props.onDeletePage}
                >
                  <Trash2 className="h-4 w-4" /> Delete page
                </Button>
              </div>
              <p className="text-xs leading-5 text-slate-400 dark:text-slate-500">
                Select an object on the canvas to edit its properties. Drag page thumbnails below to reorder.
              </p>
            </>
          ) : null}
        </div>
      </aside>
    );
  }

  // ---------- single object ----------

  const text = isTextObject(selected) ? selected : null;
  const opacity = selected.opacity ?? 1;
  const angle = Math.round(selected.angle ?? 0);
  const isImage = selected.isType("image");

  return (
    <aside className="flex w-60 shrink-0 flex-col overflow-y-auto border-l border-slate-200 bg-white dark:border-slate-700 dark:bg-slate-800">
      {header(text ? "Text" : isImage ? "Image" : "Shape")}
      <div className="space-y-4 p-3">
        {text && (
          <>
            <div>
              <label className={labelCls}>Font</label>
              <select
                className={fieldCls}
                value={String(text.fontFamily ?? "Helvetica")}
                onChange={(e) => set({ fontFamily: e.target.value })}
              >
                {FONT_FAMILIES.map((f) => (
                  <option key={f} value={f}>
                    {f}
                  </option>
                ))}
              </select>
            </div>
            <div className="grid grid-cols-2 gap-2">
              <div>
                <label className={labelCls}>Size</label>
                <input
                  type="number"
                  min={6}
                  max={200}
                  className={fieldCls}
                  value={Math.round(Number(text.fontSize ?? 14))}
                  onChange={(e) => set({ fontSize: Number(e.target.value) || 14 })}
                />
              </div>
              <div>
                <label className={labelCls}>Color</label>
                <input
                  type="color"
                  className="h-9 w-full cursor-pointer rounded-md border border-slate-300 bg-white p-1 dark:border-slate-600 dark:bg-slate-800"
                  value={typeof selected.fill === "string" && selected.fill.startsWith("#") ? selected.fill : "#111827"}
                  onChange={(e) => set({ fill: e.target.value })}
                />
              </div>
            </div>
            <div className="flex gap-1.5">
              <ToggleButton
                icon={Bold}
                label="Bold"
                active={text.fontWeight === "bold"}
                onClick={() => set({ fontWeight: text.fontWeight === "bold" ? "normal" : "bold" })}
              />
              <ToggleButton
                icon={Italic}
                label="Italic"
                active={text.fontStyle === "italic"}
                onClick={() => set({ fontStyle: text.fontStyle === "italic" ? "normal" : "italic" })}
              />
              <ToggleButton
                icon={Underline}
                label="Underline"
                active={Boolean(text.underline)}
                onClick={() => set({ underline: !text.underline })}
              />
              <span className="mx-0.5 w-px bg-slate-200 dark:bg-slate-700" />
              {(
                [
                  ["left", AlignLeft],
                  ["center", AlignCenter],
                  ["right", AlignRight],
                ] as const
              ).map(([align, Icon]) => (
                <ToggleButton
                  key={align}
                  icon={Icon}
                  label={`Align ${align}`}
                  active={text.textAlign === align}
                  onClick={() => set({ textAlign: align })}
                />
              ))}
            </div>
            <div className="grid grid-cols-2 gap-2">
              <div>
                <label className={labelCls}>Letter spacing</label>
                <input
                  type="number"
                  min={-200}
                  max={800}
                  step={10}
                  className={fieldCls}
                  value={Math.round(Number(text.charSpacing ?? 0))}
                  onChange={(e) => set({ charSpacing: Number(e.target.value) || 0 })}
                />
              </div>
              <div>
                <label className={labelCls}>Line height</label>
                <input
                  type="number"
                  min={0.5}
                  max={3}
                  step={0.1}
                  className={fieldCls}
                  value={Number(text.lineHeight ?? 1.16)}
                  onChange={(e) => set({ lineHeight: Number(e.target.value) || 1.16 })}
                />
              </div>
            </div>
          </>
        )}

        {!text && !isImage && (
          <div className="grid grid-cols-2 gap-2">
            <div>
              <label className={labelCls}>Fill</label>
              <input
                type="color"
                className="h-9 w-full cursor-pointer rounded-md border border-slate-300 bg-white p-1 dark:border-slate-600 dark:bg-slate-800"
                value={typeof selected.fill === "string" && selected.fill.startsWith("#") ? selected.fill : "#93c5fd"}
                onChange={(e) => set({ fill: e.target.value })}
              />
            </div>
            <div>
              <label className={labelCls}>Border</label>
              <input
                type="color"
                className="h-9 w-full cursor-pointer rounded-md border border-slate-300 bg-white p-1 dark:border-slate-600 dark:bg-slate-800"
                value={
                  typeof selected.stroke === "string" && selected.stroke.startsWith("#") ? selected.stroke : "#1d4ed8"
                }
                onChange={(e) => set({ stroke: e.target.value })}
              />
            </div>
          </div>
        )}

        {(!text || isImage) && (
          <div>
            <label className={labelCls}>Border width — {Number(selected.strokeWidth ?? 0)}</label>
            <input
              type="range"
              min={0}
              max={12}
              step={0.5}
              className="w-full"
              value={Number(selected.strokeWidth ?? 0)}
              onChange={(e) => set({ strokeWidth: Number(e.target.value) })}
            />
          </div>
        )}

        <div>
          <label className={labelCls}>Opacity — {Math.round(opacity * 100)}%</label>
          <input
            type="range"
            min={0.05}
            max={1}
            step={0.05}
            className="w-full"
            value={opacity}
            onChange={(e) => set({ opacity: Number(e.target.value) })}
          />
        </div>

        <div>
          <label className={labelCls}>Rotation — {angle}°</label>
          <div className="flex items-center gap-2">
            <input
              type="range"
              min={0}
              max={359}
              className="w-full"
              value={((angle % 360) + 360) % 360}
              onChange={(e) => set({ angle: Number(e.target.value) })}
            />
            <ToggleButton icon={RotateCw} label="Rotate 90°" active={false} onClick={() => set({ angle: (angle + 90) % 360 })} />
          </div>
        </div>
      </div>
    </aside>
  );
}
