import { GithubWebhookMensagens, messages } from '../../../core/messages/index.js';
import { statsStore } from '../dashboard/stats-store.js';
import { executarAnalisePullRequest } from '../push-analysis/pr-analysis-service.js';
import { executarAnalisePush } from '../push-analysis/push-analysis-service.js';
import { processarCheckSuite } from './check-suite-handler.js';
import { salvarConfigInstalacao } from './installation-store.js';
import { processarIssues } from './issues-handler.js';
import { HTTP_BAD_REQUEST, HTTP_OK, repoBase } from './octokit.js';
import { processarPullRequestReview } from './pr-review-handler.js';
export { analisarWorkflows, buscarWorkflows } from './workflow-reader.js';
export async function processarPullRequest(app, payload) {
    const { repository, pull_request, installation, action } = payload;
    if (!['opened', 'synchronize', 'reopened'].includes(action))
        return;
    if (!installation?.id)
        return;
    const owner = repository.owner.login;
    const repo = repository.name;
    try {
        await executarAnalisePullRequest(app, {
            installationId: installation.id,
            owner,
            repo,
            prNumber: pull_request.number,
            headSha: pull_request.head.sha,
            headRef: pull_request.head.ref,
            baseSha: pull_request.base.sha,
            baseRef: pull_request.base.ref,
            prTitle: pull_request.title
        });
    }
    catch (err) {
        const error = err;
        const octokit = await app.getInstallationOctokit(installation.id);
        await octokit.request('POST /repos/{owner}/{repo}/issues/{issue_number}/comments', {
            owner,
            repo,
            issue_number: pull_request.number,
            body: `## Tutanus — erro no diagnóstico\n\nNão foi possível concluir a análise: \`${error.message}\``
        }).catch(() => { });
        messages.log.erro(GithubWebhookMensagens.erroAnalisePR(owner, repo, pull_request.number, error.message));
    }
}
export async function processarPush(app, payload) {
    const { repository, head_commit, ref, installation, before, after } = payload;
    if (!installation?.id)
        return;
    if (!ref.startsWith('refs/heads/'))
        return;
    const owner = repository.owner.login;
    const repo = repository.name;
    const branch = ref.replace('refs/heads/', '');
    const headSha = after || head_commit.id;
    if (!headSha)
        return;
    try {
        await executarAnalisePush(app, {
            installationId: installation.id,
            owner,
            repo,
            branch,
            headSha,
            beforeSha: before,
            commitMessage: head_commit.message || 'push'
        });
    }
    catch (err) {
        const error = err;
        messages.log.erro(GithubWebhookMensagens.erroProcessarPush(repository.full_name, branch, error.message));
    }
}
function extractRepo(payload) {
    return (payload.repository?.full_name ||
        (payload.repository?.owner?.login
            ? `${payload.repository.owner.login}/${payload.repository.name}`
            : 'desconhecido'));
}
function extractInstallation(payload) {
    return payload.installation?.id ?? 0;
}
export function createWebhookHandler(app) {
    app.webhooks.on('check_suite.requested', async ({ payload }) => {
        await processarCheckSuite(app, {
            repository: repoBase(payload.repository),
            check_suite: { head_sha: payload.check_suite.head_sha },
            installation: { id: payload.installation?.id ?? 0 }
        });
    });
    app.webhooks.on('check_suite.rerequested', async ({ payload }) => {
        await processarCheckSuite(app, {
            repository: repoBase(payload.repository),
            check_suite: { head_sha: payload.check_suite.head_sha },
            installation: { id: payload.installation?.id ?? 0 }
        });
    });
    app.webhooks.on('pull_request.opened', async ({ payload }) => {
        await processarPullRequest(app, {
            repository: repoBase(payload.repository),
            pull_request: {
                head: payload.pull_request.head,
                base: payload.pull_request.base,
                number: payload.pull_request.number,
                title: payload.pull_request.title
            },
            installation: { id: payload.installation?.id ?? 0 },
            action: payload.action
        });
    });
    app.webhooks.on('pull_request.synchronize', async ({ payload }) => {
        await processarPullRequest(app, {
            repository: repoBase(payload.repository),
            pull_request: {
                head: payload.pull_request.head,
                base: payload.pull_request.base,
                number: payload.pull_request.number,
                title: payload.pull_request.title
            },
            installation: { id: payload.installation?.id ?? 0 },
            action: payload.action
        });
    });
    app.webhooks.on('pull_request.reopened', async ({ payload }) => {
        await processarPullRequest(app, {
            repository: repoBase(payload.repository),
            pull_request: {
                head: payload.pull_request.head,
                base: payload.pull_request.base,
                number: payload.pull_request.number,
                title: payload.pull_request.title
            },
            installation: { id: payload.installation?.id ?? 0 },
            action: payload.action
        });
    });
    app.webhooks.on('push', async ({ payload }) => {
        if (!payload.repository.owner)
            return;
        await processarPush(app, {
            repository: {
                ...repoBase(payload.repository),
                full_name: payload.repository.full_name
            },
            head_commit: {
                id: payload.head_commit?.id ?? '',
                message: payload.head_commit?.message ?? ''
            },
            ref: payload.ref,
            before: payload.before,
            after: payload.after,
            installation: { id: payload.installation?.id ?? 0 }
        });
    });
    app.webhooks.on('installation', async ({ payload }) => {
        const installation = payload.installation;
        if (!installation?.id)
            return;
        if (payload.action === 'created' || payload.action === 'new_permissions_accepted') {
            const account = installation.account;
            salvarConfigInstalacao({
                installationId: installation.id,
                accountLogin: account && 'login' in account ? String(account.login) : undefined,
                targetType: installation.target_type,
                repositorySelection: installation.repository_selection,
                pushAnalysisEnabled: true,
                pullRequestAnalysisEnabled: true,
                fast: false,
                incrementalOnPush: true
            });
        }
    });
    app.webhooks.on('installation_repositories', async ({ payload }) => {
        const installation = payload.installation;
        if (!installation?.id)
            return;
        if (payload.action === 'added' || payload.action === 'removed') {
            salvarConfigInstalacao({
                installationId: installation.id,
                repositorySelection: installation.repository_selection
            });
        }
    });
    app.webhooks.on('pull_request_review.submitted', async ({ payload }) => {
        await processarPullRequestReview(app, {
            repository: repoBase(payload.repository),
            pull_request: {
                head: { sha: payload.pull_request.head.sha },
                number: payload.pull_request.number
            },
            review: {
                state: payload.review.state,
                body: payload.review.body
            },
            installation: { id: payload.installation?.id ?? 0 },
            action: payload.action
        });
    });
    app.webhooks.on('issues.opened', async ({ payload }) => {
        await processarIssues(app, {
            repository: repoBase(payload.repository),
            issue: { number: payload.issue.number, body: payload.issue.body },
            installation: { id: payload.installation?.id ?? 0 },
            action: payload.action
        });
    });
    app.webhooks.onError(error => {
        messages.log.erro(`${GithubWebhookMensagens.erroWebhook}: ${error instanceof Error ? error.message : String(error)}`);
    });
    return async (req, res) => {
        const startTime = Date.now();
        const eventName = req.headers['x-github-event'];
        const deliveryId = req.headers['x-github-delivery'];
        const payload = req.rawBody?.toString() ?? JSON.stringify(req.body);
        let parsedBody = {};
        try {
            parsedBody = typeof req.body === 'object' ? req.body : JSON.parse(payload);
        }
        catch { }
        const repoName = extractRepo(parsedBody);
        const installationId = extractInstallation(parsedBody);
        try {
            await app.webhooks.verifyAndReceive({
                id: deliveryId,
                name: eventName,
                payload,
                signature: req.headers['x-hub-signature-256']
            });
            statsStore.recordEvent({
                id: deliveryId,
                event: eventName,
                action: parsedBody.action,
                repository: repoName,
                installation: installationId,
                status: 'success',
                durationMs: Date.now() - startTime
            });
            res.status(HTTP_OK).send('OK');
        }
        catch (err) {
            const error = err;
            statsStore.recordEvent({
                id: deliveryId,
                event: eventName,
                action: parsedBody.action,
                repository: repoName,
                installation: installationId,
                status: 'error',
                error: error.message,
                durationMs: Date.now() - startTime
            });
            messages.log.erro(GithubWebhookMensagens.erroProcessandoWebhookMsg(error.message));
            res.status(HTTP_BAD_REQUEST).send(GithubWebhookMensagens.erroProcessandoWebhookMsg(error.message));
        }
    };
}
//# sourceMappingURL=webhook-handler.js.map