import { Inject, Injectable } from '@nestjs/common';
import type { Kysely } from 'kysely';
import { KYSELY_DB } from '../../database/src';
import type { Database } from '../../database/src';
import type {
  ResearchDepth,
  TripPlanningStyle,
  TripSettings,
  UpdateTripSettingsDto,
} from './trip.types';

function toTripSettings(row: {
  trip_id: string;
  web_research_enabled: boolean;
  periodic_agent_review_enabled: boolean;
  notification_email_enabled: boolean;
  notification_push_enabled: boolean;
  default_research_depth: string | null;
  default_planning_style: string | null;
}): TripSettings {
  return {
    tripId: row.trip_id,
    webResearchEnabled: row.web_research_enabled,
    periodicAgentReviewEnabled: row.periodic_agent_review_enabled,
    notificationEmailEnabled: row.notification_email_enabled,
    notificationPushEnabled: row.notification_push_enabled,
    defaultResearchDepth: row.default_research_depth as ResearchDepth | null,
    defaultPlanningStyle:
      row.default_planning_style as TripPlanningStyle | null,
  };
}

@Injectable()
export class TripSettingsRepository {
  constructor(@Inject(KYSELY_DB) private readonly db: Kysely<Database>) {}

  async findByTripId(tripId: string): Promise<TripSettings | undefined> {
    const row = await this.db
      .selectFrom('trip_settings')
      .selectAll()
      .where('trip_id', '=', tripId)
      .executeTakeFirst();
    return row ? toTripSettings(row) : undefined;
  }

  async replace(
    tripId: string,
    dto: UpdateTripSettingsDto,
  ): Promise<TripSettings> {
    const row = await this.db
      .updateTable('trip_settings')
      .set({
        web_research_enabled: dto.webResearchEnabled,
        periodic_agent_review_enabled: dto.periodicAgentReviewEnabled,
        notification_email_enabled: dto.notificationEmailEnabled,
        notification_push_enabled: dto.notificationPushEnabled,
        default_research_depth: dto.defaultResearchDepth,
        default_planning_style: dto.defaultPlanningStyle,
        updated_at: new Date().toISOString(),
      })
      .where('trip_id', '=', tripId)
      .returningAll()
      .executeTakeFirstOrThrow();

    return toTripSettings(row);
  }
}
