import { z } from 'zod';
import { protectedProcedure, router } from '@/src/trpc/trpc-index'
import { extractKeyFromPresignedUrl, scaffoldAssetUrl } from '@/src/lib/s3-client'
import { ApiError } from '@/src/lib/api-error';
import { scheduleStoreInitialization } from '@/src/stores/store-initializer'
import {
  getBanners as getBannersFromDb,
  getBannerById as getBannerByIdFromDb,
  createBanner as createBannerInDb,
  updateBanner as updateBannerInDb,
  deleteBanner as deleteBannerFromDb,
} from '@/src/dbService'
import type { Banner } from '@packages/shared'


export const bannerRouter = router({
  // Get all banners
  getBanners: protectedProcedure
    .query(async (): Promise<{ banners: Banner[] }> => {
      try {

      // Using dbService helper (new implementation)
      const banners = await getBannersFromDb();

      
      // Old implementation - direct DB query:
      // const banners = await db.query.homeBanners.findMany({
      //  orderBy: desc(homeBanners.createdAt), // Order by creation date instead
        // Removed product relationship since we now use productIds array
      // });
      

      // Convert S3 keys to signed URLs for client
      const bannersWithSignedUrls = await Promise.all(
        banners.map(async (banner) => {
          try {
            return {
              ...banner,
              imageUrl: banner.imageUrl ? scaffoldAssetUrl(banner.imageUrl) : banner.imageUrl,
              // Ensure productIds is always an array
              productIds: banner.productIds || [],
            };
          } catch (error) {
            console.error(`Failed to generate signed URL for banner ${banner.id}:`, error);
            return {
              ...banner,
              imageUrl: banner.imageUrl, // Keep original on error
              // Ensure productIds is always an array
              productIds: banner.productIds || [],
            };
          }
        })
      );

      return {
        banners: bannersWithSignedUrls,
      };
      }
      catch(e:any) {
        console.log(e)
        
        throw new ApiError(e.message);
      }
    }),

  // Get single banner by ID
  getBanner: protectedProcedure
    .input(z.object({ id: z.number() }))
    .query(async ({ input }): Promise<Banner | null> => {
      // Using dbService helper (new implementation)
      const banner = await getBannerByIdFromDb(input.id);
      
      /*
      // Old implementation - direct DB query:
      const banner = await db.query.homeBanners.findFirst({
        where: eq(homeBanners.id, input.id),
        // Removed product relationship since we now use productIds array
      });
      */

      if (banner) {
        try {
          // Convert S3 key to signed URL for client
          if (banner.imageUrl) {
            banner.imageUrl = scaffoldAssetUrl(banner.imageUrl);
          }
        } catch (error) {
          console.error(`Failed to generate signed URL for banner ${banner.id}:`, error);
          // Keep original imageUrl on error
        }

        // Ensure productIds is always an array (handle migration compatibility)
        if (!banner.productIds) {
          banner.productIds = [];
        }
      }

      return banner;
    }),

  // Create new banner
  createBanner: protectedProcedure
    .input(z.object({
      name: z.string().min(1),
      imageUrl: z.string().url(),
      description: z.string().optional(),
      productIds: z.array(z.number()).optional(),
      redirectUrl: z.string().url().optional(),
      // serialNum removed completely
    }))
    .mutation(async ({ input }): Promise<Banner> => {
      try {
        // Using dbService helper (new implementation)
        const imageUrl = extractKeyFromPresignedUrl(input.imageUrl)
        const banner = await createBannerInDb({
          name: input.name,
          imageUrl: imageUrl,
          description: input.description ?? null,
          productIds: input.productIds || [],
          redirectUrl: input.redirectUrl ?? null,
          serialNum: 999, // Default value, not used
          isActive: false, // Default to inactive
        });

        /*
        // Old implementation - direct DB query:
        const imageUrl = extractKeyFromPresignedUrl(input.imageUrl)
        const [banner] = await db.insert(homeBanners).values({
          name: input.name,
          imageUrl: imageUrl,
          description: input.description,
          productIds: input.productIds || [],
          redirectUrl: input.redirectUrl,
          serialNum: 999, // Default value, not used
          isActive: false, // Default to inactive
        }).returning();
        */

        // Reinitialize stores to reflect changes
        await scheduleStoreInitialization()

        return banner;
      } catch (error) {
        console.error('Error creating banner:', error);
        throw error; // Re-throw to maintain tRPC error handling
      }
    }),

  // Update banner
  updateBanner: protectedProcedure
    .input(z.object({
      id: z.number(),
      name: z.string().min(1).optional(),
      imageUrl: z.string().url().optional(),
      description: z.string().optional(),
      productIds: z.array(z.number()).optional(),
      redirectUrl: z.string().url().optional(),
      serialNum: z.number().nullable().optional(),
      isActive: z.boolean().optional(),
    }))
    .mutation(async ({ input }): Promise<Banner> => {
      try {
        // Using dbService helper (new implementation)
        const { id, ...updateData } = input;

        // Extract S3 key from presigned URL if imageUrl is provided
        const processedData = {
          ...updateData,
          ...(updateData.imageUrl && {
            imageUrl: extractKeyFromPresignedUrl(updateData.imageUrl)
          }),
        };

        // Handle serialNum null case
        if ('serialNum' in processedData && processedData.serialNum === null) {
          processedData.serialNum = null;
        }

        const banner = await updateBannerInDb(id, processedData);

        /*
        // Old implementation - direct DB query:
        const { id, ...updateData } = input;
        const incomingProductIds = input.productIds;
        // Extract S3 key from presigned URL if imageUrl is provided
        const processedData = {
          ...updateData,
          ...(updateData.imageUrl && {
            imageUrl: extractKeyFromPresignedUrl(updateData.imageUrl)
          }),
        };

        // Handle serialNum null case
        const finalData: any = { ...processedData };
        if ('serialNum' in finalData && finalData.serialNum === null) {
          // Set to null explicitly
          finalData.serialNum = null;
        }

        const [banner] = await db.update(homeBanners)
          .set({ ...finalData, lastUpdated: new Date(), })
          .where(eq(homeBanners.id, id))
          .returning();
        */

        // Reinitialize stores to reflect changes
        await scheduleStoreInitialization()

        return banner;
      } catch (error) {
        console.error('Error updating banner:', error);
        throw error;
      }
    }),

  // Delete banner
  deleteBanner: protectedProcedure
    .input(z.object({ id: z.number() }))
    .mutation(async ({ input }): Promise<{ success: true }> => {
      // Using dbService helper (new implementation)
      await deleteBannerFromDb(input.id);

      /*
      // Old implementation - direct DB query:
      await db.delete(homeBanners).where(eq(homeBanners.id, input.id));
      */

      // Reinitialize stores to reflect changes
      await scheduleStoreInitialization()

      return { success: true };
    }),
});
