import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend } from 'k6/metrics';
import { BASE_URL, SLA_THRESHOLDS, authHeaders } from '../lib/config.js';

/**
 * Admin Moderation Queue Load Test — Goodgo Platform
 *
 * Tests admin endpoints: moderation queue listing, approve/reject,
 * bulk moderation, user management, dashboard stats, and audit logs.
 * Requires an admin user account.
 */

const moderationListDuration = new Trend('moderation_list_duration', true);
const moderationActionDuration = new Trend('moderation_action_duration', true);
const adminDashboardDuration = new Trend('admin_dashboard_duration', true);
const auditLogDuration = new Trend('audit_log_duration', true);
const userListDuration = new Trend('user_list_duration', true);
const adminFailRate = new Rate('admin_failures');

export const options = {
  scenarios: {
    admin_load: {
      executor: 'ramping-vus',
      startVUs: 0,
      stages: [
        { duration: '20s', target: 10 },    // admin traffic is lower volume
        { duration: '1m', target: 30 },      // sustain moderate load
        { duration: '1m', target: 50 },      // stress peak
        { duration: '20s', target: 0 },      // ramp down
      ],
      gracefulRampDown: '10s',
    },
  },
  thresholds: {
    ...SLA_THRESHOLDS,
    moderation_list_duration: ['p(95)<500'],
    moderation_action_duration: ['p(95)<800'],
    admin_dashboard_duration: ['p(95)<500'],
    audit_log_duration: ['p(95)<500'],
    user_list_duration: ['p(95)<500'],
    admin_failures: ['rate<0.05'],
  },
};

export function setup() {
  // Register admin user via the standard auth flow.
  // In a real environment the admin role would be pre-seeded;
  // for load testing we attempt registration then login.
  const adminPayload = JSON.stringify({
    phone: '0900000001',
    password: 'AdminLoad@1234!',
    fullName: 'K6 Admin User',
    email: 'k6-admin@goodgo.test',
  });

  let res = http.post(`${BASE_URL}/auth/register`, adminPayload, {
    headers: { 'Content-Type': 'application/json' },
    tags: { name: 'setup_admin_register' },
  });

  // If already exists, login
  if (res.status !== 200 && res.status !== 201) {
    res = http.post(
      `${BASE_URL}/auth/login`,
      JSON.stringify({ phone: '0900000001', password: 'AdminLoad@1234!' }),
      {
        headers: { 'Content-Type': 'application/json' },
        tags: { name: 'setup_admin_login' },
      },
    );
  }

  let accessToken = null;
  if (res.status === 200 || res.status === 201) {
    try {
      accessToken = JSON.parse(res.body).accessToken;
    } catch (_) { /* ignore */ }
  }

  // Also create some test listings for moderation queue
  const listingIds = [];
  if (accessToken) {
    for (let i = 0; i < 20; i++) {
      const listing = {
        title: `K6 Admin Test Listing ${i}`,
        description: `Moderation load test listing #${i}`,
        transactionType: i % 2 === 0 ? 'SALE' : 'RENT',
        propertyType: ['APARTMENT', 'HOUSE', 'LAND'][i % 3],
        address: `${200 + i} Đường Kiểm Duyệt`,
        ward: 'Phường 1',
        district: 'Quận 1',
        city: 'TP. Hồ Chí Minh',
        latitude: 10.7769 + (i * 0.002),
        longitude: 106.7009 + (i * 0.002),
        area: 50 + (i * 5),
        bedrooms: 1 + (i % 4),
        bathrooms: 1 + (i % 3),
        floors: 1 + (i % 3),
        priceVND: 1000000000 + (i * 200000000),
        direction: 'EAST',
      };

      const createRes = http.post(
        `${BASE_URL}/listings`,
        JSON.stringify(listing),
        { headers: authHeaders(accessToken), tags: { name: 'setup_create_listing' } },
      );

      if (createRes.status === 201 || createRes.status === 200) {
        try {
          listingIds.push(JSON.parse(createRes.body).id);
        } catch (_) { /* skip */ }
      }
    }
  }

  return { accessToken, listingIds };
}

