import { configureStore, createSlice, PayloadAction } from '@reduxjs/toolkit';
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';

// Auth Slice
interface User {
  id: string;
  email: string;
  username?: string;
}

interface AuthState {
  user: User | null;
  loading: boolean;
  error: string | null;
}

const initialAuthState: AuthState = {
  user: null,
  loading: false,
  error: null,
};

const authSlice = createSlice({
  name: 'auth',
  initialState: initialAuthState,
  reducers: {
    setLoading: (state, action: PayloadAction<boolean>) => {
      state.loading = action.payload;
    },
    setUser: (state, action: PayloadAction<User | null>) => {
      state.user = action.payload;
      state.loading = false;
      state.error = null;
    },
    setError: (state, action: PayloadAction<string>) => {
      state.error = action.payload;
      state.loading = false;
    },
    logout: (state) => {
      state.user = null;
      state.loading = false;
      state.error = null;
    },
  },
});

export const { setLoading, setUser, setError, logout } = authSlice.actions;

// Messaging Slice
interface Conversation {
  id: string;
  participantName: string;
  lastMessage: string;
  unreadCount: number;
}

interface Message {
  id: string;
  conversationId: string;
  content: string;
  senderId: string;
  timestamp: string;
  createdAt: string;
}

interface MessagingState {
  conversations: Conversation[];
  messages: Record<string, Message[]>;
}

const initialMessagingState: MessagingState = {
  conversations: [],
  messages: {},
};

const messagingSlice = createSlice({
  name: 'messaging',
  initialState: initialMessagingState,
  reducers: {
    setConversations: (state, action: PayloadAction<Conversation[]>) => {
      state.conversations = action.payload;
    },
    addMessage: (state, action: PayloadAction<Message>) => {
      const msg = action.payload;
      if (!state.messages[msg.conversationId]) {
        state.messages[msg.conversationId] = [];
      }
      state.messages[msg.conversationId].push(msg);
    },
  },
});

export const { setConversations, addMessage } = messagingSlice.actions;

// Calls Slice
interface Call {
  id: string;
  participantName: string;
  type: 'audio' | 'video' | 'voice';
  status: 'active' | 'ended' | 'missed';
  duration?: string;
  timestamp: string;
  isMuted?: boolean;
  isCameraOn?: boolean;
}

interface CallsState {
  activeCall: Call | null;
  callHistory: Call[];
}

const initialCallsState: CallsState = {
  activeCall: null,
  callHistory: [],
};

const callsSlice = createSlice({
  name: 'calls',
  initialState: initialCallsState,
  reducers: {
    setActiveCall: (state, action: PayloadAction<Call | null>) => {
      state.activeCall = action.payload;
    },
    addCallToHistory: (state, action: PayloadAction<Call>) => {
      state.callHistory.unshift(action.payload);
    },
  },
});

export const { setActiveCall, addCallToHistory } = callsSlice.actions;

// Async thunks
export const loginAsync = (credentials: { email: string; password: string }) => async (dispatch: AppDispatch) => {
  dispatch(setLoading(true));
  try {
    // TODO: Integrate with Supabase auth
    const mockUser: User = {
      id: '1',
      email: credentials.email,
      username: credentials.email.split('@')[0],
    };
    dispatch(setUser(mockUser));
  } catch (error) {
    dispatch(setError((error as Error).message));
  }
};

export const logoutAsync = () => async (dispatch: AppDispatch) => {
  dispatch(setLoading(true));
  try {
    // TODO: Integrate with Supabase auth
    dispatch(logout());
  } catch (error) {
    dispatch(setError((error as Error).message));
  }
};

// Store
export const store = configureStore({
  reducer: {
    auth: authSlice.reducer,
    messaging: messagingSlice.reducer,
    calls: callsSlice.reducer,
  },
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
