import { Router } from 'express';
import type { Request, Response } from 'express';
import { authenticate } from '../../middleware/auth.middleware';
import { friendRequestRateLimit } from './social.rate-limits';
import { friendshipService } from './friendship.service';
import { sendFriendRequestSchema, friendsPaginationSchema } from './social.schemas';
import { checkSocialEnabled } from './social.middleware';

const router = Router();
router.use(authenticate);
router.use(checkSocialEnabled);

/** GET /api/social/friends — list accepted friends (paginated) */
router.get('/', async (req: Request, res: Response) => {
  try {
    const { page, limit } = friendsPaginationSchema.parse(req.query);
    const result = await friendshipService.listFriends(req.user!.id, page, limit);
    res.json(result);
  } catch (err: any) {
    res.status(err.statusCode || 500).json({ error: { message: err.message, code: 'FRIENDS_LIST_ERROR' } });
  }
});

/** GET /api/social/friends/pending/received — incoming requests */
router.get('/pending/received', async (req: Request, res: Response) => {
  try {
    const requests = await friendshipService.listPendingReceived(req.user!.id);
    res.json({ requests });
  } catch (err: any) {
    res.status(err.statusCode || 500).json({ error: { message: err.message, code: 'PENDING_RECEIVED_ERROR' } });
  }
});

/** GET /api/social/friends/pending/sent — outgoing requests */
router.get('/pending/sent', async (req: Request, res: Response) => {
  try {
    const requests = await friendshipService.listPendingSent(req.user!.id);
    res.json({ requests });
  } catch (err: any) {
    res.status(err.statusCode || 500).json({ error: { message: err.message, code: 'PENDING_SENT_ERROR' } });
  }
});

/** POST /api/social/friends/request — send friend request */
router.post('/request', friendRequestRateLimit, async (req: Request, res: Response) => {
  try {
    const { userId } = sendFriendRequestSchema.parse(req.body);
    const friendship = await friendshipService.sendRequest(req.user!.id, userId);
    res.status(201).json(friendship);
  } catch (err: any) {
    res.status(err.statusCode || 500).json({ error: { message: err.message, code: 'FRIEND_REQUEST_ERROR' } });
  }
});

/** POST /api/social/friends/:id/accept — accept request */
router.post('/:id/accept', async (req: Request, res: Response) => {
  try {
    const friendshipId = parseInt(req.params.id as string, 10);
    if (isNaN(friendshipId)) {
      res.status(400).json({ error: { message: 'Invalid friendship ID', code: 'INVALID_ID' } });
      return;
    }
    const friendship = await friendshipService.acceptRequest(req.user!.id, friendshipId);
    res.json(friendship);
  } catch (err: any) {
    res.status(err.statusCode || 500).json({ error: { message: err.message, code: 'ACCEPT_ERROR' } });
  }
});

/** POST /api/social/friends/:id/decline — decline request */
router.post('/:id/decline', async (req: Request, res: Response) => {
  try {
    const friendshipId = parseInt(req.params.id as string, 10);
    if (isNaN(friendshipId)) {
      res.status(400).json({ error: { message: 'Invalid friendship ID', code: 'INVALID_ID' } });
      return;
    }
    const friendship = await friendshipService.declineRequest(req.user!.id, friendshipId);
    res.json(friendship);
  } catch (err: any) {
    res.status(err.statusCode || 500).json({ error: { message: err.message, code: 'DECLINE_ERROR' } });
  }
});

/** DELETE /api/social/friends/:id/cancel — cancel sent request */
router.delete('/:id/cancel', async (req: Request, res: Response) => {
  try {
    const friendshipId = parseInt(req.params.id as string, 10);
    if (isNaN(friendshipId)) {
      res.status(400).json({ error: { message: 'Invalid friendship ID', code: 'INVALID_ID' } });
      return;
    }
    const result = await friendshipService.cancelRequest(req.user!.id, friendshipId);
    res.json(result);
  } catch (err: any) {
    res.status(err.statusCode || 500).json({ error: { message: err.message, code: 'CANCEL_ERROR' } });
  }
});

/** DELETE /api/social/friends/:friendId — unfriend */
router.delete('/:friendId', async (req: Request, res: Response) => {
  try {
    const friendId = req.params.friendId as string;
    const result = await friendshipService.unfriend(req.user!.id, friendId);
    res.json(result);
  } catch (err: any) {
    res.status(err.statusCode || 500).json({ error: { message: err.message, code: 'UNFRIEND_ERROR' } });
  }
});

/** GET /api/social/friends/status/:userId — check relationship */
router.get('/status/:userId', async (req: Request, res: Response) => {
  try {
    const otherUserId = req.params.userId as string;
    const status = await friendshipService.getFriendshipStatus(req.user!.id, otherUserId);
    res.json(status);
  } catch (err: any) {
    res.status(err.statusCode || 500).json({ error: { message: err.message, code: 'STATUS_ERROR' } });
  }
});

/** GET /api/social/friends/mutual/:userId — mutual friends */
router.get('/mutual/:userId', async (req: Request, res: Response) => {
  try {
    const otherUserId = req.params.userId as string;
    const result = await friendshipService.getMutualFriends(req.user!.id, otherUserId);
    res.json(result);
  } catch (err: any) {
    res.status(err.statusCode || 500).json({ error: { message: err.message, code: 'MUTUAL_FRIENDS_ERROR' } });
  }
});

export { router as friendshipRouter };
