<%
const { utils, route, config } = it;
const { requestBodyInfo, responseBodyInfo, specificArgNameResolver } = route;
const { _, getInlineParseContent, getParseContent, parseSchema, getComponentByRef, require } = utils;
const { parameters, path, method, payload, query, formData, security, requestParams } = route.request;
const { type, errorType, contentTypes } = route.response;
const { HTTP_CLIENT, RESERVED_REQ_PARAMS_ARG_NAMES } = config.constants;
const routeDocs = includeFile("./route-docs", { config, route, utils });
const queryName = (query && query.name) || "query";
const pathParams = _.values(parameters);
const pathParamsNames = _.map(pathParams, "name");

const isFetchTemplate = config.httpClientType === HTTP_CLIENT.FETCH;

const requestConfigParam = {
    name: specificArgNameResolver.resolve(RESERVED_REQ_PARAMS_ARG_NAMES),
    optional: true,
    type: "RequestParams",
    defaultValue: "{}",
}

const argToTmpl = ({ name, optional, type, defaultValue }) => `${name}${!defaultValue && optional ? '?' : ''}: ${type}${defaultValue ? ` = ${defaultValue}` : ''}`;

const rawWrapperArgs = config.extractRequestParams ?
    _.compact([
        requestParams && {
          name: pathParams.length ? `{ ${_.join(pathParamsNames, ", ")}, ...${queryName} }` : queryName,
          optional: false,
          type: getInlineParseContent(requestParams),
        },
        ...(!requestParams ? pathParams : []),
        payload,
        requestConfigParam,
    ]) :
    _.compact([
        ...pathParams,
        query,
        payload,
        requestConfigParam,
    ])

const wrapperArgs = _
    // Sort by optionality
    .sortBy(rawWrapperArgs, [o => o.optional])
    .map(argToTmpl)
    .join(', ')

// RequestParams["type"]
const requestContentKind = {
    "JSON": "ContentType.Json",
    "JSON_API": "ContentType.JsonApi",
    "URL_ENCODED": "ContentType.UrlEncoded",
    "FORM_DATA": "ContentType.FormData",
    "TEXT": "ContentType.Text",
}
// RequestParams["format"]
const responseContentKind = {
    "JSON": '"json"',
    "IMAGE": '"blob"',
    "FORM_DATA": isFetchTemplate ? '"formData"' : '"document"'
}

const bodyTmpl = _.get(payload, "name") || null;
const queryTmpl = (query != null && queryName) || null;
const bodyContentKindTmpl = requestContentKind[requestBodyInfo.contentKind] || null;
const responseFormatTmpl = responseContentKind[responseBodyInfo.success && responseBodyInfo.success.schema && responseBodyInfo.success.schema.contentKind] || null;
const securityTmpl = security ? 'true' : null;

const describeReturnType = () => {
    if (!config.toJS) return "";

    switch(config.httpClientType) {
        case HTTP_CLIENT.AXIOS: {
          return `Promise<AxiosResponse<${type}>>`
        }
        default: {
          return `Promise<HttpResponse<${type}, ${errorType}>`
        }
    }
}

const isValidIdentifier = (name) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name);

%>
/**
<%~ routeDocs.description %>

 *<% /* Here you can add some other JSDoc tags */ %>

<%~ routeDocs.lines %>

 */
<% if (isValidIdentifier(route.routeName.usage)) { %><%~ route.routeName.usage %><%~ route.namespace ? ': ' : ' = ' %><% } else { %>"<%~ route.routeName.usage %>"<%~ route.namespace ? ': ' : ' = ' %><% } %>(<%~ wrapperArgs %>)<%~ config.toJS ? `: ${describeReturnType()}` : "" %> =>
    <%~ config.singleHttpClient ? 'this.http.request' : 'this.request' %><<%~ type %>, <%~ errorType %>>({
        path: `<%~ path %>`,
        method: '<%~ _.upperCase(method) %>',
        <%~ queryTmpl ? `query: ${queryTmpl},` : '' %>
        <%~ bodyTmpl ? `body: ${bodyTmpl},` : '' %>
        <%~ securityTmpl ? `secure: ${securityTmpl},` : '' %>
        <%~ bodyContentKindTmpl ? `type: ${bodyContentKindTmpl},` : '' %>
        <%~ responseFormatTmpl ? `format: ${responseFormatTmpl},` : '' %>
        ...<%~ _.get(requestConfigParam, "name") %>,
    })<%~ route.namespace ? ',' : '' %>
<%
// Генерируем use* функцию для GET запросов (только если включен флаг useSwr)
const isGetRequest = _.upperCase(method) === 'GET';
if (config.useSwr && isGetRequest) {
    const useMethodName = 'use' + _.upperFirst(route.routeName.usage);
    const argsWithoutParams = rawWrapperArgs.filter(arg => arg.name !== requestConfigParam.name);
    const useWrapperArgs = _
        .sortBy(argsWithoutParams, [o => o.optional])
        .map(argToTmpl)
        .join(', ');
    
    // Определяем обязательные параметры для проверки
    const requiredArgs = argsWithoutParams.filter(arg => !arg.optional);
    const requiredArgsNames = requiredArgs.map(arg => {
        // Извлекаем имя из деструктуризации типа "{ id, ...query }"
        const match = arg.name.match(/^\{\s*([^,}]+)/);
        return match ? match[1].trim() : arg.name;
    });
    
    // Генерируем условие для проверки всех обязательных параметров
    const hasRequiredArgs = requiredArgsNames.length > 0;
    const conditionCheck = hasRequiredArgs 
        ? requiredArgsNames.join(' && ')
        : 'true';
%>

/**
 * SWR hook для <%~ route.routeName.usage %>
 <%~ routeDocs.lines %>
 */
<% if (isValidIdentifier(useMethodName)) { %><%~ useMethodName %><%~ route.namespace ? ': ' : ' = ' %><% } else { %>"<%~ useMethodName %>"<%~ route.namespace ? ': ' : ' = ' %><% } %>(<%~ useWrapperArgs %>) => {
    return useSWR<<%~ type %>>(
        <%~ conditionCheck %> ? `<%~ path %>` : null,
        fetcher
    );
}<%~ route.namespace ? ',' : '' %>
<% } %>
