import { create } from 'zustand';

export interface ScaleRatio {
  label: string;     // e.g. "1:50", "2:1", "1:1"
  factor: number;    // render multiplier: 1:50 => 0.02, 2:1 => 2, 1:1 => 1
}

export const SCALE_PRESETS: ScaleRatio[] = [
  { label: '10:1',  factor: 10 },
  { label: '4:1',   factor: 4 },
  { label: '2:1',   factor: 2 },
  { label: '1:1',   factor: 1 },
  { label: '1:2',   factor: 1 / 2 },
  { label: '1:4',   factor: 1 / 4 },
  { label: '1:8',   factor: 1 / 8 },
  { label: '1:10',  factor: 1 / 10 },
  { label: '1:20',  factor: 1 / 20 },
  { label: '1:33',  factor: 1 / 33 },
  { label: '1:50',  factor: 1 / 50 },
  { label: '1:100', factor: 1 / 100 },
  { label: '1:200', factor: 1 / 200 },
];

interface ModelInfo {
  fileName: string;
  fileSize: number;
  url: string;
}

interface FineTuning {
  posX: number;
  posY: number;
  posZ: number;
  rotX: number;
  rotY: number;
  rotZ: number;
  scale: number;
}

export interface SceneModel {
  id: string;
  fileName: string;
  fileSize: number;
  url: string;
  color: string;
  visible: boolean;
  locked: boolean;
  fineTuning: FineTuning;
}

const MAX_MODELS = 5;
const MODEL_COLORS = ['#3b82f6', '#22c55e', '#eab308', '#a855f7', '#ec4899'];

type AnchorMode = 'tracking' | 'manual' | 'fine-tuning';
type InspectionResult = 'pending' | 'approved' | 'rejected';
type RenderMode = 'solid' | 'wireframe' | 'edges';

export interface MeasurePoint {
  x: number;
  y: number;
  z: number;
}

export interface Measurement {
  id: string;
  pointA: MeasurePoint;
  pointB: MeasurePoint;
  distanceMM: number;
}

export interface HoverInfo {
  type: 'hole' | 'edge';
  position: [number, number, number];
  value: number; // mm
}

export interface ChecklistItem {
  id: string;
  label: string;
  status: 'pending' | 'approved' | 'rejected';
  note: string;
  audioUrl: string | null;
}

const defaultChecklist: ChecklistItem[] = [
  { id: 'dimensions', label: 'Dimensões Gerais', status: 'pending', note: '', audioUrl: null },
  { id: 'plates', label: 'Posição das Placas', status: 'pending', note: '', audioUrl: null },
  { id: 'holes', label: 'Diâmetro dos Furos', status: 'pending', note: '', audioUrl: null },
  { id: 'weld', label: 'Especificação da Solda', status: 'pending', note: '', audioUrl: null },
];

const defaultFineTuning: FineTuning = { posX: 0, posY: 0, posZ: 0, rotX: 0, rotY: 0, rotZ: 0, scale: 1 };

interface ModelStore {
  // ── Multi-model scene ─────────────
  models: SceneModel[];
  activeModelId: string | null;
  addModel: (m: ModelInfo) => string; // returns id
  removeModel: (id: string) => void;
  setActiveModel: (id: string | null) => void;
  toggleModelVisible: (id: string) => void;
  toggleModelLocked: (id: string) => void;
  duplicateModel: (id: string) => void;
  clearAllModels: () => void;
  maxModels: number;

  // ── Legacy single-model accessors (proxy to active) ─────────────
  model: ModelInfo | null;
  setModel: (model: ModelInfo | null) => void;

  fineTuning: FineTuning;
  setFineTuning: (ft: Partial<FineTuning>) => void;
  resetFineTuning: () => void;

  anchorMode: AnchorMode;
  setAnchorMode: (mode: AnchorMode) => void;

  inspectionResult: InspectionResult;
  setInspectionResult: (result: InspectionResult) => void;

  xrSupported: boolean | null;
  setXrSupported: (supported: boolean | null) => void;

  scaleRatio: ScaleRatio;
  setScaleRatio: (r: ScaleRatio) => void;

  opacity: number;
  setOpacity: (opacity: number) => void;

  renderMode: RenderMode;
  setRenderMode: (mode: RenderMode) => void;

  showGrid: boolean;
  setShowGrid: (show: boolean) => void;

  wireframeColor: string;
  setWireframeColor: (color: string) => void;

  wireframeThickness: number;
  setWireframeThickness: (t: number) => void;

  edgeThresholdAngle: number;
  setEdgeThresholdAngle: (angle: number) => void;

