import {
  CDNProvider,
  CDNConfig,
  getCacheSettingsForMimeType,
} from "../cdn-config";

export class CloudflareCDNProvider implements CDNProvider {
  private config: CDNConfig;
  private baseUrl: string;

  constructor(config: CDNConfig) {
    this.config = config;
    this.baseUrl = config.customDomain
      ? `https://${config.customDomain}`
      : config.endpoint;
  }

  async upload(file: Buffer, key: string, mimeType: string): Promise<string> {
    if (!this.config.enabled) {
      throw new Error("CDN is disabled");
    }

    try {
      // Cloudflare R2 또는 Images API 사용
      // 실제 구현에서는 Cloudflare API 사용
      const uploadUrl = `${this.config.endpoint}/api/v1/media/${key}`;

      const response = await fetch(uploadUrl, {
        method: "PUT",
        headers: {
          Authorization: `Bearer ${this.config.accessKey}`,
          "Content-Type": mimeType,
          ...this.getCacheHeaders(mimeType),
        },
        body: file,
      });

      if (!response.ok) {
        throw new Error(`Upload failed: ${response.statusText}`);
      }

      return this.getUrl(key);
    } catch (error) {
      console.error("Cloudflare CDN upload error:", error);
      throw error;
    }
  }

  async delete(key: string): Promise<void> {
    if (!this.config.enabled) return;

    try {
      const deleteUrl = `${this.config.endpoint}/api/v1/media/${key}`;

      const response = await fetch(deleteUrl, {
        method: "DELETE",
        headers: {
          Authorization: `Bearer ${this.config.accessKey}`,
        },
      });

      if (!response.ok) {
        throw new Error(`Delete failed: ${response.statusText}`);
      }
    } catch (error) {
      console.error("Cloudflare CDN delete error:", error);
      throw error;
    }
  }

  async invalidate(keys: string[]): Promise<void> {
    if (!this.config.enabled || keys.length === 0) return;

    try {
      // Cloudflare Cache Purge API
      const purgeUrl = `https://api.cloudflare.com/client/v4/zones/${this.config.zone}/purge_cache`;

      const urls = keys.map((key) => this.getUrl(key));

      const response = await fetch(purgeUrl, {
        method: "POST",
        headers: {
          Authorization: `Bearer ${this.config.accessKey}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          files: urls,
        }),
      });

      if (!response.ok) {
        throw new Error(`Cache invalidation failed: ${response.statusText}`);
      }
    } catch (error) {
      console.error("Cloudflare CDN invalidate error:", error);
      throw error;
    }
  }

  getUrl(key: string): string {
    return `${this.baseUrl}/${key}`;
  }

  getCacheHeaders(mimeType: string): Record<string, string> {
    const cacheSettings = getCacheSettingsForMimeType(mimeType);

    return {
      "Cache-Control": `public, max-age=${cacheSettings.maxAge}, stale-while-revalidate=${cacheSettings.staleWhileRevalidate}, stale-if-error=${cacheSettings.staleIfError}`,
      "CDN-Cache-Control": `public, max-age=${cacheSettings.maxAge}`,
      "Cloudflare-CDN-Cache-Control": `public, max-age=${cacheSettings.maxAge}`,
    };
  }

  // Cloudflare 특화 기능들
  async getAnalytics(_startDate: Date, _endDate: Date) {
    try {
      const analyticsUrl = `https://api.cloudflare.com/client/v4/zones/${this.config.zone}/analytics/dashboard`;

      const response = await fetch(analyticsUrl, {
        method: "GET",
        headers: {
          Authorization: `Bearer ${this.config.accessKey}`,
        },
      });

      if (!response.ok) {
        throw new Error(`Analytics fetch failed: ${response.statusText}`);
      }

      return await response.json();
    } catch (error) {
      console.error("Cloudflare analytics error:", error);
      return null;
    }
  }

  async optimizeImage(
    key: string,
    options: {
      width?: number;
      height?: number;
      format?: "webp" | "avif" | "auto";
      quality?: number;
    }
  ) {
    // Cloudflare Images 최적화 옵션
    const params = new URLSearchParams();

    if (options.width) params.append("w", options.width.toString());
    if (options.height) params.append("h", options.height.toString());
    if (options.format) params.append("f", options.format);
    if (options.quality) params.append("q", options.quality.toString());

    const optimizedUrl = `${this.getUrl(key)}?${params.toString()}`;
    return optimizedUrl;
  }

  async getZoneSettings() {
    try {
      const settingsUrl = `https://api.cloudflare.com/client/v4/zones/${this.config.zone}/settings`;

      const response = await fetch(settingsUrl, {
        method: "GET",
        headers: {
          Authorization: `Bearer ${this.config.accessKey}`,
        },
      });

      if (!response.ok) {
        throw new Error(`Settings fetch failed: ${response.statusText}`);
      }

      return await response.json();
    } catch (error) {
      console.error("Cloudflare zone settings error:", error);
      return null;
    }
  }
}
