import { Eraser, PaintBrush } from "@phosphor-icons/react";
import { commandIds } from "@commands/ids";
import type { AppStore } from "@editor/store";
import type { MaskViewMode } from "@editor/state";
import type { BrushSettings, ToolId } from "@editor/tools";
import { BottomControlColorPicker } from "./ColorPicker";
import { BottomControlDivider } from "./Divider";
import { BottomControlSelectMenu, type BottomControlSelectOption } from "./SelectMenu";
import { BottomControlSlider } from "./Slider";
import { bottomControlFieldClass, bottomControlIconSlotClass, bottomControlLabelClass, bottomControlMenuClass } from "./styles";

export type BrushControlsProps = {
  tool: Extract<ToolId, "brush" | "eraser">;
  settings: BrushSettings;
  editingMask?: boolean;
  maskKind?: "layerMask" | "inpaintRegion";
  maskViewMode?: MaskViewMode;
  dispatch: AppStore["dispatch"];
};

const maskViewModeOptions = [
  { value: "composite", label: "Image" },
  { value: "blackWhite", label: "B/W" },
  { value: "alpha", label: "Alpha" },
  { value: "overlay", label: "Overlay" },
] satisfies readonly BottomControlSelectOption<MaskViewMode>[];

export function BrushControls({ tool, settings, editingMask = false, maskKind = "layerMask", maskViewMode = "composite", dispatch }: BrushControlsProps) {
  const inpaintRegion = editingMask && maskKind === "inpaintRegion";
  return (
    <div className={bottomControlMenuClass()}>
      <span className={bottomControlIconSlotClass()} title={editingMask ? `Mask ${tool === "eraser" ? "hide" : "reveal"}` : tool === "eraser" ? "Eraser" : "Brush"}>
        {tool === "eraser" ? <Eraser size={24} weight="regular" /> : <PaintBrush size={24} weight="regular" />}
      </span>
      <BottomControlDivider />
      {editingMask ? (
        <>
          <button type="button" className={maskModeButtonClass(tool === "brush")} aria-pressed={tool === "brush"} onClick={() => dispatch(commandIds.toolSetActive, { tool: "brush" })}>{inpaintRegion ? "Replace" : "Reveal"}</button>
          <button type="button" className={maskModeButtonClass(tool === "eraser")} aria-pressed={tool === "eraser"} onClick={() => dispatch(commandIds.toolSetActive, { tool: "eraser" })}>{inpaintRegion ? "Protect" : "Hide"}</button>
          <BottomControlDivider />
        </>
      ) : null}
      {tool === "brush" && !editingMask ? (
        <label className={bottomControlFieldClass()}>
          <span className={bottomControlLabelClass()}>Color</span>
          <BottomControlColorPicker
            value={settings.color}
            aria-label="Brush color"
            onValueChange={(color) => dispatch(commandIds.toolSetBrushSettings, { color })}
          />
        </label>
      ) : null}
      <label className={bottomControlFieldClass()}>
        <span className={bottomControlLabelClass()}>Size</span>
        <BottomControlSlider
          min={1}
          max={200}
          value={settings.size}
          className="min-w-10 w-[clamp(2.5rem,9vw,7rem)] shrink"
          aria-label={`${tool} size`}
          onValueChange={(size) => dispatch(commandIds.toolSetBrushSettings, { size })}
        />
        <span className="w-9 text-right text-xs font-medium text-white/85">{Math.round(settings.size)}</span>
      </label>
      <BottomControlDivider />
      <label className={bottomControlFieldClass()}><span className={bottomControlLabelClass()}>Opacity</span><BottomControlSlider min={0} max={100} value={settings.opacity} className="min-w-10 w-[clamp(2.5rem,7vw,6rem)] shrink" aria-label="Brush opacity" onValueChange={(opacity) => dispatch(commandIds.toolSetBrushSettings, { opacity })} /><span className="w-9 text-right text-xs font-medium text-white/85">{Math.round(settings.opacity)}</span></label>
      <BottomControlDivider />
      <label className={bottomControlFieldClass()}><span className={bottomControlLabelClass()}>Flow</span><BottomControlSlider min={1} max={100} value={settings.flow} className="min-w-10 w-[clamp(2.5rem,7vw,6rem)] shrink" aria-label="Brush flow" onValueChange={(flow) => dispatch(commandIds.toolSetBrushSettings, { flow })} /><span className="w-9 text-right text-xs font-medium text-white/85">{Math.round(settings.flow)}</span></label>
      <BottomControlDivider />
      <label className={bottomControlFieldClass()}><span className={bottomControlLabelClass()}>Smooth</span><BottomControlSlider min={0} max={100} value={settings.smoothing} className="min-w-10 w-[clamp(2.5rem,7vw,6rem)] shrink" aria-label="Brush smoothing" onValueChange={(smoothing) => dispatch(commandIds.toolSetBrushSettings, { smoothing })} /><span className="w-9 text-right text-xs font-medium text-white/85">{Math.round(settings.smoothing)}</span></label>
      <button type="button" className={maskModeButtonClass(settings.pressureSize)} aria-pressed={settings.pressureSize} title="Use pen pressure for brush size" onClick={() => dispatch(commandIds.toolSetBrushSettings, { pressureSize: !settings.pressureSize })}>Pressure</button>
      <BottomControlDivider />
      <label className={bottomControlFieldClass()}>
        <span className={bottomControlLabelClass()}>Hard</span>
        <BottomControlSlider
          min={0}
          max={100}
          value={settings.hardness}
          className="min-w-10 w-[clamp(2.5rem,9vw,7rem)] shrink"
          aria-label={`${tool} hardness`}
          onValueChange={(hardness) => dispatch(commandIds.toolSetBrushSettings, { hardness })}
        />
        <span className="w-9 text-right text-xs font-medium text-white/85">{Math.round(settings.hardness)}</span>
      </label>
      {editingMask ? (
        <>
          <BottomControlDivider />
          <label className={bottomControlFieldClass()}>
            <span className={bottomControlLabelClass()}>View</span>
            <BottomControlSelectMenu
              value={maskViewMode}
              options={maskViewModeOptions}
              aria-label="Mask view mode"
              onValueChange={(mode) => dispatch(commandIds.toolSetMaskViewMode, { mode })}
            />
          </label>
          <BottomControlDivider />
          <button
            type="button"
            className="rounded-md bg-sky-300 px-3 py-1.5 text-xs font-semibold text-slate-950 transition hover:bg-sky-200"
            onClick={() => dispatch(commandIds.toolExitMaskEdit, undefined)}
          >
            Done
          </button>
        </>
      ) : null}
    </div>
  );
}

function maskModeButtonClass(active: boolean) {
  return `rounded-md px-3 py-1.5 text-xs font-medium transition ${active ? "bg-sky-300 text-slate-950" : "bg-white/[0.06] text-white/70 hover:bg-white/10"}`;
}
