interface LexOfficeContact {
  id?: string;
  organizationId: string;
  version: number;
  roles: {
    customer?: {
      number?: number;
    };
  };
  company?: {
    name: string;
    taxNumber?: string;
    vatRegistrationId?: string;
    allowTaxFreeInvoices?: boolean;
    contactPersons?: Array<{
      salutation?: string;
      firstName?: string;
      lastName?: string;
      primary?: boolean;
      emailAddress?: string;
      phoneNumber?: string;
    }>;
  };
  person?: {
    salutation?: string;
    firstName?: string;
    lastName?: string;
  };
  addresses?: {
    billing?: Array<{
      supplement?: string;
      street?: string;
      zip?: string;
      city?: string;
      countryCode?: string;
    }>;
  };
  emailAddresses?: {
    business?: Array<string>;
    office?: Array<string>;
    private?: Array<string>;
    other?: Array<string>;
  };
  phoneNumbers?: {
    business?: Array<string>;
    office?: Array<string>;
    mobile?: Array<string>;
    private?: Array<string>;
    fax?: Array<string>;
    other?: Array<string>;
  };
  note?: string;
}

interface LexOfficeQuotation {
  id?: string;
  organizationId?: string;
  createdDate?: string;
  updatedDate?: string;
  voucherNumber?: string;
  voucherDate: string;
  address: {
    contactId?: string;
    name?: string;
    supplement?: string;
    street?: string;
    city?: string;
    zip?: string;
    countryCode: string;
  };
  lineItems: Array<{
    type: 'custom' | 'text';
    name?: string;
    description?: string;
    quantity?: number;
    unitName?: string;
    unitPrice?: {
      currency: string;
      netAmount: number;
      taxRatePercentage: number;
    };
  }>;
  totalPrice?: {
    currency: string;
  };
  taxConditions?: {
    taxType: 'net' | 'gross' | 'vatfree';
  };
  title?: string;
  introduction?: string;
  remark?: string;
}

interface LexOfficeInvoice extends Omit<LexOfficeQuotation, 'id'> {
  voucherStatus?: string;
  shippingConditions?: {
    shippingDate?: string;
    shippingType?: string;
  };
  paymentConditions?: {
    paymentTermLabel?: string;
    paymentTermDuration?: number;
  };
}

export class LexOfficeService {
  private apiKey: string;
  private baseUrl = 'https://api.lexoffice.io/v1';

  constructor() {
    this.apiKey = process.env.LEXOFFICE_API_KEY || '';
    if (!this.apiKey) {
      console.warn('LexOffice API Key nicht konfiguriert');
    }
  }

  private async request(method: string, endpoint: string, data?: any) {
    try {
      const response = await fetch(`${this.baseUrl}${endpoint}`, {
        method,
        headers: {
          'Authorization': `Bearer ${this.apiKey}`,
          'Content-Type': 'application/json',
          'Accept': 'application/json',
        },
        body: data ? JSON.stringify(data) : undefined,
      });

      if (!response.ok) {
        const errorText = await response.text();
        throw new Error(`LexOffice API Error: ${response.status} - ${errorText}`);
      }

      return await response.json();
    } catch (error) {
      console.error('LexOffice API Request failed:', error);
      throw error;
    }
  }

  async createContact(contact: Partial<LexOfficeContact>): Promise<{ id: string; resourceUri: string }> {
    return this.request('POST', '/contacts', contact);
  }

  async getContact(contactId: string): Promise<LexOfficeContact> {
    return this.request('GET', `/contacts/${contactId}`);
  }

  async createQuotation(quotation: LexOfficeQuotation): Promise<{ id: string; resourceUri: string; createdDate: string; updatedDate: string; voucherNumber: string }> {
    return this.request('POST', '/quotations', quotation);
  }

  async getQuotation(quotationId: string): Promise<LexOfficeQuotation> {
    return this.request('GET', `/quotations/${quotationId}`);
  }

  async createInvoice(invoice: LexOfficeInvoice): Promise<{ id: string; resourceUri: string; createdDate: string; updatedDate: string; voucherNumber: string }> {
    return this.request('POST', '/invoices', invoice);
  }

  async getInvoice(invoiceId: string): Promise<LexOfficeInvoice> {
    return this.request('GET', `/invoices/${invoiceId}`);
  }

