import { Injectable, Logger } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import * as fs from "fs";

@Injectable()
export class TwitterService {
  private readonly logger = new Logger(TwitterService.name);
  private client: any = null;
  private isEnabled = false;

  constructor(private readonly configService: ConfigService) {
    const apiKey = this.configService.get<string>("TWITTER_API_KEY");
    const apiSecret = this.configService.get<string>("TWITTER_API_SECRET");
    const accessToken = this.configService.get<string>("TWITTER_ACCESS_TOKEN");
    const accessSecret = this.configService.get<string>(
      "TWITTER_ACCESS_SECRET",
    );

    if (apiKey && apiSecret && accessToken && accessSecret) {
      void this.initClient(apiKey, apiSecret, accessToken, accessSecret);
    } else {
      this.logger.warn(
        "⚠️ X/Twitter API keys not configured. Set TWITTER_API_KEY, TWITTER_API_SECRET, TWITTER_ACCESS_TOKEN, TWITTER_ACCESS_SECRET",
      );
    }
  }

  private async initClient(
    apiKey: string,
    apiSecret: string,
    accessToken: string,
    accessSecret: string,
  ) {
    try {
      const { TwitterApi } = await import("twitter-api-v2");
      this.client = new TwitterApi({
        appKey: apiKey,
        appSecret: apiSecret,
        accessToken,
        accessSecret,
      });
      this.isEnabled = true;
      this.logger.log("✅ Twitter API client initialized");
    } catch (error) {
      this.logger.error("Failed to initialize Twitter client", error);
    }
  }

  get available(): boolean {
    return this.isEnabled && this.client !== null;
  }

  /**
   * Post a tweet with an image.
   *
   * @param text - Tweet text
   * @param imagePath - Absolute path to the image file
   * @returns Tweet ID
   */
  async postWithImage(text: string, imagePath: string): Promise<string | null> {
    if (!this.available) {
      this.logger.warn("Twitter not available, skipping post");
      return null;
    }

    try {
      // Step 1: Upload image media via the X media upload endpoint.
      const mediaData = fs.readFileSync(imagePath);
      const mediaId = await this.client.v1.uploadMedia(mediaData, {
        mimeType: this.getMimeType(imagePath),
      });

      // Step 2: Create tweet via v2
      const tweet = await this.client.v2.tweet({
        text,
        media: { media_ids: [mediaId] },
      });

      const tweetId = tweet.data?.id;
      this.logger.log(`✅ Tweet posted: ${tweetId}`);
      return tweetId || null;
    } catch (error) {
      this.logger.error(`❌ Twitter post failed: ${error.message}`);
      return null;
    }
  }

  private getMimeType(imagePath: string): string {
    const ext = imagePath.toLowerCase().split(".").pop();
    if (ext === "jpg" || ext === "jpeg") return "image/jpeg";
    if (ext === "webp") return "image/webp";
    if (ext === "png") return "image/png";
    return "image/jpeg";
  }
}
