import { z } from "zod";
import type { BannersIdbanner } from "~/schemas/public/Banners";
import {
  adminProcedure,
  createTRPCRouter,
  publicProcedure,
} from "~/server/api/trpc";
import {
  addBanner,
  deleteBanner,
  getAllBanners,
  getBanner,
  updateBanner,
} from "~/server/services/banners.service";
import {
  addEtichetta,
  getAllEtichette,
  removeEtichetta,
  updateEtichetta,
} from "~/server/controllers/etichette.controller";

import {
  EditFlagHandler,
  GetFlagValueHandler,
  GetFlagHandler,
  AddFlagHandler,
  RemoveFlagHandler,
} from "~/server/controllers/flags.controller";
import { db } from "~/server/db";
import {
  deleteStringa,
  getStringa,
  getStringhe,
  getStringheFiltered,
  newStringa,
  updateStringhe,
} from "~/server/services/testi_stringhe.service";
import {
  zEtichettaId,
  zFlagsId,
  zTestiEStringheStingaId,
} from "~/server/utils/zod_types";

export const settingsRouter = createTRPCRouter({
  // Flags routes
  GetFlags: adminProcedure.query(async () => {
    return await GetFlagHandler({ db });
  }),
  AddFlag: adminProcedure
    .input(
      z.object({
        id: zFlagsId,
        value: z.string(),
      }),
    )
    .mutation(async ({ input }) => {
      return await AddFlagHandler({ db, input });
    }),
  RemoveFlag: adminProcedure

    .input(
      z.object({
        id: zFlagsId,
      }),
    )
    .mutation(async ({ input }) => {
      return await RemoveFlagHandler({ db, id: input.id });
    }),

  EditFlag: adminProcedure
    .input(
      z.object({
        id: zFlagsId,
        value: z.string(),
      }),
    )
    .mutation(async ({ input }) => {
      return await EditFlagHandler({ db, input });
    }),

  GetFlagValue: publicProcedure
    .input(z.object({ id: z.string() }))
    .query(async ({ input }) => {
      return await GetFlagValueHandler({ db, id: input.id });
    }),
  // Banner routes
  getBannerData: publicProcedure
    .input(
      z.object({
        area_riservata: z.boolean(),
      }),
    )
    .query(async ({ input }) => {
      return await getBanner({
        db,
        area_riservata: input.area_riservata,
      });
    }),
  getBannerAllData: publicProcedure.query(async () => {
    return await getAllBanners({ db });
  }),
  addBanner: adminProcedure
    .input(
      z.object({
        idbanner: z.custom<BannersIdbanner>(),
        titolo: z.string().nullable(),
        testo: z.string().nullable(),
        is_unskippable: z.boolean(),
        has_cta: z.boolean(),
        cta_href: z.string().nullable(),
        cta_icon: z.string().nullable(),
        cta_text: z.string().nullable(),
        color: z.string().nullable(),
        is_active: z.boolean(),
        show_public: z.boolean(),
        show_private: z.boolean(),
        hide_duration: z.number().nullable(),
      }),
    )
    .mutation(async ({ input }) => {
      return await addBanner({ db, input });
    }),
  updateBanner: adminProcedure
    .input(
      z.object({
        idbanner: z.custom<BannersIdbanner>(),
        titolo: z.string().nullable(),
        testo: z.string().nullable(),
        is_unskippable: z.boolean(),
        has_cta: z.boolean(),
        cta_href: z.string().nullable(),
        cta_icon: z.string().nullable(),
        cta_text: z.string().nullable(),
        color: z.string().nullable(),
        is_active: z.boolean(),
        show_public: z.boolean(),
        show_private: z.boolean(),
        hide_duration: z.number().nullable(),
      }),
    )
    .mutation(async ({ input }) => {
      return await updateBanner({ db, input });
    }),
  deleteBanner: adminProcedure
    .input(z.object({ idbanner: z.custom<BannersIdbanner>() }))
    .mutation(async ({ input }) => {
      return await deleteBanner({ db, input });
    }),

  // Etichette routes
  getAllEtichette: adminProcedure.query(async () => {
    return await getAllEtichette({ db });
  }),
  addEtichetta: adminProcedure
    .input(
      z.object({
        title: z.string(),
        color_hex: z.string().max(7),
      }),
    )
    .mutation(async ({ input }) => {
      return await addEtichetta({
        db,
        title: input.title,
        color_hex: input.color_hex,
      });
    }),
  updateEtichetta: adminProcedure
    .input(
      z.object({
        id_etichetta: zEtichettaId,
        title: z.string(),
        color_hex: z.string().max(7),
      }),
    )
    .mutation(async ({ input }) => {
      return await updateEtichetta({
        db,
        etichettaid: input.id_etichetta,
        title: input.title,
        color_hex: input.color_hex,
      });
    }),
  removeEtichetta: adminProcedure
    .input(z.object({ id_etichetta: zEtichettaId }))
    .mutation(async ({ input }) => {
      return await removeEtichetta({
        db,
        etichettaid: input.id_etichetta,
      });
    }),

  // Testi e stringhe routes
  getStringhe: adminProcedure.query(async () => {
    return await getStringhe({ db });
  }),
  getStringa: publicProcedure
    .input(
      z.object({
        stringaId: zTestiEStringheStingaId,
      }),
    )
    .query(async ({ input }) => {
      return await getStringa({
        db,
        stringaId: input.stringaId,
      });
    }),
  newStringa: adminProcedure
    .input(
      z.object({
        stringaId: zTestiEStringheStingaId,
        stringaValue: z.string().nullable(),
      }),
    )
    .mutation(async ({ input }) => {
      return await newStringa({
        db,
        stringaId: input.stringaId,
        stringaValue: input.stringaValue,
      });
    }),
  updateStringa: adminProcedure
    .input(
      z.object({
        stringaId: zTestiEStringheStingaId,
        stringaValue: z.string().nullable(),
      }),
    )
    .mutation(async ({ input }) => {
      return await updateStringhe({
        db,
        stringaId: input.stringaId,
        stringaValue: input.stringaValue,
      });
    }),
  deleteStringa: adminProcedure
    .input(
      z.object({
        stringaId: zTestiEStringheStingaId,
      }),
    )
    .mutation(async ({ input }) => {
      return await deleteStringa({
        db,
        stringaId: input.stringaId,
      });
    }),
  getStringheCondizioni: adminProcedure.query(async () => {
    return await getStringheFiltered({ db, contains: "CONDIZIONI" });
  }),
});
