'use strict';

const path = require('node:path');
const fs = require('fs-extra');
const https = require('node:https');

const CODEMAGIC_ENV_REL = path.join('.kasy', 'codemagic.env');
const CODEMAGIC_API = 'https://api.codemagic.io';

const URL_CODEMAGIC_APPS = 'https://codemagic.io/apps';
const URL_CODEMAGIC_API = 'https://codemagic.io/settings/integrations';

function codemagicReleaseDocPath() {
  return 'docs/codemagic-release.md';
}

async function loadCodemagicEnv(projectDir) {
  const envPath = path.join(projectDir, CODEMAGIC_ENV_REL);
  if (!(await fs.pathExists(envPath))) {
    return null;
  }
  const content = await fs.readFile(envPath, 'utf8');
  const env = {};
  for (const line of content.split('\n')) {
    const trimmed = line.trim();
    if (!trimmed || trimmed.startsWith('#')) continue;
    const eq = trimmed.indexOf('=');
    if (eq === -1) continue;
    env[trimmed.slice(0, eq).trim()] = trimmed.slice(eq + 1).trim();
  }
  return env;
}

async function writeCodemagicEnv(projectDir, { token, appId, workflowId, branch }) {
  const lines = [
    '# Generated by kasy codemagic configure — do not commit',
    `CODEMAGIC_API_TOKEN=${token}`,
    `CODEMAGIC_APP_ID=${appId}`,
    `CODEMAGIC_WORKFLOW_ID=${workflowId || 'ios-workflow'}`,
    `CODEMAGIC_BRANCH=${branch || 'main'}`,
    '',
  ];
  await fs.ensureDir(path.join(projectDir, '.kasy'));
  await fs.outputFile(path.join(projectDir, CODEMAGIC_ENV_REL), lines.join('\n'), 'utf8');
}

function httpsJson(method, urlPath, token, body) {
  return new Promise((resolve, reject) => {
    const payload = body ? JSON.stringify(body) : null;
    const req = https.request(
      {
        hostname: 'api.codemagic.io',
        path: urlPath,
        method,
        headers: {
          'Content-Type': 'application/json',
          'x-auth-token': token,
          ...(payload ? { 'Content-Length': Buffer.byteLength(payload) } : {}),
        },
      },
      (res) => {
        let data = '';
        res.on('data', (chunk) => {
          data += chunk;
        });
        res.on('end', () => {
          try {
            const parsed = data ? JSON.parse(data) : {};
            if (res.statusCode >= 400) {
              reject(new Error(parsed.message || parsed.error || `HTTP ${res.statusCode}`));
              return;
            }
            resolve(parsed);
          } catch (err) {
            reject(err);
          }
        });
      }
    );
    req.on('error', reject);
    if (payload) req.write(payload);
    req.end();
  });
}

async function triggerBuild(projectDir, env) {
  const body = {
    appId: env.CODEMAGIC_APP_ID,
    workflowId: env.CODEMAGIC_WORKFLOW_ID,
    branch: env.CODEMAGIC_BRANCH || 'main',
  };
  return httpsJson('POST', '/builds', env.CODEMAGIC_API_TOKEN, body);
}

async function getBuildStatus(buildId, token) {
  return httpsJson('GET', `/builds/${buildId}`, token);
}

async function validateCodemagicSetup(projectDir) {
  const issues = [];
  const yamlPath = path.join(projectDir, 'codemagic.yaml');
  if (!(await fs.pathExists(yamlPath))) {
    issues.push('missing_yaml');
  }
  const env = await loadCodemagicEnv(projectDir);
  if (!env) {
    issues.push('missing_env');
    return { ok: false, issues, env: null };
  }
  if (!env.CODEMAGIC_API_TOKEN) issues.push('missing_token');
  if (!env.CODEMAGIC_APP_ID) issues.push('missing_app_id');
  if (!env.CODEMAGIC_WORKFLOW_ID) issues.push('missing_workflow');
  return { ok: issues.length === 0, issues, env };
}

module.exports = {
  CODEMAGIC_ENV_REL,
  CODEMAGIC_API,
  URL_CODEMAGIC_APPS,
  URL_CODEMAGIC_API,
  codemagicReleaseDocPath,
  loadCodemagicEnv,
  writeCodemagicEnv,
  triggerBuild,
  getBuildStatus,
  validateCodemagicSetup,
};
