import type { Tables } from '@/packages/supabase/src/database.types';

import { getSupabaseServerAdminClient } from '@kit/supabase/server-admin-client';
import { getSupabaseServerClient } from '@kit/supabase/server-client';

import { AccountSettings } from '~/home/(user)/settings/_lib/account-settings.schema';

import { AccountPreferences } from '../../app/home/(user)/settings/_lib/account-preferences.schema';
import { updateCustomer } from '../../packages/features/medusa-storefront/src/lib/data';

type Account = Tables<{ schema: 'medreport' }, 'accounts'>;
type Membership = Tables<{ schema: 'medreport' }, 'accounts_memberships'>;

export type AccountWithMemberships = Account & { memberships: Membership[] };

export async function getAccount(id: string): Promise<AccountWithMemberships> {
  const { data } = await getSupabaseServerClient()
    .schema('medreport')
    .from('accounts')
    .select('*, memberships: accounts_memberships (*)')
    .eq('id', id)
    .single()
    .throwOnError();

  return data as unknown as AccountWithMemberships;
}

export async function getUserContactAdmin(userId: string) {
  const { data } = await getSupabaseServerAdminClient()
    .schema('medreport')
    .from('accounts')
    .select('name, last_name, email, preferred_locale')
    .eq('primary_owner_user_id', userId)
    .eq('is_personal_account', true)
    .single()
    .throwOnError();

  return data;
}

export async function getAccountAdmin({
  primaryOwnerUserId,
}: {
  primaryOwnerUserId: string;
}): Promise<AccountWithMemberships> {
  const query = getSupabaseServerAdminClient()
    .schema('medreport')
    .from('accounts')
    .select('*, memberships: accounts_memberships (*)')
    .eq('is_personal_account', true);

  if (primaryOwnerUserId) {
    query.eq('primary_owner_user_id', primaryOwnerUserId);
  } else {
    throw new Error('primaryOwnerUserId is required');
  }

  const { data } = await query.single().throwOnError();

  return data as unknown as AccountWithMemberships;
}

export async function getDoctorAccounts() {
  const { data } = await getSupabaseServerAdminClient()
    .schema('medreport')
    .from('accounts')
    .select('id, email, name, last_name, preferred_locale')
    .eq('is_personal_account', true)
    .eq('application_role', 'doctor')
    .throwOnError();

  return data?.map(({ id, email, name, last_name, preferred_locale }) => ({
    id,
    email,
    name,
    lastName: last_name,
    preferredLocale: preferred_locale,
  }));
}

export async function getAssignedDoctorAccount(analysisOrderId: number) {
  const supabase = getSupabaseServerAdminClient();

  const { data: doctorUser } = await supabase
    .schema('medreport')
    .from('doctor_analysis_feedback')
    .select('doctor_user_id')
    .eq('analysis_order_id', analysisOrderId)
    .throwOnError();

  const doctorData = doctorUser[0];
  if (!doctorData || !doctorData.doctor_user_id) {
    return null;
  }

  const { data } = await supabase
    .schema('medreport')
    .from('accounts')
    .select('email')
    .eq('primary_owner_user_id', doctorData.doctor_user_id);

  return { email: data?.[0]?.email };
}

export async function updatePersonalAccount(
  accountId: string,
  account: AccountSettings,
) {
  const supabase = getSupabaseServerClient();

  return Promise.all([
    supabase
      .schema('medreport')
      .from('accounts')
      .update({
        name: account.firstName,
        last_name: account.lastName,
        email: account.email,
        phone: account.phone,
      })
      .eq('id', accountId)
      .throwOnError(),
    supabase
      .schema('medreport')
      .from('account_params')
      .upsert(
        {
          height: account.accountParams.height,
          weight: account.accountParams.weight,
          is_smoker: account.accountParams.isSmoker,
        },
        { onConflict: 'account_id' },
      )
      .throwOnError(),
    updateCustomer({
      first_name: account.firstName,
      last_name: account.lastName,
      phone: account.phone,
    }),
  ]);
}
export async function updatePersonalAccountPreferences(
  accountId: string,
  preferences: AccountPreferences,
) {
  const supabase = getSupabaseServerClient();

  return supabase
    .schema('medreport')
    .from('accounts')
    .update({
      preferred_locale: preferences.preferredLanguage,
      has_consent_anonymized_company_statistics:
        preferences.isConsentToAnonymizedCompanyStatistics,
    })
    .eq('id', accountId)
    .throwOnError();
}
