import { AxiosInstance } from 'axios'
import { HealthStatus, ListInfo } from '../common/types'
import {
	CreatePdfTemplate,
	ListPdfTemplatesQuery,
	PdfTemplate,
	RenderPdfWithCustomTemplateRequest,
	UpdatePdfTemplate,
} from './types'
import { OrganizerName, OrganizerSpecificId } from '../event'
import { getStringifiedQuery } from '../common/query'

export class PdfService {
	constructor(readonly client: AxiosInstance, readonly version: string) {}

	/**
	 * Returns true if the service is reachable
	 *
	 * @returns Services' online status
	 */
	async health(): Promise<HealthStatus> {
		try {
			const res = await this.client.get(`pdf/health`)
			if ((res.data.status as string).toLowerCase() === 'ok') {
				return { online: true }
			}
		} catch (e) {
			// Do nothing
		}

		return { online: false }
	}

	/**
	 * Create a PDF template for a specific organizer
	 * Requires the `event.event.create` org level permission for the organizer
	 * @param orgName.name The specified organizer
	 * @param template The PDF template that should be created
	 * @throws `ApiError` when the QR code image is missing
	 */
	async createPdfTemplate(
		orgName: OrganizerName,
		template: CreatePdfTemplate
	): Promise<PdfTemplate> {
		const res = await this.client.post(
			`/pdf/v1/organizer/${orgName.name}/template`,
			template
		)

		return res.data.data
	}

	/**
	 * Update an existing PDF template
	 * Requires the `event.event.create` org level permission for the organizer
	 * @param id.id ID of the PDF template
	 * @param id.organizerId Name of the organizer
	 * @param template The updated PDF template
	 * @throws `ApiError` when the QR code image is missing
	 */
	async updatePdfTemplate(
		id: OrganizerSpecificId,
		template: UpdatePdfTemplate
	): Promise<PdfTemplate> {
		const res = await this.client.patch(
			`/pdf/v1/organizer/${id.organizerId}/template/${id.id}`,
			template
		)

		return res.data.data
	}

	/**
	 * Get a single PDF template by the ID
	 * Requires the `event.event.create` org level permission for the organizer
	 * @param id.id The PDF templates ID
	 * @param id.organizerId Name of the organizer the PDF template is belonging to
	 */
	async getSinglePdfTemplate(id: OrganizerSpecificId): Promise<PdfTemplate> {
		const res = await this.client.get(
			`/pdf/v1/organizer/${id.organizerId}/template/${id.id}`
		)

		return res.data.data
	}

	/**
	 * Query the PDF template for a specific organizer
	 * Requires the `event.event.create` org level permission for the organizer
	 * @param orgName.name Name of the organizer the PDF templates are belonging to
	 * @param query.name Query PDF templates by the `name`
	 */
	async getListPdfTemplate(
		orgName: OrganizerName,
		query: ListPdfTemplatesQuery = {}
	): Promise<ListInfo<PdfTemplate>> {
		const res = await this.client.get(
			`/pdf/v1/organizer/${orgName.name}/template?${getStringifiedQuery(query)}`
		)

		const data = res.data
		return {
			data: data.data,
			paging: { limit: data.limit, offset: data.offset, total: data.total },
		}
	}

	/**
	 * Render a PDF with a custom template. Requires event permission for any organizer.
	 * @param request.template The custom Scriban template created with our PDF template editor
	 * @param request.pdfTicket Data that will be passed to the template
	 * @returns Rendered PDF
	 */
	async renderPdfWithCustomTemplate(
		request: RenderPdfWithCustomTemplateRequest
	): Promise<string> {
		const res = await this.client.post(
			`/pdf/v1/organizer/custom-template/ticket`,
			request,
			{ responseType: 'blob' }
		)

		return res.data
	}
}
