import assert from 'node:assert/strict';
import test from 'node:test';

import {
  completePendingBirdTransfersForOwner,
  createBird,
  createPendingBirdTransfer,
  getBirdById,
  listWeightsForBird,
  transferBirdToWorkspace,
} from './birdRepository.js';
import { mockDb } from '../test/mockDb.js';

test('getBirdById returns null when the bird does not exist in the workspace', async () => {
  const { calls } = mockDb({ rowCount: 0, rows: [] });

  const bird = await getBirdById('bird-1', 10);

  assert.equal(bird, null);
  assert.equal(calls.length, 1);
  assert.deepEqual(calls[0].params, ['bird-1', 10]);
});

test('createBird returns the inserted bird row', async () => {
  mockDb({
    rowCount: 1,
    rows: [
      {
        id: 'bird-1',
        workspace_id: 10,
        name: 'Kiwi',
        tag_id: 'A-1',
        species: 'Cockatiel',
        motivators: 'Step-up practice',
        demotivators: 'Vacuum noise',
        favorite_snack: 'Millet',
        gender: 'female',
        date_of_birth: null,
        gotcha_day: null,
        chart_color: '#cb3a35',
        photo_data_url: null,
        notify_on_dob: false,
        notify_on_gotcha_day: false,
        created_at: '2026-04-14T00:00:00.000Z',
        latest_weight_grams: null,
        latest_recorded_on: null,
      },
    ],
  });

  const bird = await createBird({
    workspaceId: 10,
    name: 'Kiwi',
    tagId: 'A-1',
    species: 'Cockatiel',
    motivators: 'Step-up practice',
    demotivators: 'Vacuum noise',
    favoriteSnack: 'Millet',
    gender: 'female',
    dateOfBirth: null,
    gotchaDay: null,
    chartColor: '#cb3a35',
    photoDataUrl: null,
    notifyOnDob: false,
    notifyOnGotchaDay: false,
  });

  assert.equal(bird?.name, 'Kiwi');
  assert.equal(bird?.workspace_id, 10);
  assert.equal(bird?.gender, 'female');
  assert.equal(bird?.favorite_snack, 'Millet');
});

test('listWeightsForBird scopes by bird, workspace, and day window', async () => {
  const { calls } = mockDb({
    rowCount: 0,
    rows: [],
  });

  const weights = await listWeightsForBird('bird-1', 10, 30);

  assert.deepEqual(weights, []);
  assert.equal(calls.length, 1);
  assert.deepEqual(calls[0].params, ['bird-1', 30, 10]);
  assert.match(calls[0].text, /FROM weight_records/);
});

test('transferBirdToWorkspace moves the bird to the target workspace', async () => {
  const { calls } = mockDb({
    rowCount: 1,
    rows: [
      {
        id: 'bird-1',
        workspace_id: 22,
        name: 'Kiwi',
        tag_id: 'A-1',
        species: 'Cockatiel',
        gender: 'female',
        date_of_birth: null,
        gotcha_day: null,
        chart_color: '#cb3a35',
        photo_data_url: null,
        notify_on_dob: false,
        notify_on_gotcha_day: false,
        created_at: '2026-04-14T00:00:00.000Z',
        latest_weight_grams: '92',
        latest_recorded_on: '2026-04-14',
      },
    ],
  });

  const bird = await transferBirdToWorkspace('bird-1', 10, 22);

  assert.equal(bird?.workspace_id, 22);
  assert.deepEqual(calls[0].params, ['bird-1', 10, 22]);
  assert.match(calls[0].text, /UPDATE birds/);
});

test('createPendingBirdTransfer stores an open transfer for auto-completion', async () => {
  const { calls } = mockDb({
    rowCount: 1,
    rows: [
      {
        id: 'transfer-1',
        bird_id: 'bird-1',
        source_workspace_id: 10,
        destination_owner_email: 'receiver@example.com',
        requested_by_user_id: 'user-1',
        completed_at: null,
        completed_workspace_id: null,
        last_error: null,
        created_at: '2026-04-15T00:00:00.000Z',
      },
    ],
  });

  const transfer = await createPendingBirdTransfer({
    birdId: 'bird-1',
    sourceWorkspaceId: 10,
    destinationOwnerEmail: 'receiver@example.com',
    requestedByUserId: 'user-1',
  });

  assert.equal(transfer?.id, 'transfer-1');
  assert.deepEqual(calls[0].params, ['bird-1', 10, 'receiver@example.com', 'user-1']);
  assert.match(calls[0].text, /INSERT INTO pending_bird_transfers/);
  assert.match(calls[0].text, /ON CONFLICT/);
});

test('completePendingBirdTransfersForOwner moves pending birds and marks completion', async () => {
  const { calls } = mockDb(
    {
      rowCount: 1,
      rows: [
        {
          id: 'transfer-1',
          bird_id: 'bird-1',
          source_workspace_id: 10,
          destination_owner_email: 'receiver@example.com',
          requested_by_user_id: 'user-1',
          completed_at: null,
          completed_workspace_id: null,
          last_error: null,
          created_at: '2026-04-15T00:00:00.000Z',
        },
      ],
    },
    {
      rowCount: 1,
      rows: [
        {
          id: 'bird-1',
          workspace_id: 22,
          name: 'Kiwi',
          tag_id: 'A-1',
          species: 'Cockatiel',
          gender: 'female',
          date_of_birth: null,
          gotcha_day: null,
          chart_color: '#cb3a35',
          photo_data_url: null,
          notify_on_dob: false,
          notify_on_gotcha_day: false,
          created_at: '2026-04-14T00:00:00.000Z',
          latest_weight_grams: '92',
          latest_recorded_on: '2026-04-14',
        },
      ],
    },
    { rowCount: 1, rows: [] },
  );

  const result = await completePendingBirdTransfersForOwner('receiver@example.com', 22);

  assert.deepEqual(result, { completed: 1, failed: 0 });
  assert.deepEqual(calls[0].params, ['receiver@example.com']);
  assert.deepEqual(calls[1].params, ['bird-1', 10, 22]);
  assert.deepEqual(calls[2].params, ['transfer-1', 22]);
  assert.match(calls[2].text, /completed_at = CURRENT_TIMESTAMP/);
});
