import { Selector, createSelector } from '@ngrx/store';
import { EntityState, createEntityAdapter } from '@ngrx/entity';
import moment from 'moment';
import {
  UserInfo,
  GroupDetailData,
  RoomUserData,
  RoomUserDetailData,
} from '@ucap-webmessenger/protocol-sync';
import {
  RoomInfo,
  UserInfo as RoomUserInfo,
} from '@ucap-webmessenger/protocol-room';

export interface Buddy2State extends EntityState<UserInfo> {
  syncDate: string;
}

export interface Group2State extends EntityState<GroupDetailData> {
  syncDate: string;
}

export interface RoomState extends EntityState<RoomInfo> {
  syncDate: string;
}

export interface RoomUserState extends EntityState<RoomUserDetailData> {}

export interface RoomUserShortState extends EntityState<RoomUserData> {}

export interface State {
  buddy2: Buddy2State;
  group2: Group2State;
  room: RoomState;
  roomUser: RoomUserState;
  roomUserShort: RoomUserShortState;
  chatUnreadCount: number;
}

export const adapterBuddy2 = createEntityAdapter<UserInfo>({
  selectId: userInfo => userInfo.seq,
});
export const adapterGroup2 = createEntityAdapter<GroupDetailData>({
  selectId: groupDetailData => groupDetailData.seq,
  sortComparer: (a, b) => {
    // 기본그룹은 제일 하단
    if (0 === a.seq) {
      return 1;
    } else if (0 === b.seq) {
      return -1;
    } else {
      if (a.name > b.name) {
        return 1;
      }
      if (b.name > a.name) {
        return -1;
      }
      return 0;
    }
  },
});
export const adapterRoom = createEntityAdapter<RoomInfo>({
  selectId: roomInfo => roomInfo.roomSeq,
  sortComparer: (a, b) => {
    return (
      moment(b.finalEventDate)
        .toDate()
        .getTime() -
      moment(a.finalEventDate)
        .toDate()
        .getTime()
    );
  },
});
export const adapterRoomUser = createEntityAdapter<RoomUserDetailData>({
  selectId: roomUserDetailData => roomUserDetailData.roomSeq,
});
export const adapterRoomUserShort = createEntityAdapter<RoomUserData>({
  selectId: roomUserData => roomUserData.roomSeq,
});

const buddy2InitialState: Buddy2State = adapterBuddy2.getInitialState({
  syncDate: '',
});
const group2InitialState: Group2State = adapterGroup2.getInitialState({
  syncDate: '',
});
const roomInitialState: RoomState = adapterRoom.getInitialState({
  syncDate: '',
});
const roomUserInitialState: RoomUserState = adapterRoomUser.getInitialState({});
const roomUserShortInitialState: RoomUserShortState = adapterRoomUserShort.getInitialState(
  {}
);

export const initialState: State = {
  buddy2: buddy2InitialState,
  group2: group2InitialState,
  room: roomInitialState,
  roomUser: roomUserInitialState,
  roomUserShort: roomUserShortInitialState,
  chatUnreadCount: 0,
};

const {
  selectAll: ngeSelectAllBuddy2,
  selectEntities: ngeSelectEntitiesBuddy2,
  selectIds: ngeSelectIdsBuddy2,
  selectTotal: ngeSelectTotalBuddy2,
} = adapterBuddy2.getSelectors();

const {
  selectAll: ngeSelectAllGroup2,
  selectEntities: ngeSelectEntitiesGroup2,
  selectIds: ngeSelectIdsGroup2,
  selectTotal: ngeSelectTotalGroup2,
} = adapterGroup2.getSelectors();

const {
  selectAll: ngeSelectAllRoom,
  selectEntities: ngeSelectEntitiesRoom,
  selectIds: ngeSelectIdsRoom,
  selectTotal: ngeSelectTotalRoom,
} = adapterRoom.getSelectors();

const {
  selectAll: ngeSelectAllRoomUser,
  selectEntities: ngeSelectEntitiesRoomUser,
  selectIds: ngeSelectIdsRoomUser,
  selectTotal: ngeSelectTotalRoomUser,
} = adapterRoomUser.getSelectors();

const {
  selectAll: ngeSelectAllRoomUserShort,
  selectEntities: ngeSelectEntitiesRoomUserShort,
  selectIds: ngeSelectIdsRoomUserShort,
  selectTotal: ngeSelectTotalRoomUserShort,
} = adapterRoomUserShort.getSelectors();

export function selectors<S>(selector: Selector<any, State>) {
  const selectBuddy2 = createSelector(selector, (state: State) => state.buddy2);

  const selectGroup2 = createSelector(selector, (state: State) => state.group2);

  const selectRoom = createSelector(selector, (state: State) => state.room);

  const selectRoomUser = createSelector(
    selector,
    (state: State) => state.roomUser
  );

  const selectRoomUserShort = createSelector(
    selector,
    (state: State) => state.roomUserShort
  );

  return {
    selectAllBuddy2: createSelector(selectBuddy2, ngeSelectAllBuddy2),
    selectBuddy2SyncDate: createSelector(
      selectBuddy2,
      buddy2State => buddy2State.syncDate
    ),
    selectAllGroup2: createSelector(selectGroup2, ngeSelectAllGroup2),
    selectGroup2SyncDate: createSelector(
      selectGroup2,
      group2State => group2State.syncDate
    ),
    selectAllRoom: createSelector(selectRoom, ngeSelectAllRoom),
    selectRoomSyncDate: createSelector(
      selectRoom,
      roomState => roomState.syncDate
    ),
    selectAllRoomUser: createSelector(selectRoomUser, ngeSelectAllRoomUser),
    selectAllRoomUserShort: createSelector(
      selectRoomUserShort,
      ngeSelectAllRoomUserShort
    ),
    selectChatUnreadCount: createSelector(
      selector,
      (state: State) => state.chatUnreadCount
    ),
  };
}
