import { createClient as createCustomClient } from '@supabase/supabase-js';

import axios from 'axios';
import { config } from 'dotenv';

async function syncData() {
  if (process.env.NODE_ENV === 'local') {
    config({ path: `.env.${process.env.NODE_ENV}` });
  }

  const isProd = process.env.NODE_ENV === 'production';

  const baseUrl = process.env.CONNECTED_ONLINE_URL;
  const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
  const supabaseServiceRoleKey =
    process.env.NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY;

  if (!baseUrl || !supabaseUrl || !supabaseServiceRoleKey) {
    throw new Error('Could not access all necessary environment variables');
  }

  const supabase = createCustomClient(supabaseUrl, supabaseServiceRoleKey, {
    auth: {
      persistSession: false,
      autoRefreshToken: false,
      detectSessionInUrl: false,
    },
  });

  try {
    const response = await axios.post(`${baseUrl}/Search_Load`, {
      headers: {
        'Content-Type': 'application/json; charset=utf-8',
      },
      param: "{'Value':'|et|-1'}", // get all available services in Estonian
    });

    const responseData: {
      Value: any;
      Data: any;
      ErrorCode: number;
      ErrorMessage: string;
    } = JSON.parse(response.data.d);

    if (responseData?.ErrorCode !== 0) {
      throw new Error('Failed to get Connected Online data');
    }

    if (
      !responseData.Data.T_Lic?.length ||
      !responseData.Data.T_Service?.length
    ) {
      return supabase.schema('audit').from('sync_entries').insert({
        operation: 'CONNECTED_ONLINE_SYNC',
        comment: 'No clinic or service data received',
        status: 'FAIL',
        changed_by_role: 'service_role',
      });
    }

    let clinics;
    let services;
    // Filter out "Dentas Demo OÜ" in prod or only sync "Dentas Demo OÜ" in any other environment
    if (isProd) {
      clinics = responseData.Data.T_Lic.filter((clinic) => clinic.ID !== 2);
      services = responseData.Data.T_Service.filter(
        (service) => service.ClinicID !== 2,
      );
    } else {
      clinics = responseData.Data.T_Lic.filter((clinic) => clinic.ID === 2);
      services = responseData.Data.T_Service.filter(
        (service) => service.ClinicID === 2,
      );
    }

    const mappedClinics = clinics.map((clinic) => {
      return {
        id: clinic.ID,
        can_select_worker: !!clinic.OnlineCanSelectWorker,
        email: clinic.Email || null,
        name: clinic.Name,
        personal_code_required: !!clinic.PersonalCodeRequired,
        phone_number: clinic.Phone || null,
      };
    });

    const mappedServices = services.map((service) => {
      return {
        id: service.ID,
        clinic_id: service.ClinicID,
        code: service.Code,
        description: service.Description || null,
        display: service.Display,
        duration: service.Duration,
        has_free_codes: !!service.HasFreeCodes,
        name: service.Name,
        neto_duration: service.NetoDuration,
        online_hide_duration: service.OnlineHideDuration,
        online_hide_price: service.OnlineHidePrice,
        price: service.Price,
        price_periods: service.PricePeriods || null,
        requires_payment: !!service.RequiresPayment,
        sync_id: service.SyncID,
      };
    });

    const { error: providersError } = await supabase
      .schema('medreport')
      .from('connected_online_providers')
      .upsert(mappedClinics);

    const { error: servicesError } = await supabase
      .schema('medreport')
      .from('connected_online_services')
      .upsert(mappedServices, { onConflict: 'id', ignoreDuplicates: false });

    if (providersError || servicesError) {
      return supabase
        .schema('audit')
        .from('sync_entries')
        .insert({
          operation: 'CONNECTED_ONLINE_SYNC',
          comment: providersError
            ? 'Error saving providers: ' + JSON.stringify(providersError)
            : 'Error saving services: ' + JSON.stringify(servicesError),
          status: 'FAIL',
          changed_by_role: 'service_role',
        });
    }

    await supabase.schema('audit').from('sync_entries').insert({
      operation: 'CONNECTED_ONLINE_SYNC',
      status: 'SUCCESS',
      changed_by_role: 'service_role',
    });
  } catch (e) {
    await supabase
      .schema('audit')
      .from('sync_entries')
      .insert({
        operation: 'CONNECTED_ONLINE_SYNC',
        status: 'FAIL',
        comment: JSON.stringify(e),
        changed_by_role: 'service_role',
      });
    throw new Error(
      `Failed to sync Connected Online data, error: ${JSON.stringify(e)}`,
    );
  }
}

syncData();
