import { create } from 'zustand';
import type {
  JewelryType,
  JewelrySize,
  StoneSizeMm,
  ModelTemplate,
  BeadSlot,
  Stone,
} from '../types';
import { calculateSlotCount, generateSlotPositions } from '../utils/calculations';

const DEFAULT_RADIUS = 150;

const DEFAULT_SIZE: JewelrySize = { label: 'M', circumferenceCm: 18 };
const DEFAULT_STONE_SIZE: StoneSizeMm = 8;
const DEFAULT_JEWELRY_TYPE: JewelryType = 'bileklik';

function buildSlots(circumferenceCm: number, stoneSizeMm: StoneSizeMm): { slotCount: number; slots: BeadSlot[] } {
  const slotCount = calculateSlotCount(circumferenceCm, stoneSizeMm);
  const positions = generateSlotPositions(slotCount, DEFAULT_RADIUS);
  const slots: BeadSlot[] = positions.map((pos) => ({
    index: pos.index,
    stone: null,
    position: pos,
  }));
  return { slotCount, slots };
}

interface DesignStore {
  jewelryType: JewelryType;
  size: JewelrySize;
  stoneSizeMm: StoneSizeMm;
  selectedTemplate: ModelTemplate | null;
  slots: BeadSlot[];
  slotCount: number;
  zoom: number;
  setJewelryType: (type: JewelryType) => void;
  setSize: (size: JewelrySize) => void;
  setStoneSizeMm: (size: StoneSizeMm) => void;
  setTemplate: (template: ModelTemplate) => void;
  placeStone: (slotIndex: number, stone: Stone) => void;
  removeStone: (slotIndex: number) => void;
  resetSlots: () => void;
  zoomIn: () => void;
  zoomOut: () => void;
}

const initialBuild = buildSlots(DEFAULT_SIZE.circumferenceCm, DEFAULT_STONE_SIZE);

export const useDesignStore = create<DesignStore>((set, get) => ({
  jewelryType: DEFAULT_JEWELRY_TYPE,
  size: DEFAULT_SIZE,
  stoneSizeMm: DEFAULT_STONE_SIZE,
  selectedTemplate: null,
  slots: initialBuild.slots,
  slotCount: initialBuild.slotCount,
  zoom: 1.0,

  setJewelryType: (type: JewelryType) => {
    const state = get();
    if (state.jewelryType === type) return;
    const { slotCount, slots } = buildSlots(state.size.circumferenceCm, state.stoneSizeMm);
    set({
      jewelryType: type,
      selectedTemplate: null,
      slots,
      slotCount,
    });
  },

  setSize: (size: JewelrySize) => {
    const state = get();
    const { slotCount, slots } = buildSlots(size.circumferenceCm, state.stoneSizeMm);
    set({ size, slotCount, slots });
  },

  setStoneSizeMm: (stoneSizeMm: StoneSizeMm) => {
    const state = get();
    const { slotCount, slots } = buildSlots(state.size.circumferenceCm, stoneSizeMm);
    set({ stoneSizeMm, slotCount, slots });
  },

  setTemplate: (template: ModelTemplate) => {
    set({ selectedTemplate: template });
  },

  placeStone: (slotIndex: number, stone: Stone) => {
    const state = get();
    const slot = state.slots[slotIndex];
    if (!slot || slot.stone !== null) return;
    const newSlots = state.slots.map((s) =>
      s.index === slotIndex ? { ...s, stone } : s
    );
    set({ slots: newSlots });
  },

  removeStone: (slotIndex: number) => {
    const state = get();
    const slot = state.slots[slotIndex];
    if (!slot || slot.stone === null) return;
    const newSlots = state.slots.map((s) =>
      s.index === slotIndex ? { ...s, stone: null } : s
    );
    set({ slots: newSlots });
  },

  resetSlots: () => {
    const state = get();
    const newSlots = state.slots.map((s) => ({ ...s, stone: null }));
    set({ slots: newSlots });
  },

  zoomIn: () => {
    const current = get().zoom;
    const next = Math.round((current + 0.1) * 10) / 10;
    if (next <= 2.0) set({ zoom: next });
  },

  zoomOut: () => {
    const current = get().zoom;
    const next = Math.round((current - 0.1) * 10) / 10;
    if (next >= 0.5) set({ zoom: next });
  },
}));