export default function (data) {
  if (!data.accessToken) {
    // Without auth, still test unauthenticated error handling
    const res = http.get(`${BASE_URL}/admin/moderation?page=1&limit=10`, {
      tags: { name: 'GET /admin/moderation (unauth)' },
    });
    check(res, {
      'unauth moderation: returns 401': (r) => r.status === 401,
    });
    sleep(1);
    return;
  }

  const headers = authHeaders(data.accessToken);
  const iter = __ITER;
  const scenario = iter % 7;

  if (scenario === 0) {
    // --- Moderation queue listing ---
    const page = 1 + (iter % 3);
    const res = http.get(`${BASE_URL}/admin/moderation?page=${page}&limit=10`, {
      headers,
      tags: { name: 'GET /admin/moderation' },
    });

    moderationListDuration.add(res.timings.duration);
    const ok = check(res, {
      'moderation list: status 200|403': (r) => r.status === 200 || r.status === 403,
    });
    if (!ok) adminFailRate.add(1);

  } else if (scenario === 1 && data.listingIds.length > 0) {
    // --- Approve listing ---
    const listingId = data.listingIds[iter % data.listingIds.length];
    const payload = JSON.stringify({
      listingId,
      moderationNotes: `K6 load test approval — iteration ${iter}`,
    });

    const res = http.post(`${BASE_URL}/admin/moderation/approve`, payload, {
      headers,
      tags: { name: 'POST /admin/moderation/approve' },
    });

    moderationActionDuration.add(res.timings.duration);
    const ok = check(res, {
      'approve: status 200|201|403|404|409': (r) =>
        [200, 201, 403, 404, 409].includes(r.status),
    });
    if (!ok) adminFailRate.add(1);

  } else if (scenario === 2 && data.listingIds.length > 0) {
    // --- Reject listing ---
    const listingId = data.listingIds[(iter + 1) % data.listingIds.length];
    const payload = JSON.stringify({
      listingId,
      reason: `K6 load test rejection — does not meet criteria (iter ${iter})`,
    });

    const res = http.post(`${BASE_URL}/admin/moderation/reject`, payload, {
      headers,
      tags: { name: 'POST /admin/moderation/reject' },
    });

    moderationActionDuration.add(res.timings.duration);
    const ok = check(res, {
      'reject: status 200|201|403|404|409': (r) =>
        [200, 201, 403, 404, 409].includes(r.status),
    });
    if (!ok) adminFailRate.add(1);

  } else if (scenario === 3 && data.listingIds.length >= 3) {
    // --- Bulk moderation ---
    const startIdx = iter % Math.max(1, data.listingIds.length - 3);
    const batchIds = data.listingIds.slice(startIdx, startIdx + 3);
    const payload = JSON.stringify({
      listingIds: batchIds,
      action: iter % 2 === 0 ? 'approve' : 'reject',
      reason: `K6 bulk moderation test — iteration ${iter}`,
    });

    const res = http.post(`${BASE_URL}/admin/moderation/bulk`, payload, {
      headers,
      tags: { name: 'POST /admin/moderation/bulk' },
    });

    moderationActionDuration.add(res.timings.duration);
    const ok = check(res, {
      'bulk moderate: status 200|201|403|409': (r) =>
        [200, 201, 403, 409].includes(r.status),
    });
    if (!ok) adminFailRate.add(1);

  } else if (scenario === 4) {
    // --- Admin dashboard ---
    const res = http.get(`${BASE_URL}/admin/dashboard`, {
      headers,
      tags: { name: 'GET /admin/dashboard' },
    });

    adminDashboardDuration.add(res.timings.duration);
    const ok = check(res, {
      'dashboard: status 200|403': (r) => r.status === 200 || r.status === 403,
    });
    if (!ok) adminFailRate.add(1);

  } else if (scenario === 5) {
    // --- Audit logs with various filters ---
    const filters = [
      '',
      '?action=LISTING_APPROVED',
      '?action=USER_BANNED',
      `?startDate=2026-01-01&endDate=2026-12-31`,
    ];
    const filter = filters[iter % filters.length];

    const res = http.get(`${BASE_URL}/admin/audit-logs${filter}`, {
      headers,
      tags: { name: 'GET /admin/audit-logs' },
    });

    auditLogDuration.add(res.timings.duration);
    const ok = check(res, {
      'audit logs: status 200|403': (r) => r.status === 200 || r.status === 403,
    });
    if (!ok) adminFailRate.add(1);

  } else {
    // --- User management listing ---
    const queries = [
      '?limit=20',
      '?role=AGENT&limit=10',
      '?isActive=true&limit=20',
      '?search=test&limit=10',
    ];
    const query = queries[iter % queries.length];

    const res = http.get(`${BASE_URL}/admin/users${query}`, {
      headers,
      tags: { name: 'GET /admin/users' },
    });

    userListDuration.add(res.timings.duration);
    const ok = check(res, {
      'user list: status 200|403': (r) => r.status === 200 || r.status === 403,
    });
    if (!ok) adminFailRate.add(1);
  }

  sleep(Math.random() * 1.5 + 0.5);
}
