export type AppPage = 'auth' | 'onboarding' | 'camera' | 'client' | 'activity' | 'settings';

export type ToastType = 'info' | 'success' | 'error';

export type AppToast = {
  id: string;
  type: ToastType;
  message: string;
};

export type LinkedCamera = {
  id: string;
  cameraDeviceId: string;
  clientDeviceId: string;
  cameraName?: string | null;
  cameraStatus?: string | null;
};

export type MotionNotification = {
  id: string;
  cameraDeviceId: string;
  message: string;
  createdAt: string;
  isRead: boolean;
};

export type ActivityLogItem = {
  id: string;
  type: string;
  message: string;
  createdAt: string;
};

export type RecordingItem = {
  id: string;
  status?: string;
  createdAt: string;
  cameraDeviceId?: string;
  durationSeconds?: number | null;
  streamSessionId?: string;
};

export type Device = {
  id: string;
  name: string;
  role: 'camera' | 'client';
  status?: string;
};

export type Session = {
  user?: {
    id?: string;
    name?: string;
    email?: string;
  };
  session?: {
    id?: string;
  };
};

export type AppState = {
  page: AppPage;
  session: Session | null;
  device: Device | null;
  deviceToken: string | null;
  socketConnected: boolean;
  isMotionActive: boolean;
  cameraPermissionGranted: boolean;
  cameraPreviewReady: boolean;
  cameraStatus: 'idle' | 'recording';
  linkedCameras: LinkedCamera[];
  recordings: RecordingItem[];
  motionNotifications: MotionNotification[];
  activeCameraDeviceId: string | null;
  activeStreamSessionId: string | null;
  activityLog: ActivityLogItem[];
  cameraSessions: Record<string, string>;
  connectedStreamSessionIds: string[];
  loading: boolean;
  isRegistering: boolean;
  authForm: {
    email: string;
    password: string;
    name: string;
  };
  onboardingForm: {
    name: string;
    role: 'camera' | 'client';
    pushToken: string;
  };
  toasts: AppToast[];
  clientStreamMode: 'none' | 'connecting' | 'unavailable' | 'image' | 'video';
  clientFallbackFrame: string;
  clientPlaceholderText: string;
  lastError: string | null;
};

export const createInitialState = (): AppState => ({
  page: 'auth',
  session: null,
  device: null,
  deviceToken: null,
  socketConnected: false,
  isMotionActive: false,
  cameraPermissionGranted: false,
  cameraPreviewReady: false,
  cameraStatus: 'idle',
  linkedCameras: [],
  recordings: [],
  motionNotifications: [],
  activeCameraDeviceId: null,
  activeStreamSessionId: null,
  activityLog: [],
  cameraSessions: {},
  connectedStreamSessionIds: [],
  loading: false,
  isRegistering: false,
  authForm: {
    email: '',
    password: '',
    name: '',
  },
  onboardingForm: {
    name: '',
    role: 'client',
    pushToken: '',
  },
  toasts: [],
  clientStreamMode: 'none',
  clientFallbackFrame: '',
  clientPlaceholderText: 'Select a camera to view',
  lastError: null,
});

export const unreadNotificationsCount = (state: AppState): number =>
  state.motionNotifications.reduce((count, item) => count + (item.isRead ? 0 : 1), 0);
