import { Application } from 'express';
import { Resource } from 'express-automatic-routes';
import { Req, Res } from '#interfaces/IApi';
import { AuthService } from '#services/auth';
import ZaloService from '#services/auth/zaloService';
import { createRateLimit } from '#middlewares/auth';
import Logger from '#utils/logger';
import { GenericError } from '#interfaces/error/generic';
import { buildMobileLoginResponse } from '#utils/authResponseUtils';
import { sendSuccess } from '#utils/responseUtils';

/**
 * Zalo Mini App Login Controller
 * Bearer token authentication for Zalo Mini App
 */
export default (_express: Application) => {
	return <Resource>{
		post: {
			middleware: [createRateLimit(15 * 60 * 1000, 20)] as any,
			handler: async (req: Req, res: Res) => {
				try {
					const { zalo_code, zalo_open_id, device_info } = req.body;

					// Require device ID
					const deviceId = req.headers['x-device-id'] as string;

					if (!deviceId) {
						throw new GenericError('VALIDATION_ERROR', { field: 'x-device-id' });
					}

					if (!zalo_code && !zalo_open_id) {
						throw new GenericError('VALIDATION_ERROR', { field: 'zalo_code' });
					}

					// Verify Zalo code and get user info
					let zaloUserInfo;
					if (zalo_code) {
						const tokenResponse = await ZaloService.verifyZaloCode(zalo_code);
						zaloUserInfo = await ZaloService.getZaloUserInfo(tokenResponse.access_token);
					} else if (zalo_open_id) {
						zaloUserInfo = await ZaloService.verifyZaloOpenId(zalo_open_id);
					}

					if (!zaloUserInfo) {
						throw new GenericError('INVALID_CREDENTIALS');
					}

					// Authenticate/Register user via Zalo
					const loginResult = await AuthService.zaloLogin(
						zaloUserInfo,
						device_info,
						req.ip || '',
						req.get('User-Agent') || '',
					);

					Logger.info('Zalo login successful', {
						requestId: (req as any).requestId,
						userId: loginResult.user.id,
						platform: 'zalo_miniapp',
						deviceId,
					});

					return sendSuccess(
						res,
						buildMobileLoginResponse(loginResult) as any,
						'Đăng nhập thành công',
						'Login successful',
					);
				} catch (error) {
					return res.error(error);
				}
			},
		},
	};
};
