import { createDAVClient } from 'tsdav';

export interface CalendarEvent {
  uid: string;
  summary: string;
  description?: string;
  location?: string;
  startDate: Date;
  endDate: Date;
  status?: string;
}

export class NextcloudCalendarService {
  private client: any;
  private initialized: boolean = false;

  async initialize() {
    if (this.initialized) return;

    const serverUrl = process.env.NEXTCLOUD_URL;
    const username = process.env.NEXTCLOUD_USERNAME;
    const password = process.env.NEXTCLOUD_PASSWORD;

    if (!serverUrl || !username || !password) {
      throw new Error('Nextcloud credentials not configured');
    }

    try {
      this.client = await createDAVClient({
        serverUrl: `${serverUrl}/remote.php/dav`,
        credentials: {
          username,
          password,
        },
        authMethod: 'Basic',
        defaultAccountType: 'caldav',
      });

      this.initialized = true;
      console.log('✅ Nextcloud CalDAV client initialized');
    } catch (error) {
      console.error('❌ Failed to initialize Nextcloud CalDAV client:', error);
      throw error;
    }
  }

  async getCalendars() {
    await this.initialize();
    try {
      const calendars = await this.client.fetchCalendars();
      return calendars;
    } catch (error) {
      console.error('Error fetching calendars:', error);
      throw error;
    }
  }

  async createEvent(calendarUrl: string, event: CalendarEvent) {
    await this.initialize();
    
    const icsContent = this.generateICS(event);

    try {
      const result = await this.client.createCalendarObject({
        calendar: { url: calendarUrl },
        filename: `${event.uid}.ics`,
        iCalString: icsContent,
      });
      
      console.log('✅ Event created in Nextcloud:', event.summary);
      return result;
    } catch (error) {
      console.error('Error creating event:', error);
      throw error;
    }
  }

  async updateEvent(calendarUrl: string, event: CalendarEvent) {
    await this.initialize();
    
    const icsContent = this.generateICS(event);

    try {
      const result = await this.client.updateCalendarObject({
        calendar: { url: calendarUrl },
        filename: `${event.uid}.ics`,
        iCalString: icsContent,
      });
      
      console.log('✅ Event updated in Nextcloud:', event.summary);
      return result;
    } catch (error) {
      console.error('Error updating event:', error);
      throw error;
    }
  }

  async deleteEvent(calendarUrl: string, eventUid: string) {
    await this.initialize();

    try {
      await this.client.deleteCalendarObject({
        calendar: { url: calendarUrl },
        filename: `${eventUid}.ics`,
      });
      
      console.log('✅ Event deleted from Nextcloud:', eventUid);
    } catch (error) {
      console.error('Error deleting event:', error);
      throw error;
    }
  }

  async syncBookingToCalendar(booking: any) {
    await this.initialize();

    const calendars = await this.getCalendars();
    
    if (calendars.length === 0) {
      throw new Error('No calendars found in Nextcloud');
    }

    const calendar = calendars[0];

    const event: CalendarEvent = {
      uid: `savethemoment-booking-${booking.id}`,
      summary: `${booking.customerName} - ${booking.location?.name || 'Unbekannt'}`,
      description: `
Buchung #${booking.id}
Kunde: ${booking.customerName}
E-Mail: ${booking.customerEmail}
Telefon: ${booking.customerPhone || 'N/A'}
Event-Typ: ${booking.eventType}
Status: ${booking.status}
Fotobox: ${booking.photobox?.name || 'Keine Box'}
Standort: ${booking.location?.name || 'Unbekannt'}
      `.trim(),
      location: booking.location?.address || '',
      startDate: new Date(booking.eventDate),
      endDate: new Date(new Date(booking.eventDate).getTime() + 4 * 60 * 60 * 1000),
      status: booking.status,
    };

    try {
      await this.createEvent(calendar.url, event);
      return event;
    } catch (error) {
      if (error.message?.includes('already exists') || error.response?.status === 412) {
        await this.updateEvent(calendar.url, event);
        return event;
      }
      throw error;
    }
  }

  async removeBookingFromCalendar(bookingId: string) {
    await this.initialize();

    const calendars = await this.getCalendars();
    
    if (calendars.length === 0) {
      throw new Error('No calendars found in Nextcloud');
    }

    const calendar = calendars[0];
    const eventUid = `savethemoment-booking-${bookingId}`;

    try {
      await this.deleteEvent(calendar.url, eventUid);
    } catch (error) {
      console.error('Error removing booking from calendar:', error);
    }
  }

  private generateICS(event: CalendarEvent): string {
    const formatDate = (date: Date) => {
      return date.toISOString().replace(/[-:]/g, '').split('.')[0] + 'Z';
    };

    const now = new Date();
    const dtstamp = formatDate(now);
    const dtstart = formatDate(event.startDate);
    const dtend = formatDate(event.endDate);

    return `BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//SaveTheMoment Atlas//DE
BEGIN:VEVENT
UID:${event.uid}
DTSTAMP:${dtstamp}
DTSTART:${dtstart}
DTEND:${dtend}
SUMMARY:${event.summary}
DESCRIPTION:${event.description || ''}
LOCATION:${event.location || ''}
STATUS:${event.status === 'CONFIRMED' ? 'CONFIRMED' : 'TENTATIVE'}
END:VEVENT
END:VCALENDAR`;
  }
}

export const nextcloudCalendar = new NextcloudCalendarService();