  checklist: ChecklistItem[];
  setChecklistItemStatus: (id: string, status: 'approved' | 'rejected') => void;
  setChecklistItemNote: (id: string, note: string) => void;
  setChecklistItemAudio: (id: string, audioUrl: string | null) => void;
  resetChecklist: () => void;

  measureMode: boolean;
  setMeasureMode: (on: boolean) => void;
  measurePoints: MeasurePoint[];
  addMeasurePoint: (p: MeasurePoint) => void;
  measurements: Measurement[];
  clearMeasurements: () => void;
  removeMeasurement: (id: string) => void;

  compareMode: boolean;
  setCompareMode: (on: boolean) => void;
  compareImage: string | null;
  setCompareImage: (url: string | null) => void;

  snapPoint: MeasurePoint | null;
  setSnapPoint: (p: MeasurePoint | null) => void;

  hoverInfo: HoverInfo | null;
  setHoverInfo: (info: HoverInfo | null) => void;

  screenshots: string[];
  addScreenshot: (dataUrl: string) => void;
  removeScreenshot: (index: number) => void;
  clearScreenshots: () => void;
}

/** Sync top-level legacy `model` / `fineTuning` from active SceneModel. */
function syncActive(state: Pick<ModelStore, 'models' | 'activeModelId'>): { model: ModelInfo | null; fineTuning: FineTuning } {
  const active = state.models.find(m => m.id === state.activeModelId) ?? null;
  return {
    model: active ? { fileName: active.fileName, fileSize: active.fileSize, url: active.url } : null,
    fineTuning: active ? { ...active.fineTuning } : { ...defaultFineTuning },
  };
}

