import { COOKIE_NAME } from "@shared/const";
import { getSessionCookieOptions } from "./_core/cookies";
import { systemRouter } from "./_core/systemRouter";
import { publicProcedure, router, protectedProcedure } from "./_core/trpc";

export const appRouter = router({
  system: systemRouter,
  auth: router({
    me: publicProcedure.query(opts => opts.ctx.user),
    logout: publicProcedure.mutation(({ ctx }) => {
      const cookieOptions = getSessionCookieOptions(ctx.req);
      ctx.res.clearCookie(COOKIE_NAME, { ...cookieOptions, maxAge: -1 });
      return {
        success: true,
      } as const;
    }),
  }),

  // Admin dashboard and user management
  admin: router({
    // Get dashboard statistics (admin only)
    getDashboardStats: protectedProcedure.query(async ({ ctx }) => {
      if (ctx.user?.role !== 'admin') {
        throw new Error('Unauthorized: Admin access required');
      }
      const { getDashboardStats } = await import('./db');
      return getDashboardStats();
    }),

    // List all Xtream users (admin only)
    listXtreamUsers: protectedProcedure.query(async ({ ctx }) => {
      if (ctx.user?.role !== 'admin') {
        throw new Error('Unauthorized: Admin access required');
      }
      const { listXtreamUsers } = await import('./db');
      return listXtreamUsers({ showExpired: true });
    }),

    // Create new Xtream user (admin only)
    createXtreamUser: protectedProcedure
      .input((data: any) => ({
        username: String(data.username),
        password: String(data.password),
        expirationDate: data.expirationDate ? new Date(data.expirationDate) : undefined,
        maxConnections: Number(data.maxConnections) || 1,
      }))
      .mutation(async ({ ctx, input }) => {
        if (ctx.user?.role !== 'admin') {
          throw new Error('Unauthorized: Admin access required');
        }
        const { createXtreamUser, getXtreamUserByUsername } = await import('./db');
        
        const existing = await getXtreamUserByUsername(input.username);
        if (existing) {
          throw new Error('Username already exists');
        }
        
        return createXtreamUser(input);
      }),

    // Update Xtream user (admin only)
    updateXtreamUser: protectedProcedure
      .input((data: any) => ({
        id: Number(data.id),
        username: data.username ? String(data.username) : undefined,
        password: data.password ? String(data.password) : undefined,
        expirationDate: data.expirationDate ? new Date(data.expirationDate) : undefined,
        maxConnections: data.maxConnections ? Number(data.maxConnections) : undefined,
        isActive: data.isActive !== undefined ? Boolean(data.isActive) : undefined,
      }))
      .mutation(async ({ ctx, input }) => {
        if (ctx.user?.role !== 'admin') {
          throw new Error('Unauthorized: Admin access required');
        }
        const { updateXtreamUser } = await import('./db');
        return updateXtreamUser(input.id, input);
      }),

    // Delete Xtream user (admin only)
    deleteXtreamUser: protectedProcedure
      .input((data: any) => Number(data.id))
      .mutation(async ({ ctx, input }) => {
        if (ctx.user?.role !== 'admin') {
          throw new Error('Unauthorized: Admin access required');
        }
        const { deleteXtreamUser } = await import('./db');
        return deleteXtreamUser(input);
      }),
  }),

  // Client-side music streaming API
  music: router({
    // Get all categories
    getCategories: publicProcedure.query(async () => {
      const { listStreamCategories } = await import('./db');
      return listStreamCategories();
    }),

    // Get tracks by category
    getTracksByCategory: publicProcedure
      .input((data: any) => Number(data.categoryId))
      .query(async ({ input }) => {
        const { listMusicTracksByCategory } = await import('./db');
        return listMusicTracksByCategory(input);
      }),

    // Get track details
    getTrack: publicProcedure
      .input((data: any) => Number(data.id))
      .query(async ({ input }) => {
        const { getMusicTrackById } = await import('./db');
        return getMusicTrackById(input);
      }),
  }),
});

export type AppRouter = typeof appRouter;
