/**
 * Account Router — list, add, remove, refresh, update auth, mark exhausted, providers
 */

import { z } from 'zod';
import type { ProcedureBuilder } from '../trpc.js';
import { requireAccountRepository } from './_helpers.js';
import { listProviders as listProviderNames } from '../../agent/providers/registry.js';

export function accountProcedures(publicProcedure: ProcedureBuilder) {
  return {
    listAccounts: publicProcedure
      .query(async ({ ctx }) => {
        const repo = requireAccountRepository(ctx);
        return repo.findAll();
      }),

    addAccount: publicProcedure
      .input(z.object({
        email: z.string().min(1),
        provider: z.string().default('claude'),
        configJson: z.string().optional(),
        credentials: z.string().optional(),
      }))
      .mutation(async ({ ctx, input }) => {
        const repo = requireAccountRepository(ctx);
        return repo.create({
          email: input.email,
          provider: input.provider,
          configJson: input.configJson,
          credentials: input.credentials,
        });
      }),

    removeAccount: publicProcedure
      .input(z.object({ id: z.string().min(1) }))
      .mutation(async ({ ctx, input }) => {
        const repo = requireAccountRepository(ctx);
        await repo.delete(input.id);
        return { success: true };
      }),

    refreshAccounts: publicProcedure
      .mutation(async ({ ctx }) => {
        const repo = requireAccountRepository(ctx);
        const cleared = await repo.clearExpiredExhaustion();
        return { cleared };
      }),

    updateAccountAuth: publicProcedure
      .input(z.object({
        id: z.string().min(1),
        configJson: z.string(),
        credentials: z.string(),
      }))
      .mutation(async ({ ctx, input }) => {
        const repo = requireAccountRepository(ctx);
        return repo.updateAccountAuth(input.id, input.configJson, input.credentials);
      }),

    markAccountExhausted: publicProcedure
      .input(z.object({
        id: z.string().min(1),
        until: z.string().datetime(),
      }))
      .mutation(async ({ ctx, input }) => {
        const repo = requireAccountRepository(ctx);
        return repo.markExhausted(input.id, new Date(input.until));
      }),

    listProviderNames: publicProcedure
      .query(() => {
        return listProviderNames();
      }),

    addAccountByToken: publicProcedure
      .input(z.object({
        email: z.string().min(1),
        provider: z.string().default('claude'),
        token: z.string().min(1),
      }))
      .mutation(async ({ ctx, input }) => {
        const repo = requireAccountRepository(ctx);
        const credentials = JSON.stringify({ claudeAiOauth: { accessToken: input.token } });
        const configJson = JSON.stringify({ hasCompletedOnboarding: true });
        const existing = await repo.findByEmail(input.email);
        if (existing) {
          const account = await repo.updateAccountAuth(existing.id, configJson, credentials);
          return { upserted: true, account };
        }
        const account = await repo.create({
          email: input.email,
          provider: input.provider,
          configJson,
          credentials,
        });
        return { upserted: false, account };
      }),
  };
}
