import axios from "axios";
import winston from "winston";
import { Appointment, CRMBackend } from "../crm.interfaces.js";

const CALENDLY_API_KEY = process.env.CALENDLY_API_KEY || "";
const CALENDLY_USER_URI = process.env.CALENDLY_USER_URI || ""; // Fetch this dynamically if needed

export class CalendlyBackend implements CRMBackend {
  private logger: any;
  private apiClient: any;

  constructor() {
    this.logger = winston.createLogger({
      level: "info",
      format: winston.format.json(),
      defaultMeta: { service: "crm-service" },
      transports: [
        new winston.transports.Console({
          format: winston.format.simple(),
        }),
      ],
    });

    if (!CALENDLY_API_KEY) {
      this.logger.warn("Calendly API key is missing");
    }

    this.apiClient = axios.create({
      baseURL: "https://api.calendly.com",
      headers: {
        Authorization: `Bearer ${CALENDLY_API_KEY}`,
        "Content-Type": "application/json",
      },
    });
  }
  fetchAppointmentTypes(): Promise<string[]> {
    throw new Error("Method not implemented.");
  }
  bookAppointment(appointment: Appointment): Promise<string> {
    try {
      return this.createEvent(appointment);
    } catch (error) {
      this.logger.error("Error booking appointment:", error);
      throw new Error("Failed to book appointment");
    }
  }

  modifyAppointment(
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    id: string,
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    updatedInfo: Partial<Appointment>,
  ): Promise<Appointment> {
    throw new Error("Method not implemented.");
  }

  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  findAppointmentByContactName(name: string): Promise<Appointment> {
    throw new Error("Method not implemented.");
  }

  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  findAppointmentByTimestamp(timestamp: string): Promise<Appointment | null> {
    throw new Error("Method not implemented.");
  }

  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  findAppointmentById(id: string): Promise<Appointment | null> {
    throw new Error("Method not implemented.");
  }

  async fetchAvailableSlots(): Promise<string[]> {
    try {
      const availableSlots = await this.calendalyGetAvailability(
        CALENDLY_USER_URI,
        new Date().toISOString(),
        new Date(Date.now() + 86400000).toISOString(),
      );
      return availableSlots;
    } catch (error) {
      this.logger.error("Error fetching available slots:", error);
      throw new Error("Failed to fetch available slots");
    }
  }

  async calendalyGetAvailability(
    userUri: string,
    startTime: string,
    endTime: string,
  ): Promise<string[]> {
    try {
      const response = await this.apiClient.get("/scheduling_links", {
        params: {
          user: userUri,
          start_time: startTime,
          end_time: endTime,
        },
      });
      this.logger.info("Available slots fetched successfully");
      return response.data as string[];
    } catch (error) {
      this.logger.error("Error fetching available slots:", error);
      throw new Error("Failed to fetch available slots");
    }
  }

  async createEvent(appointment: Appointment): Promise<string> {
    const attendees = [
      { email: appointment.contactEmail },
      { email: appointment.employeeEmail },
    ];
    const startTime = appointment.timestamp;
    const duration = "60"; // 60 minutes
    try {
      const payload = {
        event_type: `${CALENDLY_USER_URI}/event_types`,
        start_time: startTime,
        invitees: attendees.map((attendee) => ({ email: attendee.email })),
        duration: duration,
      };

      const response = await this.apiClient.post("/scheduled_events", payload);
      this.logger.info("Event scheduled successfully", response.data);
      return response.data.resource.uri; // Returns the event link
    } catch (error) {
      this.logger.error("Error scheduling event:", error);
      throw new Error("Failed to schedule event");
    }
  }
  
  async createEventToSms(appointment: Appointment): Promise<string> {
    throw new Error("Method not implemented.");
  }
}
