'use server';

import { createClient } from '@/lib/auth/server';
import { revalidatePath } from 'next/cache';
import type { GeneratedPlan, SmartGoal, Intervention, Behandelstructuur, Behandeldoel } from '@/lib/types/behandelplan';
import { transformFromFlat } from '@/lib/types/behandelplan';
import type { LifeDomainScore } from '@/lib/types/leefgebieden';
import type { Json } from '@/lib/supabase/database.types';

/**
 * Get care plans for a patient
 */
export async function getCarePlans(patientId: string) {
  const supabase = await createClient();

  const { data, error } = await supabase
    .from('care_plans')
    .select('*')
    .eq('patient_id', patientId)
    .order('created_at', { ascending: false });

  if (error) {
    console.error('Error fetching care plans:', error);
    return [];
  }

  return data;
}

/**
 * Get the latest active care plan for a patient
 */
export async function getActiveCarePlan(patientId: string) {
  const supabase = await createClient();

  const { data, error } = await supabase
    .from('care_plans')
    .select('*')
    .eq('patient_id', patientId)
    .in('status', ['draft', 'active'])
    .order('version', { ascending: false })
    .limit(1)
    .single();

  if (error && error.code !== 'PGRST116') {
    console.error('Error fetching active care plan:', error);
  }

  return data;
}

/**
 * Get intakes for a patient (to select for plan generation)
 */
export async function getPatientIntakes(patientId: string) {
  const supabase = await createClient();

  const { data, error } = await supabase
    .from('intakes')
    .select('id, title, status, start_date, life_domains, notes')
    .eq('patient_id', patientId)
    .order('start_date', { ascending: false });

  if (error) {
    console.error('Error fetching intakes:', error);
    return [];
  }

  return data;
}

/**
 * Get conditions for a patient
 */
export async function getPatientConditions(patientId: string) {
  const supabase = await createClient();

  const { data, error } = await supabase
    .from('conditions')
    .select('id, category, code_display, severity_code, severity_display, recorded_date')
    .eq('patient_id', patientId)
    .order('recorded_date', { ascending: false });

  if (error) {
    console.error('Error fetching conditions:', error);
    return [];
  }

  return data;
}

/**
 * Create a new care plan from generated plan
 */
export async function createCarePlan(
  patientId: string,
  intakeId: string,
  generatedPlan: GeneratedPlan,
  title: string = 'Behandelplan'
) {
  const supabase = await createClient();

  // Get current version
  const { data: existing } = await supabase
    .from('care_plans')
    .select('version')
    .eq('patient_id', patientId)
    .order('version', { ascending: false })
    .limit(1)
    .single();

  const nextVersion = (existing?.version || 0) + 1;

  const { data, error } = await supabase
    .from('care_plans')
    .insert({
      patient_id: patientId,
      based_on_intake_id: intakeId,
      title: `${title} v${nextVersion}`,
      status: 'draft',
      intent: 'plan',
      version: nextVersion,
      goals: generatedPlan.doelen as unknown as Json,
      activities: generatedPlan.interventies as unknown as Json,
      behandelstructuur: generatedPlan.behandelstructuur as unknown as Json,
      evaluatiemomenten: generatedPlan.evaluatiemomenten as unknown as Json,
      sessie_planning: generatedPlan.sessiePlanning as unknown as Json,
      veiligheidsplan: (generatedPlan.veiligheidsplan || null) as unknown as Json,
      period_start: new Date().toISOString(),
    })
    .select()
    .single();

  if (error) {
    console.error('Error creating care plan:', error);
    throw new Error('Kon behandelplan niet opslaan');
  }

  revalidatePath(`/epd/patients/${patientId}/behandelplan`);
  return data;
}

/**
 * Update care plan status
 */
export async function updateCarePlanStatus(
  carePlanId: string,
  patientId: string,
  status: 'draft' | 'active' | 'on-hold' | 'completed' | 'revoked'
) {
  const supabase = await createClient();

  const updateData: Record<string, unknown> = { status };

  // Set published_at when activating
  if (status === 'active') {
    updateData.published_at = new Date().toISOString();
  }

  const { error } = await supabase
    .from('care_plans')
    .update(updateData)
    .eq('id', carePlanId);

  if (error) {
    console.error('Error updating care plan status:', error);
    throw new Error('Kon status niet bijwerken');
  }

  revalidatePath(`/epd/patients/${patientId}/behandelplan`);
}

