import { graphql, get } from '../api';
import {
    releasePosterFragment,
    releaseActorsFragment,
    releaseTagsFragment,
} from '../fragments';
import { curateRelease } from '../curate';

function curateActor(actor) {
    const curatedActor = {
        ...actor,
        height: actor.heightMetric && {
            metric: actor.heightMetric,
            imperial: actor.heightImperial,
        },
        weight: actor.weightMetric && {
            metric: actor.weightMetric,
            imperial: actor.weightImperial,
        },
        origin: actor.birthCountry && {
            city: actor.birthCity,
            state: actor.birthState,
            country: actor.birthCountry,
        },
        residence: actor.residenceCountry && {
            city: actor.residenceCity,
            state: actor.residenceState,
            country: actor.residenceCountry,
        },
    };

    if (actor.avatar) {
        curatedActor.avatar = actor.avatar.media;
    }

    if (actor.releases) {
        curatedActor.releases = actor.releases.map(release => curateRelease(release.release));
    }

    if (actor.photos) {
        curatedActor.photos = actor.photos.map(photo => photo.media);
    }

    return curatedActor;
}

function initActorActions(store, _router) {
    async function fetchActorBySlug(actorSlug, limit = 100) {
        const { actor } = await graphql(`
            query Actor(
                $actorSlug: String!
                $limit:Int = 1000,
                $after:Date = "1900-01-01",
                $before:Date = "2100-01-01",
                $orderBy:[ReleasesActorsOrderBy!]
                $exclude: [String!]
            ) {
                actor: actorBySlug(slug: $actorSlug) {
                    id
                    name
                    slug
                    gender
                    birthdate
                    age
                    ethnicity
                    bust
                    waist
                    hip
                    naturalBoobs
                    heightMetric: height(units:METRIC)
                    heightImperial: height(units:IMPERIAL)
                    weightMetric: weight(units:METRIC)
                    weightImperial: weight(units:IMPERIAL)
                    hasTattoos
                    hasPiercings
                    tattoos
                    piercings
                    description
                    avatar: actorsAvatarByActorId {
                        media {
                            thumbnail
                            path
                        }
                    }
                    photos: actorsPhotos {
                        media {
                            id
                            thumbnail
                            path
                            index
                        }
                    }
                    birthCity
                    birthState
                    birthCountry: countryByBirthCountryAlpha2 {
                      alpha2
                      name
                      alias
                    }
                    residenceCity
                    residenceState
                    residenceCountry: countryByResidenceCountryAlpha2 {
                      alpha2
                      name
                      alias
                    }
                    social: actorsSocials {
                        id
                        url
                        platform
                    }
                    aliases: actorsByAliasFor {
                        id
                        name
                        slug
                    }
                    releases: releasesActors(
                        filter: {
                            release: {
                                date: {
                                    lessThan: $before,
                                    greaterThan: $after,
                                },
                                releasesTags: {
                                    none: {
                                        tag: {
                                            slug: {
                                                in: $exclude
                                            }
                                        }
                                    }
                                }
                            }
                        },
                        first: $limit,
                        orderBy: $orderBy
                    ) {
                        release {
                            id
                            url
                            title
                            date
                            slug
                            ${releaseActorsFragment}
                            ${releaseTagsFragment}
                            ${releasePosterFragment}
                            site {
                                id
                                name
                                slug
                                url
                                network {
                                    id
                                    name
                                    slug
                                    url
                                }
                            }
                        }
                    }
                }
            }
        `, {
            actorSlug,
            limit,
            after: store.getters.after,
            before: store.getters.before,
            orderBy: store.state.ui.range === 'upcoming' ? 'RELEASE_BY_RELEASE_ID__DATE_ASC' : 'RELEASE_BY_RELEASE_ID__DATE_DESC',
            exclude: store.state.ui.filter,
        });

        return curateActor(actor);
    }

    async function fetchActors({ _commit }, {
        actorSlug,
        limit = 100,
        letter,
        genders,
    }) {
        if (actorSlug) {
            return fetchActorBySlug(actorSlug);
        }

        const { actors } = await graphql(`
            query Actors(
                $limit: Int,
                $letter: String! = "",
                $genders: [String!] = ["female"],
            ) {
                actors(
                    first:$limit,
                    orderBy: NAME_ASC,
                    filter: {
                        name: {
                            startsWith: $letter
                        },
                        or: [
                            {
                                gender: {
                                    in: $genders
                                },
                            },
                            {
                                gender: {
                                    isNull: true
                                },
                            }
                        ]
                    },
                ) {
                    id
                    name
                    slug
                    age
                    birthdate
                    gender
                    avatar: actorsAvatarByActorId {
                        media {
                            thumbnail
                        }
                    }
                    birthCountry: countryByBirthCountryAlpha2 {
                      alpha2
                      name
                      alias
                    }
                }
            }
        `, {
            limit,
            letter,
            genders,
        });

        return actors.map(actor => curateActor(actor));
    }

    async function fetchActorReleases({ _commit }, actorId) {
        const releases = await get(`/actors/${actorId}/releases`, {
            filter: store.state.ui.filter,
            after: store.getters.after,
            before: store.getters.before,
        });

        return releases;
    }

    return {
        fetchActors,
        fetchActorReleases,
    };
}

export default initActorActions;
