package controller

import (
    "arimelody-web/model"

    "github.com/jmoiron/sqlx"
)

// DATABASE

func GetArtist(db *sqlx.DB, id string) (*model.Artist, error) {
    var artist = model.Artist{}

    err := db.Get(&artist, "SELECT * FROM artist WHERE id=$1", id)
    if err != nil {
        return nil, err
    }

    return &artist, nil
}

func GetAllArtists(db *sqlx.DB) ([]*model.Artist, error) {
    var artists = []*model.Artist{}

    err := db.Select(&artists, "SELECT * FROM artist")
    if err != nil {
        return nil, err
    }

    return artists, nil
}

func GetArtistsNotOnRelease(db *sqlx.DB, releaseID string) ([]*model.Artist, error) {
    var artists = []*model.Artist{}

    err := db.Select(&artists,
        "SELECT * FROM artist "+
        "WHERE id NOT IN "+
        "(SELECT artist FROM musiccredit WHERE release=$1)",
        releaseID)
    if err != nil {
        return nil, err
    }

    return artists, nil
}

func GetArtistCredits(db *sqlx.DB, artistID string, show_hidden bool) ([]*model.Credit, error) {
    var query string = "SELECT release.id,title,artwork,release_date,artist.id,name,website,avatar,role,is_primary "+
        "FROM musiccredit "+
        "JOIN musicrelease AS release ON release=release.id "+
        "JOIN artist ON artist=artist.id "+
        "WHERE artist=$1 "
    if !show_hidden { query += "AND visible=true " }
    query += "ORDER BY release_date DESC"
    rows, err := db.Query(query, artistID)
    if err != nil {
        return nil, err
    }
    defer rows.Close()
    
    type NamePrimary struct {
        Name    string  `json:"name"`
        Primary bool    `json:"primary" db:"is_primary"`
    }
    var credits []*model.Credit
    for rows.Next() {
        var credit model.Credit
        err = rows.Scan(
            &credit.Release.ID,
            &credit.Release.Title,
            &credit.Release.Artwork,
            &credit.Release.ReleaseDate,
            &credit.Artist.ID,
            &credit.Artist.Name,
            &credit.Artist.Website,
            &credit.Artist.Avatar,
            &credit.Role,
            &credit.Primary,
        )

        otherArtists := []NamePrimary{}
        err = db.Select(&otherArtists,
            "SELECT name,is_primary FROM artist "+
            "JOIN musiccredit ON artist=id "+
            "WHERE release=$1",
            credit.Release.ID)
        for _, otherCredit := range otherArtists {
            credit.Release.Credits = append(credit.Release.Credits, &model.Credit{
                Artist: model.Artist{
                    Name: otherCredit.Name,
                },
                Primary: otherCredit.Primary,
            })
        }

        credits = append(credits, &credit)
    }

    return credits, nil
}

func CreateArtist(db *sqlx.DB, artist *model.Artist) error {
    _, err := db.Exec(
        "INSERT INTO artist (id, name, website, avatar) "+
        "VALUES ($1, $2, $3, $4)",
        artist.ID,
        artist.Name,
        artist.Website,
        artist.Avatar,
    )
    if err != nil {
        return err
    }
    
    return nil
}

func UpdateArtist(db *sqlx.DB, artist *model.Artist) error {
    _, err := db.Exec(
        "UPDATE artist "+
        "SET name=$2, website=$3, avatar=$4 "+
        "WHERE id=$1",
        artist.ID,
        artist.Name,
        artist.Website,
        artist.Avatar,
    )
    if err != nil {
        return err
    }

    return nil
}

func DeleteArtist(db *sqlx.DB, artistID string) error {
    _, err := db.Exec(
        "DELETE FROM artist "+
        "WHERE id=$1",
        artistID,
    )
    if err != nil {
        return err
    }

    return nil
}
