import { GraphQLJSONObject } from './scalars.js';
import { getOrCreateTelegramUser, requireTelegramUser } from '../auth/telegram.js';
import { listPlaces, listVoiceExperiences } from './places.js';
import { createVoiceExperience } from './voice-experiences.js';

export type GraphqlContext = {
  telegramInitData?: string;
};

export const schema = /* GraphQL */ `
  scalar JSON

  enum VoiceExperienceStatus {
    UPLOADED
    TRANSCRIBING
    TRANSCRIBED
    ANALYZING
    ANALYZED
    FAILED
  }

  type Place {
    id: ID!
    googlePlaceId: String!
    name: String!
    latitude: Float!
    longitude: Float!
    experiences: [VoiceExperience!]!
  }

  type User {
    id: ID!
    telegramId: String!
    username: String
    firstName: String
    lastName: String
    photoUrl: String
    languageCode: String
  }

  type VoiceExperience {
    id: ID!
    place: Place!
    user: User
    status: VoiceExperienceStatus!
    durationSeconds: Int!
    audioObjectKey: String!
    transcript: String
    analysis: JSON
    createdAt: String!
  }

  input CreateVoiceExperienceInput {
    googlePlaceId: String!
    googleName: String!
    latitude: Float!
    longitude: Float!
    durationSeconds: Int!
    audioObjectKey: String!
  }

  input AuthenticateTelegramInput {
    initData: String!
  }

  type AuthPayload {
    user: User!
  }

  type Query {
    health: String!
    places: [Place!]!
    voiceExperiences: [VoiceExperience!]!
  }

  type Mutation {
    authenticateTelegram(input: AuthenticateTelegramInput!): AuthPayload!
    createVoiceExperience(input: CreateVoiceExperienceInput!): VoiceExperience!
  }
`;

export const resolvers = {
  JSON: GraphQLJSONObject,
  Query: {
    health: () => 'ok',
    places: () => listPlaces(),
    voiceExperiences: () => listVoiceExperiences(),
  },
  Mutation: {
    authenticateTelegram: async (
      _: unknown,
      args: { input: { initData: string } },
    ) => ({ user: await getOrCreateTelegramUser(args.input.initData) }),
    createVoiceExperience: async (
      _: unknown,
      args: { input: Parameters<typeof createVoiceExperience>[0] },
      context: unknown,
    ) => {
      const graphqlContext = context as GraphqlContext;
      const user = await requireTelegramUser(graphqlContext.telegramInitData);
      return createVoiceExperience(args.input, user.id);
    },
  },
};
