import { z } from "zod";

import type {
    CreateContractRouteDetails,
    InferContract,
    InferContractParams,
    InferContractRequest,
    InferContractResponse,
} from "@devowl-wp/api";
import { ContractResponse, EHttpStatusCodeSuccess, ERouteHttpVerb, createContract } from "@devowl-wp/api";

import { createUntranslatableSchema } from "../../entity/template/untranslatable.js";
import { createContractGuardJwt } from "../../guard/jwt.js";

const createContractUntranslatableDeleteGroup = (): CreateContractRouteDetails["groups"] => [
    {
        name: "Untranslatable",
        description:
            "Untranslatables are words or text phrases that should not be translated. For example, the word 'Cookie' or brand names like 'Everest Forms' should not be translated. This is especially useful on machine translations. You can associate untranslatables with specific service templates or content blockers.",
    },
];

const createContractUntranslatableGet = () =>
    createContract({
        z,
        versions: ["1.0.0"],
        route: {
            path: "/template/untranslatable",
            method: ERouteHttpVerb.GET,
        },
        routeDetails: {
            shortDescription: "Get all untranslatable strings",
            longDescription: "Get all untranslatable strings",
            groups: createContractUntranslatableDeleteGroup(),
        },
        guards: () => ({
            jwt: createContractGuardJwt(),
        }),
        params: (context) =>
            z
                .object({
                    templateType: z.string().optional(),
                    templateIdentifier: z.string().optional().meta({
                        description: "The template identifier (unique identifier) to get untranslatables for.",
                        example: "activecampaign",
                    }),
                })
                .meta({
                    description:
                        "The template type and identifier to get untranslatables for. They need to be provided together or not at all.",
                })
                .refine(
                    (data) => {
                        // Both must be provided together or neither
                        const hasTemplateType = !!data.templateType;
                        const hasTemplateIdentifier = !!data.templateIdentifier;
                        return (
                            (hasTemplateType && hasTemplateIdentifier) || (!hasTemplateType && !hasTemplateIdentifier)
                        );
                    },
                    {
                        error: () =>
                            context.getStore().t("Both templateType and templateIdentifier must be provided together"),
                        path: ["templateType"],
                    },
                ),
        response: (context) => ({
            [EHttpStatusCodeSuccess.OK]: ContractResponse.fromSchema({
                schema: z.object({
                    untranslatables: createUntranslatableSchema(context).meta({ id: "Untranslatable" }).array(),
                }),
            }),
        }),
    });

type UntranslatableGetContract = InferContract<typeof createContractUntranslatableGet>;

interface IUntranslatableGetContractRequest extends InferContractRequest<typeof createContractUntranslatableGet> {}
interface IUntranslatableGetContractParams extends InferContractParams<typeof createContractUntranslatableGet> {}
interface IUntranslatableGetContractResponse extends InferContractResponse<typeof createContractUntranslatableGet> {}

export {
    type IUntranslatableGetContractParams,
    type IUntranslatableGetContractRequest,
    type IUntranslatableGetContractResponse,
    type UntranslatableGetContract,
    createContractUntranslatableGet,
};
