import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
import { phishingDetector } from './lib/phishing-detector';

interface UrlCheckRequest {
  url: string;
}

interface PhishingReportRequest {
  url: string;
  pageTitle: string;
  tabId: number;
  timestamp: number;
  reason: string;
  heuristics: Record<string, unknown>;
}

export async function extensionRoutes(fastify: FastifyInstance) {
  fastify.post('/url-check', async (request: FastifyRequest, reply: FastifyReply) => {
    const authReq = request as FastifyRequest & { user?: { id: string; tier?: string } };
    const userId = authReq.user?.id;

    if (!userId) {
      return reply.code(401).send({ error: 'Authentication required' });
    }

    const body = request.body as UrlCheckRequest;
    if (!body.url) {
      return reply.code(400).send({ error: 'url is required' });
    }

    try {
      const url = new URL(body.url);
      const heuristic = phishingDetector.analyzeUrl(body.url);

      const threats = heuristic.threats.map((t) => ({
        type: t.type,
        severity: t.severity,
        source: t.source,
        description: t.description,
      }));

      return reply.send({
        url: body.url,
        domain: url.hostname,
        verdict: heuristic.verdict,
        confidence: heuristic.score / 100,
        threats,
        timestamp: Date.now(),
      });
    } catch (error) {
      const message = error instanceof Error ? error.message : 'URL check failed';
      return reply.code(500).send({ error: message });
    }
  });

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

    if (!userId) {
      return reply.code(401).send({ error: 'Authentication required' });
    }

    const body = request.body as PhishingReportRequest;

    try {
      fastify.log.info({ url: body.url, userId, reason: body.reason }, 'Phishing report received');

      return reply.send({
        success: true,
        reportId: `report_${Date.now()}_${userId}`,
        timestamp: new Date().toISOString(),
      });
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Report submission failed';
      return reply.code(500).send({ error: message });
    }
  });

  fastify.post('/auth', async (request: FastifyRequest, reply: FastifyReply) => {
    const authHeader = request.headers.authorization;
    if (!authHeader?.startsWith('Bearer ')) {
      return reply.code(401).send({ error: 'Bearer token required' });
    }

    const token = authHeader.slice(7);

    try {
      const result = await validateExtensionToken(token, fastify);
      return reply.send(result);
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Authentication failed';
      return reply.code(401).send({ error: message });
    }
  });

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

    if (!userId) {
      return reply.code(401).send({ error: 'Authentication required' });
    }

    try {
      const today = new Date().toDateString();
      return reply.send({
        threatsBlockedToday: 0,
        urlsCheckedToday: 0,
        lastSyncAt: new Date().toISOString(),
        syncDate: today,
      });
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Stats retrieval failed';
      return reply.code(500).send({ error: message });
    }
  });

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

    if (!userId) {
      return reply.code(401).send({ error: 'Authentication required' });
    }

    const body = request.body as { domain: string };
    if (!body.domain) {
      return reply.code(400).send({ error: 'domain is required' });
    }

    try {
      const { prisma } = await import('@shieldai/db');

      const exposures = await prisma.exposure.findMany({
        where: {
          alert: {
            some: {
              userId,
            },
          },
        },
        select: {
          dataSource: true,
          breachName: true,
          metadata: true,
        },
        take: 10,
      });

      const domainLower = body.domain.toLowerCase();
      const relevantExposures = exposures.filter((e) => {
        const meta = e.metadata as Record<string, unknown> | null;
        return meta?.domain?.toLowerCase() === domainLower ||
          String(e.breachName).toLowerCase().includes(domainLower);
      });

      return reply.send({
        exposed: relevantExposures.length > 0,
        sources: relevantExposures.map((e) => e.dataSource),
        count: relevantExposures.length,
      });
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Exposure check failed';
      return reply.code(500).send({ error: message });
    }
  });
}

async function validateExtensionToken(
  token: string,
  fastify: FastifyInstance
): Promise<{ userId: string; tier: string }> {
  try {
    const { prisma } = await import('@shieldai/db');

    const session = await prisma.session.findFirst({
      where: { token },
      include: {
        user: {
          include: {
            subscription: {
              where: { status: 'active' },
              take: 1,
            },
          },
        },
      },
    });

    if (!session) {
      throw new Error('Session not found');
    }

    const tier = session.user.subscription[0]?.tier || 'basic';

    return {
      userId: session.userId,
      tier: tier.toLowerCase(),
    };
  } catch (error) {
    if (error instanceof Error && error.message === 'Session not found') {
      throw error;
    }
    fastify.log.warn({ error }, 'Extension token validation failed');
    throw new Error('Token validation failed');
  }
}
