import Phaser from 'phaser';
import { PALETTE } from '../data/outfits';

// Shared look for every juice widget. Chunky, high contrast, slightly grubby —
// this club has not been deep-cleaned since the Olympics. Colours lean on the
// doll PALETTE so UI and patrons live in the same world.

export const UI = {
  ink: 0x0b0b12,
  panel: 0x1a1a24,
  panelLip: 0x2c2c3a,
  grime: 0x24242e,
  paper: PALETTE.paper ?? 0xdad4c4,
  neonPink: 0xd03470,
  neonGreen: 0x9fe8a0,
  kebabAmber: 0xd8a020,
  danger: PALETTE.red ?? 0xc03434,
  ok: PALETTE.green ?? 0x2e7d46,
  dim: 0x556,
} as const;

export const hex = (c: number): string => `#${c.toString(16).padStart(6, '0')}`;

export const font = (size: number, colour: number): Phaser.Types.GameObjects.Text.TextStyle => ({
  fontFamily: 'monospace',
  fontSize: `${size}px`,
  color: hex(colour),
});

/**
 * A grubby recessed panel: dark fill, lit top lip, dark bottom shadow. Returns a
 * container positioned at (x, y) with the panel centred on its origin, so
 * callers can add children in local coordinates.
 */
export function panel(
  scene: Phaser.Scene,
  x: number,
  y: number,
  w: number,
  h: number,
  fill: number = UI.panel,
): Phaser.GameObjects.Container {
  const c = scene.add.container(x, y);
  c.add(scene.add.rectangle(0, 0, w, h, fill).setStrokeStyle(1, UI.ink));
  c.add(scene.add.rectangle(0, -h / 2 + 1, w - 2, 1, UI.panelLip, 0.5));
  c.add(scene.add.rectangle(0, h / 2 - 1, w - 2, 1, UI.ink, 0.6));
  return c;
}

export interface ChunkyButtonOptions {
  w?: number;
  h?: number;
  fill?: number;
  textColour?: number;
  fontSize?: number;
  onClick: () => void;
}

/**
 * Chunky pixel button with a real press: it drops 1px and darkens on pointerdown
 * and springs back on release. The 1px travel is most of why it feels physical.
 */
export function chunkyButton(
  scene: Phaser.Scene,
  x: number,
  y: number,
  label: string,
  opts: ChunkyButtonOptions,
): Phaser.GameObjects.Container {
  const w = opts.w ?? 56;
  const h = opts.h ?? 16;
  const fill = opts.fill ?? UI.panelLip;
  const c = scene.add.container(x, y);
  const face = scene.add.rectangle(0, 0, w, h, fill).setStrokeStyle(1, UI.ink);
  const shadow = scene.add.rectangle(0, h / 2, w, 2, UI.ink, 0.8);
  const text = scene.add
    .text(0, 0, label, font(opts.fontSize ?? 8, opts.textColour ?? UI.paper))
    .setOrigin(0.5);
  c.add([shadow, face, text]);

  face.setInteractive({ useHandCursor: true });
  const press = (down: boolean): void => {
    face.y = down ? 1 : 0;
    text.y = down ? 1 : 0;
    shadow.setAlpha(down ? 0.2 : 0.8);
    face.setFillStyle(down ? Phaser.Display.Color.ValueToColor(fill).darken(20).color : fill);
  };
  // Phaser fires 'pointerup' on any release over the object, even one whose
  // 'pointerdown' landed elsewhere. Arm on our own down and disarm the moment the
  // pointer leaves, so a stray release can't phantom-click (clicker tally is load-bearing).
  let armed = false;
  face.on('pointerdown', () => {
    armed = true;
    press(true);
  });
  // Leaving the face is the only way to release elsewhere, so this covers the
  // press-drag-away-release case too.
  face.on('pointerout', () => {
    armed = false;
    press(false);
  });
  face.on('pointerup', () => {
    const fire = armed;
    armed = false;
    press(false);
    if (fire) opts.onClick();
  });
  return c;
}

/** Short, sharp camera shake. Used by the stamp and anything else with weight. */
export function shake(scene: Phaser.Scene, px = 4, ms = 120): void {
  scene.cameras.main.shake(ms, px / 1000, true);
}
