// Package plugin_pathresponse a plugin to rewrite the response body based on request requestUri.
package plugin_pathresponse

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"os"
)

// Config holds the plugin configuration.
type Config struct{}

// CreateConfig creates and initializes the plugin configuration.
func CreateConfig() *Config {
	return &Config{}
}

type pathResponseConfig struct {
	RequestUri string `json:"urlPath,omitempty"`
	FileName   string `json:"fileName,omitempty"`
}

// Static config
var StaticConfig = []pathResponseConfig{
	{
		RequestUri: "/apollo-api/test/?request=1",
		FileName:   "mocks/test-1.json",
	},
	{
		RequestUri: "/apollo-api/test/?request=2",
		FileName:   "mocks/test-2.json",
	},
	{
		RequestUri: "/apollo-api/visited-tracks/?market=global",
		FileName:   "mocks/visited-tracks.json",
	},
	{
		RequestUri: "/gate-api/v1/playlists/streams/graph/?vendor=spotify&start_date=2023-07-16&end_date=2023-07-29&markets=global&playlist_id=0FKH1r0kLKyGSfTZQVCe6c",
		FileName:   "mocks/streams_graph.json",
	},
	{
		RequestUri: "/gate-api/charts/summary/?isrc=USSM12209777&vendor=spotify&offset=0&limit=1",
		FileName:   "mocks/charts-placements-spotify.json",
	},
	{
		RequestUri: "/gate-api/charts/summary/?isrc=USSM12209777&vendor=apple&offset=0&limit=1",
		FileName:   "mocks/charts-placements-apple.json",
	},
	{
		RequestUri: "/gate-api/v1/tracks/playlists/hot-hits/?isrc=USSM12209777&offset=0&order_by=top_market&order_by=code&limit=3",
		FileName:   "mocks/hot-hits.json",
	},
	{
		RequestUri: "/gate-api/v3/playlists/spotify/by-track/?isrc=USSM12209777&offset=0&limit=1&streams_market=us&streams_type=priority",
		FileName:   "mocks/playlists-info-1.json",
	},
	{
		RequestUri: "/gate-api/v3/playlists/spotify/by-track/?isrc=USSM12209777&limit=5&streams_market=us&recent_adds_only=true&order_by=-added_date&order_by=current_position&start_date=2023-08-20&end_date=2023-08-26&streams_type=priority",
		FileName:   "mocks/playlists-info-2.json",
	},
	{
		RequestUri: "/gate-api/v3/playlists/spotify/by-track/?isrc=USSM12209777&limit=5&streams_market=us&order_by=-current_streams&keep_zero_streams=false&start_date=2023-08-20&end_date=2023-08-26&streams_type=priority",
		FileName:   "mocks/playlists-info-3.json",
	},
	{
		RequestUri: "/gate-api/v3/playlists/spotify/by-track/history/?isrc=USSM12209777&offset=0&limit=1&streams_market=us",
		FileName:   "mocks/playlists-info-4.json",
	},
	{
		RequestUri: "/gate-api/v3/playlists/spotify/by-track/history/?isrc=USSM12209777&limit=5&recent_removals_only=true&exclude_current_playlists=true&order_by=-removed_date&order_by=id&streams_market=us",
		FileName:   "mocks/playlists-info-5.json",
	},
	{
		RequestUri: "/dsp-api/analytics/v1/daily-and-weekly-streams-count?isrc=USSM12209777&market=us",
		FileName:   "mocks/market-section-1.json",
	},
	{
		RequestUri: "/dsp-api/analytics/v1/streams-graph?isrc=USSM12209777&start_date=2023-08-13&end_date=2023-08-26&market=us&per_vendors=true",
		FileName:   "mocks/market-section-2.json",
	},
	{
		RequestUri: "/dsp-api/analytics/v1/streams-graph?isrc=USSM12209777&start_date=2023-08-13&end_date=2023-08-26&per_vendors=true",
		FileName:   "mocks/market-section-3.json",
	},
	{
		RequestUri: "/dsp-api/analytics/v1/weekly-streams-count?isrc=USSM12209777&market=us",
		FileName:   "mocks/market-section-4.json",
	},
	{
		RequestUri: "/dsp-api/analytics/v1/total-streams-count?isrc=USSM12209777&market=us",
		FileName:   "mocks/market-section-5.json",
	},
	{
		RequestUri: "/gate-api/v1/tracks/playlists/nmf/?track_id=0yLdNVWF3Srea0uzk55zFn&isrc=USSM12209777&offset=0&include=top_playlist_image_url&order_by=top_market&order_by=code&limit=3",
		FileName:   "mocks/nmf.json",
	},
	{
		RequestUri: "/dsp-api/analytics/v1/tiktok/top-markets?limit=1&isrc=USSM12209777",
		FileName:   "mocks/tiktok.json",
	},
	{
		RequestUri: "/dsp-api/analytics/v1/youtube/videos?group_by=date,video_id&sort_by=views&limit=1&views=0&isrc=USSM12209777&content_type=partner_uploaded,premium_ugc&expand_to=related_isrcs",
		FileName:   "mocks/youtube.json",
	},
	{
		RequestUri: "/dsp-api/consumer_analytics/streams-latest-date?vendors=amazon,apple,spotify",
		FileName:   "mocks/latest-date.json",
	},
	{
		RequestUri: "/vendor-api/spotify/v1/tracks/0yLdNVWF3Srea0uzk55zFn",
		FileName:   "mocks/tri-1.json",
	},
	{
		RequestUri: "/vendor-api/spotify/v1/albums/7I0tjwFtxUwBC1vgyeMAax",
		FileName:   "mocks/tri-2.json",
	},
	{
		RequestUri: "/vendor-api/spotify/v1/search?item_type=track&query=isrc:USSM12209777",
		FileName:   "mocks/tri-3.json",
	},
	{
		RequestUri: "/vendor-api/apple/v1/tracks?isrc=USSM12209777",
		FileName:   "mocks/tri-4.json",
	},
	{
		RequestUri: "/gate-api/distributors/check/?country_code=_gl&track_id=spotify_0yLdNVWF3Srea0uzk55zFn&distributors=sme&distributors=theorchard&distributors=awal",
		FileName:   "mocks/tri-5.json",
	},
	// Add more paths and files as needed
}

