import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
import {
  numberReputationService,
  smsClassifierService,
  callAnalysisService,
  spamFeedbackService,
} from '../services/spamshield';
import { ErrorHandler, SpamErrorCode } from '../services/spamshield/spamshield.error-handler';

export async function spamshieldRoutes(fastify: FastifyInstance) {
  // Classify SMS text
  fastify.post('/sms/classify', async (request: FastifyRequest, reply: FastifyReply) => {
    const authReq = request as FastifyRequest & { user?: { id: string } };
    const userId = authReq.user?.id;

    if (!userId) {
      ErrorHandler.send(reply, SpamErrorCode.UNAUTHORIZED, 'User ID required', { status: 401 });
      return;
    }

    const body = request.body as { text: string };

    const textValidation = ErrorHandler.validateRequiredField(body.text, 'text');
    if (!textValidation.isValid && textValidation.error) {
      ErrorHandler.send(reply, textValidation.error.code, textValidation.error.message, {
        field: textValidation.error.field,
        status: 400,
      });
      return;
    }

    try {
      const result = await smsClassifierService.classify(body.text);
      return reply.send({
        classification: {
          isSpam: result.isSpam,
          confidence: result.confidence,
          spamFeatures: result.spamFeatures,
        },
      });
    } catch (error) {
      ErrorHandler.send(reply, SpamErrorCode.CLASSIFICATION_FAILED, 'Classification failed', {
        status: 422,
      });
    }
  });

  // Check number reputation
  fastify.post('/number/reputation', async (request: FastifyRequest, reply: FastifyReply) => {
    const authReq = request as FastifyRequest & { user?: { id: string } };
    const userId = authReq.user?.id;

    if (!userId) {
      ErrorHandler.send(reply, SpamErrorCode.UNAUTHORIZED, 'User ID required', { status: 401 });
      return;
    }

    const body = request.body as { phoneNumber: string };

    const phoneValidation = ErrorHandler.validateRequiredField(body.phoneNumber, 'phoneNumber');
    if (!phoneValidation.isValid && phoneValidation.error) {
      ErrorHandler.send(reply, phoneValidation.error.code, phoneValidation.error.message, {
        field: phoneValidation.error.field,
        status: 400,
      });
      return;
    }

    try {
      const result = await numberReputationService.checkReputation(body.phoneNumber);
      return reply.send({
        reputation: {
          isSpam: result.isSpam,
          confidence: result.confidence,
          spamType: result.spamType,
          reportCount: result.reportCount,
        },
      });
    } catch (error) {
      ErrorHandler.send(reply, SpamErrorCode.REPUTATION_CHECK_FAILED, 'Reputation check failed', {
        status: 422,
      });
    }
  });

  // Analyze incoming call
  fastify.post('/call/analyze', async (request: FastifyRequest, reply: FastifyReply) => {
    const authReq = request as FastifyRequest & { user?: { id: string } };
    const userId = authReq.user?.id;

    if (!userId) {
      ErrorHandler.send(reply, SpamErrorCode.UNAUTHORIZED, 'User ID required', { status: 401 });
      return;
    }

    const body = request.body as {
      phoneNumber: string;
      duration?: number;
      callTime: string;
      isVoip?: boolean;
    };

    const phoneValidation = ErrorHandler.validateRequiredField(body.phoneNumber, 'phoneNumber');
    const callTimeValidation = ErrorHandler.validateRequiredField(body.callTime, 'callTime');
    
    if (!phoneValidation.isValid && phoneValidation.error) {
      ErrorHandler.send(reply, phoneValidation.error.code, phoneValidation.error.message, {
        field: phoneValidation.error.field,
        status: 400,
      });
      return;
    }
    
    if (!callTimeValidation.isValid && callTimeValidation.error) {
      ErrorHandler.send(reply, callTimeValidation.error.code, callTimeValidation.error.message, {
        field: callTimeValidation.error.field,
        status: 400,
      });
      return;
    }

    try {
      const result = await callAnalysisService.analyzeCall({
        phoneNumber: body.phoneNumber,
        duration: body.duration,
        callTime: new Date(body.callTime),
        isVoip: body.isVoip,
      });
      return reply.send({
        analysis: {
          decision: result.decision,
          confidence: result.confidence,
          reasons: result.reasons,
        },
      });
    } catch (error) {
      ErrorHandler.send(reply, SpamErrorCode.ANALYSIS_FAILED, 'Call analysis failed', {
        status: 422,
      });
    }
  });

  // Record spam feedback
  fastify.post('/feedback', async (request: FastifyRequest, reply: FastifyReply) => {
    const authReq = request as FastifyRequest & { user?: { id: string } };
    const userId = authReq.user?.id;

    if (!userId) {
      ErrorHandler.send(reply, SpamErrorCode.UNAUTHORIZED, 'User ID required', { status: 401 });
      return;
    }

    const body = request.body as {
      phoneNumber: string;
      isSpam: boolean;
      confidence?: number;
      metadata?: Record<string, unknown>;
    };

    const phoneValidation = ErrorHandler.validateRequiredField(body.phoneNumber, 'phoneNumber');
    if (!phoneValidation.isValid && phoneValidation.error) {
      ErrorHandler.send(reply, phoneValidation.error.code, phoneValidation.error.message, {
        field: phoneValidation.error.field,
        status: 400,
      });
      return;
    }

    const isSpamValidation = ErrorHandler.validateBooleanField(body.isSpam, 'isSpam');
    if (!isSpamValidation.isValid && isSpamValidation.error) {
      ErrorHandler.send(reply, isSpamValidation.error.code, isSpamValidation.error.message, {
        field: isSpamValidation.error.field,
        status: 400,
      });
      return;
    }

    try {
      const feedback = await spamFeedbackService.recordFeedback(
        userId,
        body.phoneNumber,
        body.isSpam,
        body.confidence,
        body.metadata
      );
      return reply.code(201).send({
        feedback: {
          id: feedback.id,
          phoneNumber: feedback.phoneNumber,
          isSpam: feedback.isSpam,
          createdAt: feedback.createdAt,
        },
      });
    } catch (error) {
      ErrorHandler.send(reply, SpamErrorCode.FEEDBACK_RECORD_FAILED, 'Feedback recording failed', {
        status: 422,
      });
    }
  });

  // Get spam history
  fastify.get('/history', async (request: FastifyRequest, reply: FastifyReply) => {
    const authReq = request as FastifyRequest & { user?: { id: string } };
    const userId = authReq.user?.id;

    if (!userId) {
      ErrorHandler.send(reply, SpamErrorCode.UNAUTHORIZED, 'User ID required', { status: 401 });
      return;
    }

    const query = request.query as {
      limit?: string;
      isSpam?: string;
      startDate?: string;
    };

    const results = await spamFeedbackService.getSpamHistory(userId, {
      limit: query.limit ? parseInt(query.limit, 10) : undefined,
      isSpam: query.isSpam !== undefined ? query.isSpam === 'true' : undefined,
      startDate: query.startDate ? new Date(query.startDate) : undefined,
    });

    return reply.send({
      history: results.map((r) => ({
        id: r.id,
        phoneNumber: r.phoneNumber,
        isSpam: r.isSpam,
        createdAt: r.createdAt,
      })),
    });
  });

  // Get spam statistics
  fastify.get('/statistics', async (request: FastifyRequest, reply: FastifyReply) => {
    const authReq = request as FastifyRequest & { user?: { id: string } };
    const userId = authReq.user?.id;

    if (!userId) {
      ErrorHandler.send(reply, SpamErrorCode.UNAUTHORIZED, 'User ID required', { status: 401 });
      return;
    }

    try {
      const stats = await spamFeedbackService.getStatistics(userId);
      return reply.send({ statistics: stats });
    } catch (error) {
      ErrorHandler.send(reply, SpamErrorCode.ANALYSIS_FAILED, 'Statistics retrieval failed', {
        status: 422,
      });
    }
  });
}
