import { Request, Response } from 'express';
import { ApiTokenService } from '../services/apiToken.service';
import { ResponseHandler } from '../utils/responseHandler';
import { AuthenticatedRequest } from '../types/express';
import { z } from 'zod';

const createTokenSchema = z.object({
    name: z.string().min(1).max(100),
    expiresInDays: z.number().int().positive().optional(),
});

export class ApiTokenController {
    private apiTokenService: ApiTokenService;

    constructor() {
        this.apiTokenService = new ApiTokenService();
    }

    /**
     * Create a new API Token
     */
    async create(req: AuthenticatedRequest, res: Response): Promise<void> {
        try {
            const validation = createTokenSchema.safeParse(req.body);
            if (!validation.success) {
                ResponseHandler.error(res, 'Validation error', 400, validation.error.message);
                return;
            }

            const { name, expiresInDays } = validation.data;
            const userId = req.user.userId;

            const result = await this.apiTokenService.createToken(userId, name, expiresInDays);

            ResponseHandler.success(res, {
                token: result.token,
                apiToken: result.apiToken
            }, 'API Token created successfully. Please copy the token now, you will not be able to see it again.');
        } catch (error) {
            const errorMessage = error instanceof Error ? error.message : 'Unknown error';
            ResponseHandler.error(res, 'Failed to create API token', 500, errorMessage);
        }
    }

    /**
     * List user's API Tokens
     */
    async list(req: AuthenticatedRequest, res: Response): Promise<void> {
        try {
            const userId = req.user.userId;
            const tokens = await this.apiTokenService.listTokens(userId);
            ResponseHandler.success(res, { tokens }, 'API Tokens retrieved successfully');
        } catch (error) {
            const errorMessage = error instanceof Error ? error.message : 'Unknown error';
            ResponseHandler.error(res, 'Failed to list API tokens', 500, errorMessage);
        }
    }

    /**
     * Revoke an API Token
     */
    async revoke(req: AuthenticatedRequest, res: Response): Promise<void> {
        try {
            const userId = req.user.userId;
            const { id } = req.params;

            const success = await this.apiTokenService.revokeToken(userId, id);

            if (success) {
                ResponseHandler.success(res, null, 'API Token revoked successfully');
            } else {
                ResponseHandler.notFound(res, 'Token not found or already revoked');
            }
        } catch (error) {
            const errorMessage = error instanceof Error ? error.message : 'Unknown error';
            ResponseHandler.error(res, 'Failed to revoke API token', 500, errorMessage);
        }
    }
}
