import assert from 'node:assert/strict';
import { randomUUID } from 'node:crypto';
import { pool } from './db';
import { call, register } from './smokeSupport';

type PhotoResponse = { photo: { mode: 'blurred' | 'revealed'; accessStatus: string | null } };
const syntheticJpeg = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2Q==';

export const runPhotoSmoke = async (): Promise<void> => {
  const owner = await register('PhotoOwner');
  const viewer = await register('PhotoViewer');
  const requestId = randomUUID();
  await pool.query(
    `INSERT INTO engagement_requests (id,sender_user_id,recipient_user_id,status)
     VALUES ($1,$2,$3,'accepted')`, [requestId, owner.user.id, viewer.user.id],
  );
  await call('/v1/me/profile-photo', 200, owner.token, 'PUT', {
    original: syntheticJpeg, blurred: syntheticJpeg,
  });
  const initial = await call<PhotoResponse>(
    `/v1/profiles/${owner.user.id}/photo`, 200, viewer.token,
  );
  assert.equal(initial.photo.mode, 'blurred');
  await call(`/v1/profiles/${owner.user.id}/photo-request`, 200, viewer.token, 'POST');
  const requests = await call<{ requests: Array<{ viewerUserId: string; status: string }> }>(
    '/v1/me/photo-requests', 200, owner.token,
  );
  assert.equal(requests.requests[0]?.viewerUserId, viewer.user.id);
  assert.equal(requests.requests[0]?.status, 'requested');
  const ownerWorkspace = await call<{
    incomingPhotoRequest: { viewerUserId: string } | null;
    events: Array<{ type: string }>;
  }>(`/v1/requests/${requestId}/workspace`, 200, owner.token);
  assert.equal(ownerWorkspace.incomingPhotoRequest?.viewerUserId, viewer.user.id);
  assert(ownerWorkspace.events.some((item) => item.type === 'photo_requested'));
  await call(`/v1/me/photo-requests/${viewer.user.id}`, 200, owner.token, 'PATCH', {
    decision: 'approved',
  });
  const revealed = await call<PhotoResponse>(
    `/v1/profiles/${owner.user.id}/photo`, 200, viewer.token,
  );
  assert.equal(revealed.photo.mode, 'revealed');
  const decidedWorkspace = await call<{
    incomingPhotoRequest: null; events: Array<{ type: string }>;
  }>(`/v1/requests/${requestId}/workspace`, 200, owner.token);
  assert.equal(decidedWorkspace.incomingPhotoRequest, null);
  assert(decidedWorkspace.events.some((item) => item.type === 'photo_approved'));
  const sharing = await call<{ sharing: { hasPhoto: boolean; status: string | null } }>(
    `/v1/profiles/${viewer.user.id}/my-photo-sharing`, 200, owner.token,
  );
  assert.equal(sharing.sharing.hasPhoto, true);
  assert.equal(sharing.sharing.status, 'revealed');
  await call(`/v1/profiles/${viewer.user.id}/photo-hide`, 200, owner.token, 'POST');
  const hidden = await call<PhotoResponse>(
    `/v1/profiles/${owner.user.id}/photo`, 200, viewer.token,
  );
  assert.equal(hidden.photo.mode, 'blurred');
  assert.equal(hidden.photo.accessStatus, null);
  const hiddenWorkspace = await call<{ events: Array<{ type: string }> }>(
    `/v1/requests/${requestId}/workspace`, 200, owner.token,
  );
  assert(hiddenWorkspace.events.some((item) => item.type === 'photo_hidden'));
};
