import { router, protectedProcedure } from '@/src/trpc/trpc-index'
import { z } from 'zod';
import { generateSignedUrlsFromS3Urls } from '@/src/lib/s3-client'
import { queueDataPusher } from '@/src/lib/queue-data-pusher'
import {
  getComplaintById,
  getComplaints as getComplaintsFromDb,
  getNotifTokensByUserIds,
  resolveComplaint as resolveComplaintInDb,
} from '@/src/dbService'
import type { ComplaintWithUser } from '@packages/shared'

export const complaintRouter = router({
  getAll: protectedProcedure
    .input(z.object({
      cursor: z.number().optional(),
      limit: z.number().default(20),
    }))
    .query(async ({ input }): Promise<{
      complaints: Array<{
        id: number;
        text: string;
        userId: number;
        userName: string | null;
        userMobile: string | null;
        orderId: number | null;
        status: string;
        createdAt: Date;
        images: string[];
      }>;
      nextCursor?: number;
    }> => {
      const { cursor, limit } = input;

      // Using dbService helper (new implementation)
      const { complaints: complaintsData, hasMore } = await getComplaintsFromDb(cursor, limit);

      /*
      // Old implementation - direct DB query:
      const { cursor, limit } = input;

      let whereCondition = cursor 
        ? lt(complaints.id, cursor) 
        : undefined;

      const complaintsData = await db
        .select({
          id: complaints.id,
          complaintBody: complaints.complaintBody,
          userId: complaints.userId,
          orderId: complaints.orderId,
          isResolved: complaints.isResolved,
          createdAt: complaints.createdAt,
          userName: users.name,
          userMobile: users.mobile,
          images: complaints.images,
        })
        .from(complaints)
        .leftJoin(users, eq(complaints.userId, users.id))
        .where(whereCondition)
        .orderBy(desc(complaints.id))
        .limit(limit + 1);

      const hasMore = complaintsData.length > limit;
      const complaintsToReturn = hasMore ? complaintsData.slice(0, limit) : complaintsData;
      */

      const complaintsToReturn = hasMore ? complaintsData.slice(0, limit) : complaintsData;

      const complaintsWithSignedImages = await Promise.all(
        complaintsToReturn.map(async (c: ComplaintWithUser) => {
          const signedImages = c.images
            ? await generateSignedUrlsFromS3Urls(c.images as string[])
            : [];

          return {
            id: c.id,
            text: c.complaintBody,
            userId: c.userId,
            userName: c.userName,
            userMobile: c.userMobile,
            orderId: c.orderId,
            status: c.isResolved ? 'resolved' : 'pending',
            createdAt: c.createdAt,
            images: signedImages,
          };
        })
      );

      return {
        complaints: complaintsWithSignedImages,
        nextCursor: hasMore
          ? complaintsToReturn[complaintsToReturn.length - 1].id
          : undefined,
      };
    }),

  resolve: protectedProcedure
    .input(z.object({ id: z.string(), response: z.string().min(1) }))
    .mutation(async ({ input }): Promise<{ message: string }> => {
      const complaintId = parseInt(input.id)
      const responseText = input.response.trim()

      const complaint = await getComplaintById(complaintId)

      if (!complaint) {
        throw new Error('Complaint not found')
      }

      // Using dbService helper (new implementation)
      await resolveComplaintInDb(complaintId, responseText)

      const tokens = await getNotifTokensByUserIds([complaint.userId])
      for (const t of tokens) {
        try {
          await queueDataPusher.pushNotifQueue({
            name: 'send-admin-notification',
            jobData: {
              token: t.token,
              title: 'Complaint Response Received',
              body: responseText,
              imageUrl: null,
            },
            options: {
              attempts: 3,
              backoff: {
                type: 'exponential',
                delay: 2000,
              },
            },
          })
        } catch (e) {
          console.error('Failed to queue complaint response notification', e)
        }
      }

      /*
      // Old implementation - direct DB query:
      await db
        .update(complaints)
        .set({ isResolved: true, response: input.response })
        .where(eq(complaints.id, parseInt(input.id)));
      */

      return { message: 'Complaint resolved successfully' };
    }),
});