type pathResponse struct {
	requestUri string
	file       []byte
}

type pathResponseBody struct {
	name          string
	next          http.Handler
	pathResponses []pathResponse
}

// New creates and returns a new pathResponse plugin instance.
func New(_ context.Context, next http.Handler, config *Config, name string) (http.Handler, error) {
	pathResponses := make([]pathResponse, len(StaticConfig))

	for i, pathResponseConfig := range StaticConfig {
		localFile, err := os.ReadFile(pathResponseConfig.FileName)
		if err != nil {
			return nil, fmt.Errorf("error reading file %q: %w", pathResponseConfig.FileName, err)
		}

		pathResponses[i] = pathResponse{
			requestUri: pathResponseConfig.RequestUri,
			file:       localFile,
		}
	}

	return &pathResponseBody{
		name:          name,
		next:          next,
		pathResponses: pathResponses,
	}, nil
}

func (p *pathResponseBody) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
	h := req.Header.Get("uitest")
	if h == "true" {
		for _, pathResponse := range p.pathResponses {
			if req.RequestURI == pathResponse.requestUri {
				rw.Header().Add("Content-Type", "application/json; charset=utf-8")
				rw.Header().Add("X-Middleware", "plugin-pathresponse")
				rw.WriteHeader(http.StatusOK)
				if _, err := rw.Write(pathResponse.file); err != nil {
					log.Printf("unable to write file content: %v", err)
				}
				return
			}
		}
	}
	p.next.ServeHTTP(rw, req)
}
