/**
 * @ai-summary Data access layer for stations
 */

import { Pool } from 'pg';
import { Station, SavedStation } from '../domain/stations.types';

export class StationsRepository {
  constructor(private pool: Pool) {}

  async cacheStation(station: Station): Promise<void> {
    const query = `
      INSERT INTO station_cache (
        place_id, name, address, latitude, longitude,
        price_regular, price_premium, price_diesel, rating, photo_reference
      )
      VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
      ON CONFLICT (place_id) DO UPDATE
      SET name = $2, address = $3, latitude = $4, longitude = $5,
          rating = $9, photo_reference = $10, cached_at = NOW()
    `;

    await this.pool.query(query, [
      station.placeId,
      station.name,
      station.address,
      station.latitude,
      station.longitude,
      station.priceRegular,
      station.pricePremium,
      station.priceDiesel,
      station.rating,
      station.photoReference
    ]);
  }

  async getCachedStation(placeId: string): Promise<Station | null> {
    const query = 'SELECT * FROM station_cache WHERE place_id = $1';
    const result = await this.pool.query(query, [placeId]);
    
    if (result.rows.length === 0) {
      return null;
    }
    
    return this.mapCacheRow(result.rows[0]);
  }

  async saveStation(
    userId: string,
    placeId: string,
    data?: {
      nickname?: string;
      notes?: string;
      isFavorite?: boolean;
      has93Octane?: boolean;
      has93OctaneEthanolFree?: boolean;
    }
  ): Promise<SavedStation> {
    const query = `
      INSERT INTO saved_stations (
        user_id,
        place_id,
        nickname,
        notes,
        is_favorite,
        has_93_octane,
        has_93_octane_ethanol_free
      )
      VALUES ($1, $2, $3, $4, $5, $6, $7)
      ON CONFLICT (user_id, place_id) DO UPDATE
      SET nickname = COALESCE($3, saved_stations.nickname),
          notes = COALESCE($4, saved_stations.notes),
          is_favorite = COALESCE($5, saved_stations.is_favorite),
          has_93_octane = COALESCE($6, saved_stations.has_93_octane),
          has_93_octane_ethanol_free = CASE
            WHEN $6 IS NOT NULL AND $6 = false THEN false
            ELSE COALESCE($7, saved_stations.has_93_octane_ethanol_free)
          END,
          updated_at = NOW()
      RETURNING *
    `;
    
    const result = await this.pool.query(query, [
      userId,
      placeId,
      data?.nickname,
      data?.notes,
      data?.isFavorite ?? false,
      data?.has93Octane ?? false,
      data?.has93OctaneEthanolFree ?? false
    ]);
    
    return this.mapSavedRow(result.rows[0]);
  }

  async updateSavedStation(
    userId: string,
    placeId: string,
    data: {
      nickname?: string;
      notes?: string;
      isFavorite?: boolean;
      has93Octane?: boolean;
      has93OctaneEthanolFree?: boolean;
    }
  ): Promise<SavedStation | null> {
    const query = `
      UPDATE saved_stations
      SET
        nickname = COALESCE($3, nickname),
        notes = COALESCE($4, notes),
        is_favorite = COALESCE($5, is_favorite),
        has_93_octane = COALESCE($6, has_93_octane),
        has_93_octane_ethanol_free = CASE
          WHEN $6 IS NOT NULL AND $6 = false THEN false
          ELSE COALESCE($7, has_93_octane_ethanol_free)
        END,
        updated_at = NOW()
      WHERE user_id = $1 AND place_id = $2
      RETURNING *
    `;

    const result = await this.pool.query(query, [
      userId,
      placeId,
      data.nickname,
      data.notes,
      data.isFavorite,
      data.has93Octane,
      data.has93OctaneEthanolFree
    ]);

    if (result.rows.length === 0) {
      return null;
    }

    return this.mapSavedRow(result.rows[0]);
  }

  async getUserSavedStations(userId: string): Promise<SavedStation[]> {
    const query = `
      SELECT * FROM saved_stations
      WHERE user_id = $1
      ORDER BY is_favorite DESC, created_at DESC
    `;
    
    const result = await this.pool.query(query, [userId]);
    return result.rows.map(row => this.mapSavedRow(row));
  }

  async deleteSavedStation(userId: string, placeId: string): Promise<boolean> {
    const query = 'DELETE FROM saved_stations WHERE user_id = $1 AND place_id = $2';
    const result = await this.pool.query(query, [userId, placeId]);
    return (result.rowCount ?? 0) > 0;
  }

  private mapCacheRow(row: any): Station {
    return {
      id: row.id,
      placeId: row.place_id,
      name: row.name,
      address: row.address,
      latitude: parseFloat(row.latitude),
      longitude: parseFloat(row.longitude),
      priceRegular: row.price_regular ? parseFloat(row.price_regular) : undefined,
      pricePremium: row.price_premium ? parseFloat(row.price_premium) : undefined,
      priceDiesel: row.price_diesel ? parseFloat(row.price_diesel) : undefined,
      rating: row.rating ? parseFloat(row.rating) : undefined,
      photoReference: row.photo_reference,
      lastUpdated: row.cached_at
    };
  }

  private mapSavedRow(row: any): SavedStation {
    return {
      id: row.id,
      userId: row.user_id,
      stationId: row.place_id,
      placeId: row.place_id,
      nickname: row.nickname,
      notes: row.notes,
      isFavorite: row.is_favorite,
      has93Octane: row.has_93_octane ?? false,
      has93OctaneEthanolFree: row.has_93_octane_ethanol_free ?? false,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    };
  }
}
