import http from 'utils/fetch';
import { api } from 'constants/config';
import { actionTypes } from 'constants/action-types';
import { uploadAssets } from 'utils/upload';
import { AddSource, SourceType } from './source.types';

export function getSources() {
  return async (dispatch, getState) => {
    const { sources } = getState();
    const { pageSize, page } = sources;
    dispatch({
      type: actionTypes.SOURCES_GET_START,
    });

    interface DataSources {
      data_id: number;
      data_name: string;
      desc: string;
      update_time: string | number;
      baseURL: string;
      data_type: string | number;
    }
    interface Resulf {
      data_sources: DataSources[];
    }

    const result: Resulf = await http.get(api.sourceList);

    if (result) {
      if (result.data_sources.length <= pageSize) {
        dispatch(changePage(page > 1 ? page - 1 : 1));
      }
      dispatch({
        type: actionTypes.SOURCES_GET_SUCCESS,
        payload: {
          list: result.data_sources.map((d) => ({
            id: d.data_id,
            name: d.data_name,
            type: d.data_type,
            description: d.desc,
            updatedAt: d.update_time,
            baseURL: d.baseURL,
          })),
        },
      });
    } else {
      dispatch({
        type: actionTypes.SOURCES_GET_FAILURE,
      });
    }

    return result;
  };
}

export function getSource(id) {
  return async () => {
    const result = await http.get(api.sourceGet, { id });

    if (result) {
      return result;
    }
  };
}

export const addSource: AddSource = (data) => {
  let { type, filePath, description = '', user: username, host, ...param } = data || {};
  return async (dispatch, getState) => {
    const { user } = getState();
    const { userInfo } = user;
    const { tenantId } = userInfo;

    if (type === 'csv') {
      if (filePath != null && typeof filePath === 'object') {
        const path = `data/csv/${tenantId}/${filePath.name}`;
        const result = await uploadAssets({ path, file: filePath });
        if (!result) {
          return;
        }
        filePath = result;
      }
    }

    // 去除值的首尾空格
    param = Object.entries(param).reduce((result, item) => {
      result[item[0]] = typeof item[1] === 'string' ? item[1].trim() : item[1];
      return result;
    }, {});

    const result = await http.post(api.sourceAdd, {
      type: type,
      filePath,
      desc: description.trim(),
      username,
      addr: host,
      ...param,
    });

    if (result) {
      dispatch(getSources());
      return result;
    }
  };
};

export function updateSource({ id, type, filePath, host, user: username, ...param }) {
  return async (dispatch, getState) => {
    const { user } = getState();
    const { userInfo } = user;
    const { tenantId } = userInfo;

    if (type === 'csv') {
      if (filePath != null && typeof filePath === 'object') {
        const path = `data/csv/${tenantId}/${filePath.name}`;
        const result = await uploadAssets({ path, file: filePath });
        if (!result) {
          return;
        }
        filePath = result;
      }
    }

    // 去除值的首尾空格
    param = Object.entries(param).reduce((result, item) => {
      result[item[0]] = typeof item[1] === 'string' ? item[1].trim() : item[1];
      return result;
    }, {});

    const result = await http.post(api.sourceUpdate, {
      id,
      type,
      filePath,
      addr: host,
      username,
      ...param,
    });

    if (result) {
      dispatch(getSources());
      return result;
    }
  };
}

export function deleteSource(id) {
  return async (dispatch) => {
    const result = await http.post(api.sourceDelete, { data_id: id });

    if (result) {
      dispatch(getSources());
    }
  };
}

export function getDatabases({
  type,
  host,
  port,
  user,
  id,
  password,
}: {
  type?: string;
  host?: string;
  id?: string | number;
  port?: number | string;
  user?: string;
  password?: string;
}) {
  return async () => {
    let param = {
      data_type: type,
      addr: host,
      port,
      username: user,
      password,
    };
    if (id) {
      param = Object.assign(param, { id });
    }
    const result = await http.post(api.sourceDatabaseList, param);

    if (result) {
      return result;
    }
  };
}

export function testDatabaseConnect({
  type,
  host,
  user,
  ...param
}: {
  type: string;
  host?: string;
  user?: string;
  [x: string]: any;
}) {
  return async () => {
    const result = await http.post(api.sourceTest, {
      data_type: type,
      addr: host,
      username: user,
      ...param,
    });

    if (result) {
      return result;
    }
  };
}

export function searchSources(name) {
  return {
    type: actionTypes.SOURCES_SEARCH,
    payload: {
      search: name,
    },
  };
}

export function changePage(page) {
  return {
    type: actionTypes.SOURCES_PAGE_CHANGE,
    payload: {
      page: page,
    },
  };
}

const initialState: SourceType = {
  loading: true,
  page: 1,
  pageSize: 20,
  search: '',
  list: [],
};

export default function reducer(state = initialState, { type, payload }): SourceType {
  switch (type) {
    case actionTypes.SOURCES_GET_START: {
      return { ...state, loading: true };
    }
    case actionTypes.SOURCES_GET_SUCCESS: {
      return { ...state, list: payload.list, loading: false };
    }
    case actionTypes.SOURCES_GET_FAILURE: {
      return { ...state, loading: false };
    }
    case actionTypes.SOURCES_SEARCH: {
      return { ...state, search: payload.search, page: 1 };
    }
    case actionTypes.SOURCES_PAGE_CHANGE: {
      return { ...state, page: payload.page };
    }
    default:
      return state;
  }
}