export const useModelStore = create<ModelStore>((set, get) => ({
  // ── Multi-model ─────────────
  models: [],
  activeModelId: null,
  maxModels: MAX_MODELS,

  addModel: (m) => {
    const state = get();
    if (state.models.length >= MAX_MODELS) {
      return '';
    }
    const id = `mdl_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
    const color = MODEL_COLORS[state.models.length % MODEL_COLORS.length];
    // Stagger position so multiple models don't perfectly overlap
    const offsetIdx = state.models.length;
    const newModel: SceneModel = {
      id,
      fileName: m.fileName,
      fileSize: m.fileSize,
      url: m.url,
      color,
      visible: true,
      locked: false,
      fineTuning: { ...defaultFineTuning, posX: offsetIdx * 0.15 },
    };
    const models = [...state.models, newModel];
    set({ models, activeModelId: id, ...syncActive({ models, activeModelId: id }) });
    return id;
  },

  removeModel: (id) => {
    const state = get();
    const models = state.models.filter(m => m.id !== id);
    const activeModelId = state.activeModelId === id
      ? (models[0]?.id ?? null)
      : state.activeModelId;
    set({ models, activeModelId, ...syncActive({ models, activeModelId }) });
  },

  setActiveModel: (id) => {
    const state = get();
    set({ activeModelId: id, ...syncActive({ models: state.models, activeModelId: id }) });
  },

  toggleModelVisible: (id) => set((state) => ({
    models: state.models.map(m => m.id === id ? { ...m, visible: !m.visible } : m),
  })),

  toggleModelLocked: (id) => set((state) => ({
    models: state.models.map(m => m.id === id ? { ...m, locked: !m.locked } : m),
  })),

  duplicateModel: (id) => {
    const state = get();
    if (state.models.length >= MAX_MODELS) return;
    const src = state.models.find(m => m.id === id);
    if (!src) return;
    const newId = `mdl_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
    const color = MODEL_COLORS[state.models.length % MODEL_COLORS.length];
    const copy: SceneModel = {
      ...src,
      id: newId,
      color,
      fineTuning: { ...src.fineTuning, posX: src.fineTuning.posX + 0.15 },
    };
    const models = [...state.models, copy];
    set({ models, activeModelId: newId, ...syncActive({ models, activeModelId: newId }) });
  },

  clearAllModels: () => set({ models: [], activeModelId: null, model: null, fineTuning: { ...defaultFineTuning } }),

  // ── Legacy single-model proxies ─────────────
  model: null,
  setModel: (m) => {
    if (!m) {
      set({ models: [], activeModelId: null, model: null, fineTuning: { ...defaultFineTuning } });
      return;
    }
    // Legacy: replace all models with this single one
    const id = `mdl_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
    const newModel: SceneModel = {
      id, fileName: m.fileName, fileSize: m.fileSize, url: m.url,
      color: MODEL_COLORS[0], visible: true, locked: false,
      fineTuning: { ...defaultFineTuning },
    };
    set({ models: [newModel], activeModelId: id, ...syncActive({ models: [newModel], activeModelId: id }) });
  },

  fineTuning: { ...defaultFineTuning },
  setFineTuning: (ft) => set((state) => {
    const newFT = { ...state.fineTuning, ...ft };
    // Also write to the active model's fineTuning
    const models = state.activeModelId
      ? state.models.map(m => m.id === state.activeModelId ? { ...m, fineTuning: newFT } : m)
      : state.models;
    return { fineTuning: newFT, models };
  }),
  resetFineTuning: () => set((state) => {
    const reset = { ...defaultFineTuning };
    const models = state.activeModelId
      ? state.models.map(m => m.id === state.activeModelId ? { ...m, fineTuning: reset } : m)
      : state.models;
    return { fineTuning: reset, models };
  }),

  anchorMode: 'manual',
  setAnchorMode: (anchorMode) => set({ anchorMode }),

  inspectionResult: 'pending',
  setInspectionResult: (inspectionResult) => set({ inspectionResult }),

  xrSupported: null,
  setXrSupported: (xrSupported) => set({ xrSupported }),

  scaleRatio: SCALE_PRESETS.find(p => p.label === '1:1')!,
  setScaleRatio: (scaleRatio) => set({ scaleRatio }),

  opacity: 1,
  setOpacity: (opacity) => set({ opacity }),

  renderMode: 'solid',
  setRenderMode: (renderMode) => set({ renderMode }),

  showGrid: true,
  setShowGrid: (showGrid) => set({ showGrid }),

  wireframeColor: '#8899aa',
  setWireframeColor: (wireframeColor) => set({ wireframeColor }),

  wireframeThickness: 1,
  setWireframeThickness: (wireframeThickness) => set({ wireframeThickness }),

  edgeThresholdAngle: 15,
  setEdgeThresholdAngle: (edgeThresholdAngle) => set({ edgeThresholdAngle }),

  checklist: defaultChecklist.map(i => ({ ...i })),
  setChecklistItemStatus: (id, status) => set((state) => ({
    checklist: state.checklist.map(item =>
      item.id === id ? { ...item, status } : item
    ),
  })),
  setChecklistItemNote: (id, note) => set((state) => ({
    checklist: state.checklist.map(item =>
      item.id === id ? { ...item, note } : item
    ),
  })),
  setChecklistItemAudio: (id, audioUrl) => set((state) => ({
    checklist: state.checklist.map(item =>
      item.id === id ? { ...item, audioUrl } : item
    ),
  })),
  resetChecklist: () => set({ checklist: defaultChecklist.map(i => ({ ...i })) }),

  measureMode: false,
  setMeasureMode: (measureMode) => set({ measureMode, measurePoints: [] }),
  measurePoints: [],
  addMeasurePoint: (p) => set((state) => {
    const points = [...state.measurePoints, p];
    if (points.length === 2) {
      const [a, b] = points;
      const dx = (a.x - b.x) * 1000;
      const dy = (a.y - b.y) * 1000;
      const dz = (a.z - b.z) * 1000;
      const distanceWorldMM = Math.sqrt(dx * dx + dy * dy + dz * dz);
      const factor = state.scaleRatio?.factor ?? 1;
      const distanceMM = distanceWorldMM / factor;
      const measurement: Measurement = {
        id: `m_${Date.now()}`,
        pointA: a,
        pointB: b,
        distanceMM,
      };
      return { measurePoints: [], measurements: [...state.measurements, measurement] };
    }
    return { measurePoints: points };
  }),
  measurements: [],
  clearMeasurements: () => set({ measurements: [], measurePoints: [] }),
  removeMeasurement: (id) => set((state) => ({
    measurements: state.measurements.filter(m => m.id !== id),
  })),

  compareMode: false,
  setCompareMode: (compareMode) => set({ compareMode }),
  compareImage: null,
  setCompareImage: (compareImage) => set({ compareImage }),

  snapPoint: null,
  setSnapPoint: (snapPoint) => set({ snapPoint }),

  hoverInfo: null,
  setHoverInfo: (hoverInfo) => set({ hoverInfo }),

  screenshots: [],
  addScreenshot: (dataUrl) => set((state) => ({ screenshots: [...state.screenshots, dataUrl] })),
  removeScreenshot: (index) => set((state) => ({
    screenshots: state.screenshots.filter((_, i) => i !== index),
  })),
  clearScreenshots: () => set({ screenshots: [] }),
}));
