import { ApolloError } from "apollo-boost";
import gql from "graphql-tag";
import { graphql } from "react-apollo";


/////////////////////////////////////////////////////////////////////
// somehow generate these interfaces based on the query and schema //
/////////////////////////////////////////////////////////////////////
interface IPost {
  id: number;
  title: string;
}
interface IResponse {
  allPosts?: IPost[];
}
interface IVariables {
  first: number;
  skip: number;
}
interface IActions {
  loadMorePosts: () => void;
}
interface IApolloResponse<R /* The response format */> {
  data: R & {
    /* the tricky part is that we have to only select some
       of the response fields here */
    error?: ApolloError;
    loading: boolean;
  };
};
type ChildProps = IActions & IApolloResponse<IResponse>;


const ALL_POST_QUERY = gql`
  query allPosts($first: Int!, $skip: Int!) {
    allPosts(first: $first, skip: $skip) {
      id
      title
    }
  }
`;

const withData = graphql<{}, IResponse, IVariables, ChildProps>(
  ALL_POST_QUERY,
  {
    options: {
      variables: { first: 5, skip: 0 }
    },
    props: ({ data }): ChildProps => {
      return { 
        data, 
        loadMorePosts: () => {
          // do stuff here
        }
      };
    }
  }
);

const component = ({
  data: { 
    loading, 
    error, 
    allPosts 
  },
  loadMorePosts
}: ChildProps) => {
  if (error) {
    return <div>Error loading posts.</div>;
  }
  if (loading) {
    return <div>Loading......</div>;
  }
  if (allPosts && allPosts.length) {
    return (
      <div>
        <ul>
          {allPosts.map(post => <li key={post.id}>{post.title}</li>)}
        </ul>
        <button onClick={() => loadMorePosts()}>Show More</button>
      </div>
    );
  }
  return <div>No post to show</div>;
}

export default withData(component)