import * as lark from "@larksuiteoapi/node-sdk";
import { logger } from "./lib/logger";

export interface UserAccessTokenData {
	access_token: string;
	token_type: string;
	expires_in: number;
	refresh_token: string;
	refresh_expires_in: number;
	scope: string;
	name: string;
	open_id: string;
	email?: string;
}

export class FeishuClient {
	public client: lark.Client;
	public appId: string;
	public appSecret: string;

	constructor(appId: string, appSecret: string) {
		this.appId = appId;
		this.appSecret = appSecret;
		this.client = new lark.Client({
			appId: appId,
			appSecret: appSecret,
			disableTokenCache: false,
		});
	}

	async sendMessage(
		receiveId: string,
		receiveIdType: "open_id" | "user_id" | "email" | "chat_id",
		msgType: string,
		content: Record<string, unknown> | string,
		uuid?: string,
	) {
		// Content needs to be stringified for 'text' type in API, but SDK might handle it differently?
		// Actually SDK expects 'content' as string JSON for 'im.v1.messages.create'
		const contentStr =
			typeof content === "string" ? content : JSON.stringify(content);

		try {
			const response = await this.client.im.message.create({
				params: {
					receive_id_type: receiveIdType,
				},
				data: {
					receive_id: receiveId,
					msg_type: msgType,
					content: contentStr,
					uuid: uuid,
				},
			});

			if (response.code !== 0) {
				logger.error({ response }, "Feishu send message error");
				throw new Error(`Failed to send message: ${response.msg}`);
			}
			return response.data;
		} catch (e) {
			console.error("Feishu SDK error:", e);
			throw e;
		}
	}

	async getUserAccessToken(
		code: string,
	): Promise<UserAccessTokenData | undefined> {
		try {
			const response = await this.client.authen.accessToken.create({
				data: {
					grant_type: "authorization_code",
					code,
				},
			});

			if (response.code !== 0) {
				logger.error({ response }, "Feishu get user access token error");
				throw new Error(`Failed to get user access token: ${response.msg}`);
			}
			return response.data as UserAccessTokenData;
		} catch (e) {
			console.error("Feishu SDK error:", e);
			throw e;
		}
	}
}

// Singleton instance
export const feishuClient = new FeishuClient(
	process.env.FEISHU_APP_ID || "",
	process.env.FEISHU_APP_SECRET || "",
);
