import { IShopifyMediaService } from "../interfaces/IShopifyMediaService" import { IShop } from "../interfaces/IShop" import { formatGqlForJSON, buildGqlQuery } from "../shopifyApi" export class ShopifyMediaService implements IShopifyMediaService { private shop: IShop constructor(shop: IShop) { this.shop = shop } stagedUploadsCreate(input: any[]): any { const query = /* GraphQL */ ` mutation stagedUploadsCreate($input: [StagedUploadInput!]!) { stagedUploadsCreate(input: $input) { stagedTargets { url resourceUrl parameters { name value } } userErrors { field message } } } ` const variables = { input } const payload = buildGqlQuery(query, variables) const response = this.shop.shopifyGraphQLAPI(payload) return response.content.data.stagedUploadsCreate } productCreateMedia(productId: string, media: any[]): any { const query = /* GraphQL */ ` mutation productCreateMedia($media: [CreateMediaInput!]!, $productId: ID!) { productCreateMedia(media: $media, productId: $productId) { media { id alt mediaContentType status } mediaUserErrors { field message } product { id title } } } ` const variables = { productId, media } const payload = buildGqlQuery(query, variables) const response = this.shop.shopifyGraphQLAPI(payload) return response.content.data.productCreateMedia } getProductMedia(productId: string): any[] { const query = /* GraphQL */ ` query getProductMedia($productId: ID!) { product(id: $productId) { media(first: 250) { edges { node { id alt mediaContentType status preview { image { originalSrc } } ... on Video { sources { url mimeType } } ... on MediaImage { image { url } } } } } } } ` const variables = { productId } const payload = buildGqlQuery(query, variables) const response = this.shop.shopifyGraphQLAPI(payload) if (!response || !response.content || !response.content.data || !response.content.data.product) { console.error("getProductMedia: Invalid response or product not found. Raw Response:", JSON.stringify(response)); throw new Error(`Product not found or access denied for ID: ${productId}. See Logs for details.`); } return response.content.data.product.media.edges.map((edge: any) => edge.node) } productDeleteMedia(productId: string, mediaId: string): any { const query = /* GraphQL */ ` mutation productDeleteMedia($mediaIds: [ID!]!, $productId: ID!) { productDeleteMedia(mediaIds: $mediaIds, productId: $productId) { deletedMediaIds mediaUserErrors { field message } } } ` const variables = { productId, mediaIds: [mediaId] } const payload = buildGqlQuery(query, variables) const response = this.shop.shopifyGraphQLAPI(payload) if (!response || !response.content || !response.content.data) { console.error("productDeleteMedia failed. Response:", JSON.stringify(response)) if (response && response.content && response.content.errors) { console.error("GraphQL Errors:", JSON.stringify(response.content.errors)) } throw new Error(`Shopify API failed for productDeleteMedia: ${response ? 'Invalid Response' : 'No Response'}`) } return response.content.data.productDeleteMedia } productReorderMedia(productId: string, moves: any[]): any { const query = /* GraphQL */ ` mutation productReorderMedia($id: ID!, $moves: [MoveInput!]!) { productReorderMedia(id: $id, moves: $moves) { job { id done } userErrors { field message } } } ` const variables = { id: productId, moves } const payload = buildGqlQuery(query, variables) const response = this.shop.shopifyGraphQLAPI(payload) return response.content.data.productReorderMedia return response.content.data.productReorderMedia } getShopDomain(): string { return this.shop.getShopDomain() } }