import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { Vehicle } from '@/models/teltoinstall/Vehicle';
import { Device } from '@/models/teltoinstall/Device';
import { Wiring } from '@/models/teltoinstall/Wiring';
import { InstallationValidation } from '@/models/teltoinstall/InstallationValidation';
import { Photo } from '@/models/teltoinstall/Photo';

export type WizardStep = 0 | 1 | 2 | 3 | 4 | 5;

/**
 * Champs verrouillés quand la pose a été démarrée depuis une demande confirmée :
 * l'immatriculation et le boîtier sont figés ; le VIN ne l'est que si la source
 * en portait déjà un. Pilote l'état lecture seule des champs du wizard.
 */
export interface LockedFields {
  license_plate: boolean;
  vin: boolean;
  telematics_box_id: boolean;
}

interface InstallationState {
  installationId: number | null;
  currentStep: WizardStep;
  vehicle: Partial<Vehicle>;
  device: Partial<Device>;
  wirings: Wiring[];
  location: string;
  installer_name: string;
  intervention_date: string;
  notes: string;
  /** Numéro de programme du boîtier (obligatoire quand le boîtier embarque un bus CAN). */
  program_number: string;
  validation: Partial<InstallationValidation>;
  photos: Photo[];
  locked: LockedFields;
  isSaving: boolean;
  saveError: string | null;
}

const initialState: InstallationState = {
  installationId: null,
  currentStep: 0,
  vehicle: {},
  device: {},
  wirings: [],
  location: '',
  installer_name: '',
  intervention_date: '',
  notes: '',
  program_number: '',
  validation: {},
  photos: [],
  locked: { license_plate: false, vin: false, telematics_box_id: false },
  isSaving: false,
  saveError: null,
};

const installationSlice = createSlice({
  name: 'installation',
  initialState,
  reducers: {
    setInstallationId(state, action: PayloadAction<number>) {
      state.installationId = action.payload;
    },
    setCurrentStep(state, action: PayloadAction<WizardStep>) {
      state.currentStep = action.payload;
    },
    setVehicleData(state, action: PayloadAction<Partial<Vehicle>>) {
      state.vehicle = { ...state.vehicle, ...action.payload };
    },
    setDeviceData(state, action: PayloadAction<Partial<Device>>) {
      state.device = { ...state.device, ...action.payload };
    },
    setWirings(state, action: PayloadAction<Wiring[]>) {
      state.wirings = action.payload;
    },
    setLocation(state, action: PayloadAction<string>) {
      state.location = action.payload;
    },
    setInstallerInfo(state, action: PayloadAction<{ installer_name: string; intervention_date: string }>) {
      state.installer_name = action.payload.installer_name;
      state.intervention_date = action.payload.intervention_date;
    },
    setNotes(state, action: PayloadAction<string>) {
      state.notes = action.payload;
    },
    setProgramNumber(state, action: PayloadAction<string>) {
      state.program_number = action.payload;
    },
    setValidation(state, action: PayloadAction<Partial<InstallationValidation>>) {
      state.validation = { ...state.validation, ...action.payload };
    },
    addPhotos(state, action: PayloadAction<Photo[]>) {
      state.photos = [...state.photos, ...action.payload];
    },
    removePhoto(state, action: PayloadAction<number>) {
      state.photos = state.photos.filter((_, i) => i !== action.payload);
    },
    setSaving(state, action: PayloadAction<boolean>) {
      state.isSaving = action.payload;
    },
    setSaveError(state, action: PayloadAction<string | null>) {
      state.saveError = action.payload;
    },
    resetInstallation() {
      return initialState;
    },
    hydrateInstallation(state, action: PayloadAction<Omit<InstallationState, 'isSaving' | 'saveError'>>) {
      return {
        ...initialState,
        ...action.payload,
        isSaving: false,
        saveError: null,
      };
    },
  },
});

export const {
  setInstallationId,
  setCurrentStep,
  setVehicleData,
  setDeviceData,
  setWirings,
  setLocation,
  setInstallerInfo,
  setNotes,
  setProgramNumber,
  setValidation,
  addPhotos,
  removePhoto,
  setSaving,
  setSaveError,
  resetInstallation,
  hydrateInstallation,
} = installationSlice.actions;

export default installationSlice.reducer;