/**
 * Update care plan goals
 */
export async function updateCarePlanGoals(
  carePlanId: string,
  patientId: string,
  goals: GeneratedPlan['doelen']
) {
  const supabase = await createClient();

  const { error } = await supabase
    .from('care_plans')
    .update({ goals: goals as unknown as Json })
    .eq('id', carePlanId);

  if (error) {
    console.error('Error updating goals:', error);
    throw new Error('Kon doelen niet bijwerken');
  }

  revalidatePath(`/epd/patients/${patientId}/behandelplan`);
}

/**
 * Save life domains to intake
 */
export async function saveLifeDomains(
  intakeId: string,
  patientId: string,
  lifeDomains: LifeDomainScore[]
) {
  const supabase = await createClient();

  const { error } = await supabase
    .from('intakes')
    .update({ life_domains: lifeDomains as unknown as Json })
    .eq('id', intakeId);

  if (error) {
    console.error('Error saving life domains:', error);
    throw new Error('Kon leefgebieden niet opslaan');
  }

  revalidatePath(`/epd/patients/${patientId}/behandelplan`);
}

/**
 * Delete a care plan
 */
export async function deleteCarePlan(carePlanId: string, patientId: string) {
  const supabase = await createClient();

  const { error } = await supabase
    .from('care_plans')
    .delete()
    .eq('id', carePlanId);

  if (error) {
    console.error('Error deleting care plan:', error);
    throw new Error('Kon behandelplan niet verwijderen');
  }

  revalidatePath(`/epd/patients/${patientId}/behandelplan`);
}

/**
 * Create a new empty/manual care plan
 */
export async function createEmptyCarePlan(
  patientId: string,
  intakeId?: string,
  title: string = 'Behandelplan'
) {
  const supabase = await createClient();

  // Get current version
  const { data: existing } = await supabase
    .from('care_plans')
    .select('version')
    .eq('patient_id', patientId)
    .order('version', { ascending: false })
    .limit(1)
    .single();

  const nextVersion = (existing?.version || 0) + 1;

  const { data, error } = await supabase
    .from('care_plans')
    .insert({
      patient_id: patientId,
      based_on_intake_id: intakeId || null,
      title: `${title} v${nextVersion}`,
      status: 'draft',
      intent: 'plan',
      version: nextVersion,
      goals: [],
      activities: [],
      period_start: new Date().toISOString(),
    })
    .select()
    .single();

  if (error) {
    console.error('Error creating empty care plan:', error);
    throw new Error('Kon behandelplan niet aanmaken');
  }

  revalidatePath(`/epd/patients/${patientId}/behandelplan`);
  return data;
}

// =============================================================================
// BEHANDELSTRUCTUUR
// =============================================================================

/**
 * Update behandelstructuur
 */
export async function updateBehandelstructuur(
  carePlanId: string,
  patientId: string,
  behandelstructuur: Behandelstructuur
) {
  const supabase = await createClient();

  const { error } = await supabase
    .from('care_plans')
    .update({ behandelstructuur: behandelstructuur as unknown as Json })
    .eq('id', carePlanId);

  if (error) {
    console.error('Error updating behandelstructuur:', error);
    throw new Error('Kon behandelstructuur niet bijwerken');
  }

  revalidatePath(`/epd/patients/${patientId}/behandelplan`);
}

// =============================================================================
// GOALS (DOELEN)
// =============================================================================

/**
 * Add a goal to a care plan
 */
export async function addGoal(
  carePlanId: string,
  patientId: string,
  goal: SmartGoal
) {
  const supabase = await createClient();

  // Get current goals
  const { data: plan } = await supabase
    .from('care_plans')
    .select('goals')
    .eq('id', carePlanId)
    .single();

  const currentGoals = (plan?.goals as unknown as SmartGoal[]) || [];
  const updatedGoals = [...currentGoals, goal];

  const { error } = await supabase
    .from('care_plans')
    .update({ goals: updatedGoals as unknown as Json })
    .eq('id', carePlanId);

  if (error) {
    console.error('Error adding goal:', error);
    throw new Error('Kon doel niet toevoegen');
  }

  revalidatePath(`/epd/patients/${patientId}/behandelplan`);
}

