import { ResponseCategory } from '@spiffy-ai/commerce-api-client';
import { Response, ReviewRichInformation } from 'src/application/models/index';
import { ApiReviewRichInformation } from 'src/application/models/api/responseGenerics';
import { isApiPageResponseAttributes } from 'src/application/models/guards/api/isApiPageResponseAttributes';
import { isApiProductResponseAttributes } from 'src/application/models/guards/api/isApiProductResponseAttributes';
import { isApiResponse } from 'src/application/models/guards/api/isApiResponse';
import { isApiReviewResponseAttributes } from 'src/application/models/guards/api/isApiReviewResponseAttributes';
import { isApiTextResponseAttributes } from 'src/application/models/guards/api/isApiTextResponseAttributes';
import { isApiProductSearchResponseAttributes } from 'src/application/models/guards/api/isApiProductSearchAttributes';
import { isApiFormResponseAttributes } from 'src/application/models/guards/api/isApiFormResponse';
import { isApiOrderResponseAttributes } from 'src/application/models/guards/api/isApiOrderResponseAttributes';
import { stringToFulfillmentDisplayStatusEnumValue } from 'src/application/models/utils/stringToFulfillmentDisplayStatusEnumValue';
import { isApiProductSearchFilterResponseAttributes } from 'src/application/models/guards/api/isApiProductSearchFilterAttributes';

const richInformationFromCommerceRichInformation = (
  data: ApiReviewRichInformation,
): ReviewRichInformation => ({
  cons: data.cons,
  pros: data.pros,
  reviewDate: data.review_date,
  reviewerTitle: data.reviewer_title,
  productFamiliarity: data.product_familiarity,
});

export const validateResponse = (data: unknown): Response | undefined => {
  if (!isApiResponse(data)) {
    return undefined;
  }

  if (data.category === ResponseCategory.Text && isApiTextResponseAttributes(data.attributes)) {
    return {
      id: data.id,
      createdAt: data.created_at,
      category: ResponseCategory.Text,
      attributes: {
        content: data.attributes.content,
      },
    };
  }

  if (
    data.category === ResponseCategory.Product &&
    isApiProductResponseAttributes(data.attributes)
  ) {
    return {
      id: data.id,
      createdAt: data.created_at,
      category: ResponseCategory.Product,
      attributes: {
        id: data.attributes.id,
        description: data.attributes.description,
        imageUrl: data.attributes.image_url,
        imageUrls: data.attributes.image_urls,
        title: data.attributes.title,
        url: data.attributes.url,
        originalPrice: data.attributes.original_price,
        salePrice: data.attributes.sale_price,
        averageRating: data.attributes.average_rating,
        numberReviews: data.attributes.number_reviews,
        metadata: data.attributes.metadata,
        isForGrid: data.attributes.is_for_grid,
        colors: data.attributes.colors,
        sizes: data.attributes.sizes,
        filters: data.attributes.filters,
      },
    };
  }

  if (data.category === ResponseCategory.Review && isApiReviewResponseAttributes(data.attributes)) {
    return {
      id: data.id,
      createdAt: data.created_at,
      category: ResponseCategory.Review,
      attributes: {
        id: data.attributes.id,
        productId: data.attributes.product_id,
        title: data.attributes.title,
        reviewer: data.attributes.reviewer,
        review: data.attributes.review,
        stars: data.attributes.stars,
        richInformation: data.attributes.rich_information
          ? richInformationFromCommerceRichInformation(data.attributes.rich_information)
          : undefined,
      },
    };
  }

  if (data.category === ResponseCategory.Separator) {
    return {
      id: data.id,
      createdAt: data.created_at,
      category: ResponseCategory.Separator,
    };
  }

  if (data.category === ResponseCategory.Page && isApiPageResponseAttributes(data.attributes)) {
    return {
      id: data.id,
      createdAt: data.created_at,
      category: ResponseCategory.Page,
      attributes: {
        id: data.attributes.id,
        title: data.attributes.title,
        description: data.attributes.description,
        url: data.attributes.url,
      },
    };
  }

  if (data.category === ResponseCategory.Form && isApiFormResponseAttributes(data.attributes)) {
    return {
      id: data.id,
      createdAt: data.created_at,
      category: ResponseCategory.Form,
      attributes: {
        formCategory: data.attributes.form_category
          ? {
              formType: data.attributes.form_category.form_type,
            }
          : undefined,
        schema: {
          properties: data.attributes.schema.properties,
          required: data.attributes.schema.required.map(String),
        },
      },
    };
  }

  if (
    data.category === ResponseCategory.ProductSearch &&
    isApiProductSearchResponseAttributes(data.attributes)
  ) {
    return {
      id: data.id,
      createdAt: data.created_at,
      category: ResponseCategory.ProductSearch,
      attributes: {
        generatedQuery: data.attributes.generated_query,
        productCount: data.attributes.product_count,
      },
    };
  }

  if (
    data.category === ResponseCategory.ProductSearchFilter &&
    isApiProductSearchFilterResponseAttributes(data.attributes)
  ) {
    return {
      id: data.id,
      createdAt: data.created_at,
      category: ResponseCategory.ProductSearchFilter,
      attributes: {
        filterName: data.attributes.filter_name,
      },
    };
  }

  if (data.category === ResponseCategory.Order && isApiOrderResponseAttributes(data.attributes)) {
    return {
      id: data.id,
      createdAt: data.created_at,
      category: ResponseCategory.Order,
      attributes: {
        orderId: data.attributes.order_id,
        orderNumber: data.attributes.order_number,
        createdAt: data.attributes.created_at,
        latestEventDate: data.attributes.latest_event_date,
        lineItems: data.attributes.line_items.map(item => ({
          itemTitle: item.item_title,
          itemPrice: item.item_price,
          itemQuantity: item.item_quantity,
          orderItemId: item.order_item_id,
          image: item.image ?? undefined,
          inTransitAt: item.in_transit_at ?? undefined,
          deliveredAt: item.delivered_at ?? undefined,
          estimatedDeliveryAt: item.estimated_delivery_at ?? undefined,
          fulfillmentDisplayStatus: item.fulfillment_display_status
            ? stringToFulfillmentDisplayStatusEnumValue(item.fulfillment_display_status)
            : undefined,
          trackingUrl: item.tracking_url ?? undefined,
        })),
      },
    };
  }

  return undefined;
};
