import { getConfig, NotFoundError } from "blitz";
import type { MessageInstance } from "twilio/lib/rest/api/v2010/account/message";
import type { CallInstance } from "twilio/lib/rest/api/v2010/account/call";
import twilio from "twilio";

import type { Organization } from "db";
import { CallStatus, Direction, MessageStatus } from "../db";

type MinimalOrganization = Pick<Organization, "twilioAccountSid" | "twilioApiKey" | "twilioApiSecret">;

export default function getTwilioClient(organization: MinimalOrganization | null): twilio.Twilio {
	if (
		!organization ||
		!organization.twilioAccountSid ||
		!organization.twilioApiKey ||
		!organization.twilioApiSecret
	) {
		throw new NotFoundError();
	}

	return twilio(organization.twilioApiKey, organization.twilioApiSecret, {
		accountSid: organization.twilioAccountSid,
	});
}

const { serverRuntimeConfig } = getConfig();

export const smsUrl = `https://${serverRuntimeConfig.app.baseUrl}/api/webhook/incoming-message`;

export const voiceUrl = `https://${serverRuntimeConfig.app.baseUrl}/api/webhook/call`;

export function getTwiMLName() {
	switch (serverRuntimeConfig.app.baseUrl) {
		case "local.shellphone.app":
			return "Shellphone LOCAL";
		case "dev.shellphone.app":
			return "Shellphone DEV";
		case "www.shellphone.app":
			return "Shellphone";
	}
}

export function translateMessageStatus(status: MessageInstance["status"]): MessageStatus {
	switch (status) {
		case "accepted":
			return MessageStatus.Accepted;
		case "canceled":
			return MessageStatus.Canceled;
		case "delivered":
			return MessageStatus.Delivered;
		case "failed":
			return MessageStatus.Failed;
		case "partially_delivered":
			return MessageStatus.PartiallyDelivered;
		case "queued":
			return MessageStatus.Queued;
		case "read":
			return MessageStatus.Read;
		case "received":
			return MessageStatus.Received;
		case "receiving":
			return MessageStatus.Receiving;
		case "scheduled":
			return MessageStatus.Scheduled;
		case "sending":
			return MessageStatus.Sending;
		case "sent":
			return MessageStatus.Sent;
		case "undelivered":
			return MessageStatus.Undelivered;
	}
}

export function translateMessageDirection(direction: MessageInstance["direction"]): Direction {
	switch (direction) {
		case "inbound":
			return Direction.Inbound;
		case "outbound-api":
		case "outbound-call":
		case "outbound-reply":
		default:
			return Direction.Outbound;
	}
}

export function translateCallStatus(status: CallInstance["status"]): CallStatus {
	switch (status) {
		case "busy":
			return CallStatus.Busy;
		case "canceled":
			return CallStatus.Canceled;
		case "completed":
			return CallStatus.Completed;
		case "failed":
			return CallStatus.Failed;
		case "in-progress":
			return CallStatus.InProgress;
		case "no-answer":
			return CallStatus.NoAnswer;
		case "queued":
			return CallStatus.Queued;
		case "ringing":
			return CallStatus.Ringing;
	}
}

export function translateCallDirection(direction: CallInstance["direction"]): Direction {
	switch (direction) {
		case "inbound":
			return Direction.Inbound;
		case "outbound":
		default:
			return Direction.Outbound;
	}
}