/**
 * Update a single goal in a care plan
 */
export async function updateGoal(
  carePlanId: string,
  patientId: string,
  goalId: string,
  updatedGoal: SmartGoal
) {
  const supabase = await createClient();

  // Get current goals
  const { data: plan } = await supabase
    .from('care_plans')
    .select('goals')
    .eq('id', carePlanId)
    .single();

  const currentGoals = (plan?.goals as unknown as SmartGoal[]) || [];
  const updatedGoals = currentGoals.map((g) =>
    g.id === goalId ? updatedGoal : g
  );

  const { error } = await supabase
    .from('care_plans')
    .update({ goals: updatedGoals as unknown as Json })
    .eq('id', carePlanId);

  if (error) {
    console.error('Error updating goal:', error);
    throw new Error('Kon doel niet bijwerken');
  }

  revalidatePath(`/epd/patients/${patientId}/behandelplan`);
}

/**
 * Delete a goal from a care plan
 */
export async function deleteGoal(
  carePlanId: string,
  patientId: string,
  goalId: string
) {
  const supabase = await createClient();

  // Get current goals
  const { data: plan } = await supabase
    .from('care_plans')
    .select('goals')
    .eq('id', carePlanId)
    .single();

  const currentGoals = (plan?.goals as unknown as SmartGoal[]) || [];
  const updatedGoals = currentGoals.filter((g) => g.id !== goalId);

  const { error } = await supabase
    .from('care_plans')
    .update({ goals: updatedGoals as unknown as Json })
    .eq('id', carePlanId);

  if (error) {
    console.error('Error deleting goal:', error);
    throw new Error('Kon doel niet verwijderen');
  }

  revalidatePath(`/epd/patients/${patientId}/behandelplan`);
}

// =============================================================================
// INTERVENTIONS (INTERVENTIES)
// =============================================================================

/**
 * Add an intervention to a care plan
 */
export async function addIntervention(
  carePlanId: string,
  patientId: string,
  intervention: Intervention
) {
  const supabase = await createClient();

  // Get current interventions
  const { data: plan } = await supabase
    .from('care_plans')
    .select('activities')
    .eq('id', carePlanId)
    .single();

  const currentInterventions = (plan?.activities as unknown as Intervention[]) || [];
  const updatedInterventions = [...currentInterventions, intervention];

  const { error } = await supabase
    .from('care_plans')
    .update({ activities: updatedInterventions as unknown as Json })
    .eq('id', carePlanId);

  if (error) {
    console.error('Error adding intervention:', error);
    throw new Error('Kon interventie niet toevoegen');
  }

  revalidatePath(`/epd/patients/${patientId}/behandelplan`);
}

/**
 * Update a single intervention in a care plan
 */
export async function updateIntervention(
  carePlanId: string,
  patientId: string,
  interventionId: string,
  updatedIntervention: Intervention
) {
  const supabase = await createClient();

  // Get current interventions
  const { data: plan } = await supabase
    .from('care_plans')
    .select('activities')
    .eq('id', carePlanId)
    .single();

  const currentInterventions = (plan?.activities as unknown as Intervention[]) || [];
  const updatedInterventions = currentInterventions.map((i) =>
    i.id === interventionId ? updatedIntervention : i
  );

  const { error } = await supabase
    .from('care_plans')
    .update({ activities: updatedInterventions as unknown as Json })
    .eq('id', carePlanId);

  if (error) {
    console.error('Error updating intervention:', error);
    throw new Error('Kon interventie niet bijwerken');
  }

  revalidatePath(`/epd/patients/${patientId}/behandelplan`);
}

/**
 * Delete an intervention from a care plan
 */
export async function deleteIntervention(
  carePlanId: string,
  patientId: string,
  interventionId: string
) {
  const supabase = await createClient();

  // Get current interventions
  const { data: plan } = await supabase
    .from('care_plans')
    .select('activities')
    .eq('id', carePlanId)
    .single();

  const currentInterventions = (plan?.activities as unknown as Intervention[]) || [];
  const updatedInterventions = currentInterventions.filter((i) => i.id !== interventionId);

  const { error } = await supabase
    .from('care_plans')
    .update({ activities: updatedInterventions as unknown as Json })
    .eq('id', carePlanId);

  if (error) {
    console.error('Error deleting intervention:', error);
    throw new Error('Kon interventie niet verwijderen');
  }

  revalidatePath(`/epd/patients/${patientId}/behandelplan`);
}

