import axios, { type AxiosError } from 'axios';
import { auth } from '$lib/stores/auth';
import { browser } from '$app/environment';
import { get } from 'svelte/store';

// Use environment variable or default to localhost
const API_BASE_URL = browser 
	? (import.meta.env.VITE_API_URL || 'http://localhost:8000')
	: (import.meta.env.VITE_API_URL || 'http://localhost:8000');

const api = axios.create({
	baseURL: API_BASE_URL,
	headers: {
		'Content-Type': 'application/json'
	}
});

export { api };

api.interceptors.request.use((config) => {
	const authState = get(auth);
	if (authState.token) {
		config.headers.Authorization = `Bearer ${authState.token}`;
	}
	return config;
});

api.interceptors.response.use(
	(response) => response,
	(error: AxiosError) => {
		if (error.response?.status === 401) {
			auth.logout();
			if (browser) {
				window.location.href = '/';
			}
		}
		return Promise.reject(error);
	}
);

export interface Score {
	id: string;
	name: string;
	compositor: string;
	ressource?: string | null;
	instruments?: Instrument[];
}

export interface Piece {
	id: number;
	name: string;
}

export interface Instrument {
	id: string;
	title: string;
	piece: string;
	parts: Part[];
}

export interface Part {
	id: string;
	files: PdfFile[];
}

export interface PdfFile {
	name: string;
	filename: string;
	path: string;
	part: string | null;
	key: string | null;
	clef: string | null;
	variant: string | null;
}

export const apiService = {
	async login(username: string, password: string): Promise<{ token: string; user: { username: string; role: string } }> {
		const response = await api.post('/login', { username, password });
		return response.data;
	},

	async getScores(): Promise<Score[]> {
		const response = await api.get('/scores');
		return response.data.scores;
	},

	async getScore(id: string): Promise<Score> {
		const response = await api.get(`/scores/${id}`);
		return response.data.score;
	},

	async getInstruments(scoreId: string, pieceId?: number): Promise<Instrument[]> {
		const url = pieceId 
			? `/scores/${scoreId}/instruments?piece=${pieceId}`
			: `/scores/${scoreId}/instruments`;
		const response = await api.get(url);
		return response.data.instruments;
	},

	async getPieces(scoreId: string): Promise<Piece[]> {
		const response = await api.get(`/pieces/${scoreId}`);
		return response.data.pieces;
	},

	async downloadPdf(path: string): Promise<Blob> {
		const response = await api.get(`/download/${path}`, {
			responseType: 'blob'
		});
		return response.data;
	},

	getDownloadUrl(path: string): string {
		// Security: Token is now passed via Authorization header, not URL
		// The backend will read the token from the header in the request
		return `${API_BASE_URL}/download/${path}`;
	},

	// New method to download with proper auth header
	async downloadFileWithAuth(path: string): Promise<Blob> {
		const response = await api.get(`/download/${path}`, {
			responseType: 'blob'
		});
		return response.data;
	},

	async createScore(name: string, compositor: string, pieces: { number: number; name: string }[] = []): Promise<{ success: boolean; score?: any; error?: string }> {
		const response = await api.post('/admin/scores', { name, compositor, pieces });
		return response.data;
	},

	async updateScore(id: string, name: string, compositor: string): Promise<{ success: boolean; error?: string }> {
		const response = await api.put(`/admin/scores/${id}`, { name, compositor });
		return response.data;
	},

	async deleteScore(id: string): Promise<{ success: boolean; error?: string }> {
		const response = await api.delete(`/admin/scores/${id}`);
		return response.data;
	},

	async uploadPdf(scoreId: string, file: File, piece: string, instrument: string, version: string, key?: string, clef?: string, variant?: string, part?: string): Promise<{ success: boolean; path?: string; error?: string }> {
		const formData = new FormData();
		formData.append('file', file);
		formData.append('piece', piece);
		formData.append('instrument', instrument);
		formData.append('version', version);
		if (key) formData.append('key', key);
		if (clef) formData.append('clef', clef);
		if (variant) formData.append('variant', variant);
		if (part) formData.append('part', part);
		
		const response = await api.post(`/admin/scores/${scoreId}/upload`, formData, {
			headers: {
				'Content-Type': 'multipart/form-data'
			}
		});
		return response.data;
	},

	async getScoreFiles(scoreId: string): Promise<{ success: boolean; files: any[]; error?: string }> {
		const response = await api.get(`/admin/scores/${scoreId}/files`);
		return response.data;
	},

	async deleteScoreFile(scoreId: string, filePath: string): Promise<{ success: boolean; error?: string }> {
		const response = await api.delete(`/admin/scores/${scoreId}/files`, {
			params: { path: filePath }
		});
		return response.data;
	}
};
