/**
 * Copyright (c) 2018-Present, Nitrogen Labs, Inc.
 * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
 */
import {APIGatewayProxyEvent, APIGatewayProxyResult, Context} from 'aws-lambda';

export interface DataLayerOptions {
  readonly tableName?: string;
  readonly region?: string;
  readonly endpoint?: string;
}

export class DataLayer {
  private readonly options: DataLayerOptions;

  constructor(options: DataLayerOptions = {}) {
    this.options = {
      tableName: process.env.TABLE_NAME || 'default-table',
      region: process.env.AWS_REGION || 'us-east-1',
      endpoint: process.env.DYNAMODB_ENDPOINT,
      ...options
    };
  }

  /**
   * Get a single item by ID
   */
  async getItem(id: string): Promise<any> {
    try {
      // TODO: Implement DynamoDB getItem logic
      console.log(`Getting item with ID: ${id}`);

      // Example response structure
      return {
        id,
        data: 'sample data',
        timestamp: new Date().toISOString()
      };
    } catch (error) {
      console.error('Error getting item:', error);
      throw error;
    }
  }

  /**
   * Create a new item
   */
  async createItem(data: any): Promise<any> {
    try {
      // TODO: Implement DynamoDB putItem logic
      console.log('Creating new item:', data);

      const newItem = {
        id: data.id || `item-${Date.now()}`,
        ...data,
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString()
      };

      return newItem;
    } catch (error) {
      console.error('Error creating item:', error);
      throw error;
    }
  }

  /**
   * Update an existing item
   */
  async updateItem(id: string, data: any): Promise<any> {
    try {
      // TODO: Implement DynamoDB updateItem logic
      console.log(`Updating item ${id}:`, data);

      const updatedItem = {
        id,
        ...data,
        updatedAt: new Date().toISOString()
      };

      return updatedItem;
    } catch (error) {
      console.error('Error updating item:', error);
      throw error;
    }
  }

  /**
   * Delete an item by ID
   */
  async deleteItem(id: string): Promise<boolean> {
    try {
      // TODO: Implement DynamoDB deleteItem logic
      console.log(`Deleting item with ID: ${id}`);

      return true;
    } catch (error) {
      console.error('Error deleting item:', error);
      throw error;
    }
  }

  /**
   * List items with optional filtering
   */
  async listItems(filters?: any): Promise<any[]> {
    try {
      // TODO: Implement DynamoDB scan/query logic
      console.log('Listing items with filters:', filters);

      // Example response
      return [
        {
          id: 'item-1',
          data: 'sample data 1',
          timestamp: new Date().toISOString()
        },
        {
          id: 'item-2',
          data: 'sample data 2',
          timestamp: new Date().toISOString()
        }
      ];
    } catch (error) {
      console.error('Error listing items:', error);
      throw error;
    }
  }

  /**
   * Lambda handler for HTTP requests
   */
  async handleRequest(event: APIGatewayProxyEvent, context: Context): Promise<APIGatewayProxyResult> {
    try {
      const {httpMethod, pathParameters, body, queryStringParameters} = event;
      const id = pathParameters?.id;

      let result: any;

      switch (httpMethod) {
        case 'GET':
          if (id) {
            result = await this.getItem(id);
          } else {
            result = await this.listItems(queryStringParameters);
          }
          break;

        case 'POST':
          const createData = body ? JSON.parse(body) : {};
          result = await this.createItem(createData);
          break;

        case 'PUT':
        case 'PATCH':
          if (!id) {
            return {
              statusCode: 400,
              headers: {
                'Content-Type': 'application/json',
                'Access-Control-Allow-Origin': '*'
              },
              body: JSON.stringify({error: 'ID is required for update operations'})
            };
          }
          const updateData = body ? JSON.parse(body) : {};
          result = await this.updateItem(id, updateData);
          break;

        case 'DELETE':
          if (!id) {
            return {
              statusCode: 400,
              headers: {
                'Content-Type': 'application/json',
                'Access-Control-Allow-Origin': '*'
              },
              body: JSON.stringify({error: 'ID is required for delete operations'})
            };
          }
          await this.deleteItem(id);
          result = {message: 'Item deleted successfully'};
          break;

        default:
          return {
            statusCode: 405,
            headers: {
              'Content-Type': 'application/json',
              'Access-Control-Allow-Origin': '*'
            },
            body: JSON.stringify({error: 'Method not allowed'})
          };
      }

      return {
        statusCode: 200,
        headers: {
          'Content-Type': 'application/json',
          'Access-Control-Allow-Origin': '*'
        },
        body: JSON.stringify(result)
      };

    } catch (error) {
      console.error('Handler error:', error);

      return {
        statusCode: 500,
        headers: {
          'Content-Type': 'application/json',
          'Access-Control-Allow-Origin': '*'
        },
        body: JSON.stringify({
          error: 'Internal server error',
          message: error instanceof Error ? error.message : 'Unknown error'
        })
      };
    }
  }
}

// Export the handler function for Lambda
export const handler = async (event: APIGatewayProxyEvent, context: Context): Promise<APIGatewayProxyResult> => {
  const dataLayer = new DataLayer();
  return dataLayer.handleRequest(event, context);
};