// =============================================================================
// BEHANDELDOEL (FLAT STRUCTURE - doel met embedded interventies)
// =============================================================================

/**
 * Save a behandeldoel (creates or updates)
 * Transforms flat structure to goals + activities for backwards compatibility
 */
export async function saveBehandeldoel(
  carePlanId: string,
  patientId: string,
  behandeldoel: Behandeldoel
) {
  const supabase = await createClient();

  // Get current plan
  const { data: plan } = await supabase
    .from('care_plans')
    .select('goals, activities')
    .eq('id', carePlanId)
    .single();

  const currentGoals = (plan?.goals as unknown as SmartGoal[]) || [];
  const currentActivities = (plan?.activities as unknown as Intervention[]) || [];

  // Check if this is an update or a new goal
  const existingGoalIndex = currentGoals.findIndex((g) => g.id === behandeldoel.id);

  // Convert behandeldoel to SmartGoal
  const smartGoal: SmartGoal = {
    id: behandeldoel.id,
    title: behandeldoel.title,
    description: '', // Not used in flat structure
    clientVersion: behandeldoel.clientVersion,
    lifeDomain: behandeldoel.lifeDomain,
    priority: 'middel', // Default
    measurability: '', // Not used in flat structure
    timelineWeeks: behandeldoel.endWeek,
    status: behandeldoel.status,
    progress: behandeldoel.progress,
  };

  // Update goals array
  let updatedGoals: SmartGoal[];
  if (existingGoalIndex >= 0) {
    updatedGoals = currentGoals.map((g, i) =>
      i === existingGoalIndex ? smartGoal : g
    );
  } else {
    updatedGoals = [...currentGoals, smartGoal];
  }

  // Handle interventions: remove old ones for this goal and add new ones
  const otherActivities = currentActivities.filter(
    (a) => !a.linkedGoalIds.includes(behandeldoel.id)
  );

  const newActivities: Intervention[] = behandeldoel.interventies.map((int) => ({
    id: int.id,
    name: int.name,
    description: int.description,
    rationale: '', // Not used in flat structure
    linkedGoalIds: [behandeldoel.id],
  }));

  const updatedActivities = [...otherActivities, ...newActivities];

  // Save to database
  const { error } = await supabase
    .from('care_plans')
    .update({
      goals: updatedGoals as unknown as Json,
      activities: updatedActivities as unknown as Json,
    })
    .eq('id', carePlanId);

  if (error) {
    console.error('Error saving behandeldoel:', error);
    throw new Error('Kon behandeldoel niet opslaan');
  }

  revalidatePath(`/epd/patients/${patientId}/behandelplan`);
}

/**
 * Delete a behandeldoel and its linked interventions
 */
export async function deleteBehandeldoel(
  carePlanId: string,
  patientId: string,
  doelId: string
) {
  const supabase = await createClient();

  // Get current plan
  const { data: plan } = await supabase
    .from('care_plans')
    .select('goals, activities')
    .eq('id', carePlanId)
    .single();

  const currentGoals = (plan?.goals as unknown as SmartGoal[]) || [];
  const currentActivities = (plan?.activities as unknown as Intervention[]) || [];

  // Remove the goal
  const updatedGoals = currentGoals.filter((g) => g.id !== doelId);

  // Remove interventions linked to this goal
  const updatedActivities = currentActivities.filter(
    (a) => !a.linkedGoalIds.includes(doelId)
  );

  // Save to database
  const { error } = await supabase
    .from('care_plans')
    .update({
      goals: updatedGoals as unknown as Json,
      activities: updatedActivities as unknown as Json,
    })
    .eq('id', carePlanId);

  if (error) {
    console.error('Error deleting behandeldoel:', error);
    throw new Error('Kon behandeldoel niet verwijderen');
  }

  revalidatePath(`/epd/patients/${patientId}/behandelplan`);
}
