import axios from 'axios'
import type {Organization, App, DeeplinkTemplate, Environment} from '@/types'

// API returns environments as { name: scheme } map; client expects Environment[].
type ApiApp = Omit<App, 'environments'> & { environments: Record<string, string> }

function normalizeApp(api: ApiApp): App {
    const envs: Environment[] = api.environments
        ? Object.entries(api.environments).map(([name, scheme]) => ({name, scheme}))
        : []
    return {...api, environments: envs}
}

const api = axios.create({
    baseURL: import.meta.env.VITE_API_BASE_URL,
    headers: {
        'Content-Type': 'application/json',
    },
})

api.interceptors.response.use(
    (response) => response,
    (error) => {
        const {config, response} = error
        const method = config?.method?.toUpperCase() ?? 'REQUEST'
        const url = config?.url ?? ''
        const data = response.data
        console.error({"data": data})
        if (data) {
            console.error(`[API] ${method} ${url} → ${response.status} ${response.statusText}`, response.data)
            return Promise.reject(Error(data.toString()))
        }
        console.error(`[API] ${method} ${url} → network error`, error.message)
        return Promise.reject(error)
    },
)

// Organizations
export async function getOrganizations() {
    const response = await api.get<Organization[]>('/organizations')
    return response.data
}

export async function createOrganization(name: string) {
    const response = await api.post<Organization>('/organizations', {"name": name})
    return response.data
}

export const getOrganization = (orgId: string) =>
    api.get<Organization>(`/organizations/${orgId}`).then(r => r.data)

export const getOrganizationBySlug = (slug: string) =>
    api.get<Organization>(`/organizations/by-slug/${slug}`).then(r => r.data)

export const deleteOrganization = (orgId: string) =>
    api.delete(`/organizations/${orgId}`)

// Apps
export const getApps = (orgId: string) =>
    api.get<ApiApp[]>(`/organizations/${orgId}/apps`).then(r => r.data.map(normalizeApp))

export async function createApp(
    orgId: string,
    data: { name: string; environments: Record<string, string> }
): Promise<App> {
    const response = await api.post<ApiApp>(`/organizations/${orgId}/apps`, data)
    return normalizeApp(response.data)
}

export const getApp = (orgId: string, appId: string) =>
    api.get<ApiApp>(`/organizations/${orgId}/apps/${appId}`).then(r => normalizeApp(r.data))

export const getAppBySlug = (orgSlug: string, appSlug: string) =>
    api
        .get<ApiApp>(`/organizations/by-slug/${orgSlug}/apps/by-slug/${appSlug}`)
        .then(r => normalizeApp(r.data))

export async function updateApp(
    orgId: string,
    appId: string,
    data: { name: string; environments: Record<string, string> }
): Promise<App> {
    const response = await api.put<ApiApp>(`/organizations/${orgId}/apps/${appId}`, data)
    return normalizeApp(response.data)
}

export const deleteApp = (orgId: string, appId: string) =>
    api.delete(`/organizations/${orgId}/apps/${appId}`)

// Deeplinks
export const getDeeplinks = (orgId: string, appId: string) =>
    api
        .get<DeeplinkTemplate[]>(`/organizations/${orgId}/apps/${appId}/deeplinks`)
        .then(r => r.data)

export const createDeeplink = (
    orgId: string,
    appId: string,
    data: Omit<DeeplinkTemplate, 'id' | 'appId'>
) =>
    api
        .post<DeeplinkTemplate>(`/organizations/${orgId}/apps/${appId}/deeplinks`, data)
        .then(r => r.data)

export const getDeeplink = (orgId: string, appId: string, deeplinkId: string) =>
    api
        .get<DeeplinkTemplate>(
            `/organizations/${orgId}/apps/${appId}/deeplinks/${deeplinkId}`
        )
        .then(r => r.data)

export async function updateDeeplink(
    orgId: string,
    appId: string,
    deeplinkId: string,
    data: Omit<DeeplinkTemplate, 'id' | 'appId'>
) {
    const url = `/organizations/${orgId}/apps/${appId}/deeplinks/${deeplinkId}`
    const response = await api.put<DeeplinkTemplate>(url, data)
    return response.data
}


export const deleteDeeplink = (orgId: string, appId: string, deeplinkId: string) =>
    api.delete(`/organizations/${orgId}/apps/${appId}/deeplinks/${deeplinkId}`)

export default api