  async finalizeInvoice(invoiceId: string): Promise<{ id: string; resourceUri: string }> {
    return this.request('PUT', `/invoices/${invoiceId}/pursue`, {
      precedingSalesVoucherId: null,
      preserveVoucherNumber: false,
    });
  }

  async createContactFromBooking(booking: any): Promise<string> {
    const contact: Partial<LexOfficeContact> = {
      roles: {
        customer: {},
      },
      addresses: {
        billing: [{
          street: booking.customerAddress,
          zip: booking.customerZip,
          city: booking.customerCity,
          countryCode: 'DE',
        }],
      },
      emailAddresses: {
        business: [booking.customerEmail],
      },
      phoneNumbers: {
        business: [booking.customerPhone],
      },
    };

    if (booking.invoiceType === 'BUSINESS' && booking.companyName) {
      contact.company = {
        name: booking.companyName,
        contactPersons: [{
          firstName: booking.customerName.split(' ')[0],
          lastName: booking.customerName.split(' ').slice(1).join(' '),
          primary: true,
          emailAddress: booking.customerEmail,
          phoneNumber: booking.customerPhone,
        }],
      };
    } else {
      const [firstName, ...lastNameParts] = booking.customerName.split(' ');
      contact.person = {
        firstName: firstName,
        lastName: lastNameParts.join(' '),
      };
    }

    const result = await this.createContact(contact);
    return result.id;
  }

  async createQuotationFromBooking(booking: any, contactId: string): Promise<string> {
    const quotation: LexOfficeQuotation = {
      voucherDate: new Date().toISOString().split('T')[0],
      address: {
        contactId: contactId,
        countryCode: 'DE',
      },
      lineItems: [
        {
          type: 'custom',
          name: 'Fotobox-Vermietung',
          description: `Event am ${new Date(booking.eventDate).toLocaleDateString('de-DE')} in ${booking.eventCity}`,
          quantity: 1,
          unitName: 'Stück',
          unitPrice: {
            currency: 'EUR',
            netAmount: booking.calculatedPrice || 0,
            taxRatePercentage: 19,
          },
        },
      ],
      totalPrice: {
        currency: 'EUR',
      },
      taxConditions: {
        taxType: 'net',
      },
      title: `Angebot Fotobox-Vermietung - ${booking.bookingNumber}`,
      introduction: 'Vielen Dank für Ihre Anfrage! Gerne erstellen wir Ihnen folgendes Angebot:',
      remark: 'Wir freuen uns auf Ihre Bestellung!',
    };

    const result = await this.createQuotation(quotation);
    return result.id;
  }

  async createConfirmationFromBooking(booking: any, contactId: string): Promise<string> {
    const invoice: LexOfficeInvoice = {
      voucherDate: new Date().toISOString().split('T')[0],
      address: {
        contactId: contactId,
        countryCode: 'DE',
      },
      lineItems: [
        {
          type: 'custom',
          name: 'Fotobox-Vermietung',
          description: `Event am ${new Date(booking.eventDate).toLocaleDateString('de-DE')} in ${booking.eventCity}\nAufbau: ${new Date(booking.setupTimeStart).toLocaleString('de-DE')}\nOrt: ${booking.eventAddress}, ${booking.eventZip} ${booking.eventCity}`,
          quantity: 1,
          unitName: 'Stück',
          unitPrice: {
            currency: 'EUR',
            netAmount: booking.calculatedPrice || 0,
            taxRatePercentage: 19,
          },
        },
      ],
      totalPrice: {
        currency: 'EUR',
      },
      taxConditions: {
        taxType: 'net',
      },
      title: `Auftragsbestätigung - ${booking.bookingNumber}`,
      introduction: 'Vielen Dank für Ihre Bestellung! Hiermit bestätigen wir Ihren Auftrag:',
      remark: 'Wir freuen uns auf Ihre Veranstaltung!',
      shippingConditions: {
        shippingDate: new Date(booking.eventDate).toISOString().split('T')[0],
        shippingType: 'service',
      },
      paymentConditions: {
        paymentTermLabel: 'Zahlung bei Lieferung',
        paymentTermDuration: 0,
      },
    };

    const result = await this.createInvoice(invoice);
    
    await this.finalizeInvoice(result.id);
    
    return result.id;
  }
}

export const lexofficeService = new LexOfficeService();
