import { describe, it, expect, vi, beforeEach } from 'vitest';
import { createCreateCommand } from '../../src/commands/create.js';
import { createGetCommand } from '../../src/commands/get.js';
import { createDescribeCommand } from '../../src/commands/describe.js';
import { type ApiClient, ApiError } from '../../src/api-client.js';

function mockClient(): ApiClient {
  return {
    get: vi.fn(async () => []),
    post: vi.fn(async () => ({ id: 'new-id', name: 'test' })),
    put: vi.fn(async () => ({})),
    delete: vi.fn(async () => {}),
  } as unknown as ApiClient;
}

describe('project with new fields', () => {
  let client: ReturnType<typeof mockClient>;
  let output: string[];
  const log = (...args: unknown[]) => output.push(args.map(String).join(' '));

  beforeEach(() => {
    client = mockClient();
    output = [];
  });

  describe('create project with enhanced options', () => {
    it('creates project with servers', async () => {
      const cmd = createCreateCommand({ client, log });
      await cmd.parseAsync([
        'project', 'smart-home',
        '-d', 'Smart home project',
        '--server', 'my-grafana',
        '--server', 'my-ha',
      ], { from: 'user' });

      expect(client.post).toHaveBeenCalledWith('/api/v1/projects', expect.objectContaining({
        name: 'smart-home',
        description: 'Smart home project',
        servers: ['my-grafana', 'my-ha'],
      }));
    });
  });

  describe('get projects shows new columns', () => {
    it('shows SERVERS column', async () => {
      const deps = {
        output: [] as string[],
        fetchResource: vi.fn(async () => [{
          id: 'proj-1',
          name: 'smart-home',
          description: 'Test',
          ownerId: 'user-1',
          servers: [{ server: { name: 'grafana' } }, { server: { name: 'ha' } }],
        }]),
        log: (...args: string[]) => deps.output.push(args.join(' ')),
      };
      const cmd = createGetCommand(deps);
      await cmd.parseAsync(['node', 'test', 'projects']);

      const text = deps.output.join('\n');
      expect(text).toContain('SERVERS');
      expect(text).toContain('smart-home');
    });
  });

  describe('describe project shows full detail', () => {
    it('shows servers and LLM config', async () => {
      const deps = {
        output: [] as string[],
        client: mockClient(),
        fetchResource: vi.fn(async () => ({
          id: 'proj-1',
          name: 'smart-home',
          description: 'Smart home',
          llmProvider: 'gemini-cli',
          llmModel: 'gemini-2.0-flash',
          ownerId: 'user-1',
          servers: [
            { server: { name: 'my-grafana' } },
            { server: { name: 'my-ha' } },
          ],
          createdAt: '2025-01-01',
          updatedAt: '2025-01-01',
        })),
        log: (...args: string[]) => deps.output.push(args.join(' ')),
      };
      const cmd = createDescribeCommand(deps);
      await cmd.parseAsync(['node', 'test', 'project', 'proj-1']);

      const text = deps.output.join('\n');
      expect(text).toContain('=== Project: smart-home ===');
      expect(text).toContain('gemini-cli');
      expect(text).toContain('my-grafana');
      expect(text).toContain('my-ha');
    });
  });
});
