import type { TimeEntry, TimeEntryWrite } from './dto/time-entry'
import type { HydraCollection } from '~/utils/api'
import { extractHydraMembers } from '~/utils/api'

export function useTimeEntryService() {
    const api = useApi()

    async function getByDateRange(params: {
        after: string
        before: string
        user?: number
        project?: number
        tag?: number
    }): Promise<TimeEntry[]> {
        const query: Record<string, unknown> = {
            'startedAt[after]': params.after,
            'startedAt[before]': params.before,
        }
        if (params.user) {
            query.user = `/api/users/${params.user}`
        }
        if (params.project) {
            query.project = `/api/projects/${params.project}`
        }
        if (params.tag) {
            query['tags[]'] = `/api/task_tags/${params.tag}`
        }
        const data = await api.get<HydraCollection<TimeEntry>>('/time_entries/range', query)
        return extractHydraMembers(data)
    }

    async function getActive(): Promise<TimeEntry | null> {
        try {
            const data = await api.get<HydraCollection<TimeEntry>>('/time_entries/active', {}, { toast: false })
            const members = extractHydraMembers(data)
            return members[0] ?? null
        } catch {
            return null
        }
    }

    async function create(payload: TimeEntryWrite): Promise<TimeEntry> {
        return api.post<TimeEntry>('/time_entries', payload as Record<string, unknown>, {
            toastSuccessKey: 'timeEntries.created',
        })
    }

    async function update(id: number, payload: Partial<TimeEntryWrite>): Promise<TimeEntry> {
        return api.patch<TimeEntry>(`/time_entries/${id}`, payload as Record<string, unknown>, {
            toastSuccessKey: 'timeEntries.updated',
        })
    }

    async function remove(id: number): Promise<void> {
        await api.delete(`/time_entries/${id}`, {}, {
            toastSuccessKey: 'timeEntries.deleted',
        })
    }

    function getExportUrl(params: {
        after: string
        before: string
        users?: number[]
        projects?: number[]
        client?: number
        tags?: number[]
    }): string {
        const query = new URLSearchParams()
        query.set('after', params.after)
        query.set('before', params.before)
        if (params.users?.length) {
            params.users.forEach(id => query.append('users[]', String(id)))
        }
        if (params.client) query.set('client', String(params.client))
        if (params.projects?.length) {
            params.projects.forEach(id => query.append('projects[]', String(id)))
        }
        if (params.tags?.length) {
            params.tags.forEach(id => query.append('tags[]', String(id)))
        }
        return `/time_entries/export?${query.toString()}`
    }

    async function downloadExport(params: {
        after: string
        before: string
        users?: number[]
        projects?: number[]
        client?: number
        tags?: number[]
    }): Promise<{ blob: Blob; filename: string }> {
        const url = getExportUrl(params)
        const response = await api.getBlob(url)
        const disposition = response.headers.get('content-disposition') ?? ''
        const filenameMatch = disposition.match(/filename="?([^";\n]+)"?/)
        const filename = filenameMatch?.[1] ?? `export-temps-${params.after}_${params.before}.xlsx`
        return { blob: response.data, filename }
    }

    return { getByDateRange, getActive, create, update, remove, getExportUrl, downloadExport }
}
