'use server';

import { revalidatePath } from 'next/cache';
import { createClient } from '@/lib/auth/server';
import type { Database } from '@/lib/supabase/database.types';

export type Encounter = Database['public']['Tables']['encounters']['Row'];
export type RiskAssessment = Database['public']['Tables']['risk_assessments']['Row'];
export type Anamnese = Database['public']['Tables']['anamneses']['Row'];
export type Examination = Database['public']['Tables']['examinations']['Row'];
export type Condition = Database['public']['Tables']['conditions']['Row'];

export type KindcheckData = {
  hasChildren?: boolean;
  childCount?: number;
  ages?: string;
  concerns?: boolean;
  concernsNotes?: string;
  actionTaken?: boolean;
  actionNotes?: string;
  notes?: string;
};

function buildPath(patientId: string, intakeId: string, tab?: string) {
  const base = `/epd/patients/${patientId}/intakes/${intakeId}`;
  return tab ? `${base}/${tab}` : base;
}

async function getSupabase() {
  return createClient();
}

// ---------------- Contacts ----------------
export async function getContactMoments(intakeId: string) {
  const supabase = await getSupabase();
  const { data, error } = await supabase
    .from('encounters')
    .select('*')
    .eq('intake_id', intakeId)
    .order('period_start', { ascending: false });

  if (error) {
    console.error('getContactMoments error', error);
    throw new Error('Kon contactmomenten niet ophalen');
  }
  return data || [];
}

export interface ContactPayload {
  patientId: string;
  intakeId: string;
  date: string;
  startTime: string;
  endTime?: string;
  type: string;
  location?: string;
  notes?: string;
}

export async function createContactMoment(input: ContactPayload) {
  const supabase = await getSupabase();
  const startIso = new Date(`${input.date}T${input.startTime}:00`).toISOString();
  const endIso = input.endTime ? new Date(`${input.date}T${input.endTime}:00`).toISOString() : null;

  const { error } = await supabase.from('encounters').insert({
    patient_id: input.patientId,
    intake_id: input.intakeId,
    class_code: input.location || 'AMB',
    class_display: input.location || 'Onbekend',
    status: 'completed',
    type_code: input.type,
    type_display: input.type,
    period_start: startIso,
    period_end: endIso,
    notes: input.notes,
  });

  if (error) {
    console.error('createContactMoment error', error);
    throw new Error(error.message);
  }

  revalidatePath(buildPath(input.patientId, input.intakeId, 'contacts'));
  revalidatePath(buildPath(input.patientId, input.intakeId));
}

export async function deleteContactMoment(patientId: string, intakeId: string, encounterId: string) {
  const supabase = await getSupabase();
  const { error } = await supabase.from('encounters').delete().eq('id', encounterId);
  if (error) {
    console.error('deleteContactMoment error', error);
    throw new Error(error.message);
  }
  revalidatePath(buildPath(patientId, intakeId, 'contacts'));
  revalidatePath(buildPath(patientId, intakeId));
}

// ---------------- Kindcheck ----------------
export async function getKindcheck(intakeId: string): Promise<KindcheckData> {
  const supabase = await getSupabase();
  const { data, error } = await supabase
    .from('intakes')
    .select('kindcheck_data')
    .eq('id', intakeId)
    .maybeSingle();
  if (error) {
    console.error('getKindcheck error', error);
    throw new Error('Kon kindcheck niet ophalen');
  }
  return (data?.kindcheck_data as KindcheckData) || {};
}

export async function saveKindcheck(
  patientId: string,
  intakeId: string,
  payload: KindcheckData
) {
  const supabase = await getSupabase();
  const { error } = await supabase
    .from('intakes')
    .update({ kindcheck_data: payload })
    .eq('id', intakeId);
  if (error) {
    console.error('saveKindcheck error', error);
    throw new Error(error.message);
  }
  revalidatePath(buildPath(patientId, intakeId, 'kindcheck'));
  revalidatePath(buildPath(patientId, intakeId));
}

// ---------------- Risks ----------------
export async function getRiskAssessments(intakeId: string) {
  const supabase = await getSupabase();
  const { data, error } = await supabase
    .from('risk_assessments')
    .select('*')
    .eq('intake_id', intakeId)
    .order('assessment_date', { ascending: false });
  if (error) {
    console.error('getRiskAssessments error', error);
    throw new Error('Kon risicotaxaties niet ophalen');
  }
  return data || [];
}

export interface RiskPayload {
  patientId: string;
  intakeId: string;
  date: string;
  type: string;
  level: string;
  rationale: string;
  measures?: string;
  evaluationDate?: string;
  notes?: string;
}

export async function createRiskAssessment(payload: RiskPayload) {
  const supabase = await getSupabase();
  const { error } = await supabase.from('risk_assessments').insert({
    intake_id: payload.intakeId,
    assessment_date: payload.date,
    risk_type: payload.type,
    risk_level: payload.level,
    rationale: payload.rationale,
    measures: payload.measures,
    evaluation_date: payload.evaluationDate || null,
    notes: payload.notes,
  });
  if (error) {
    console.error('createRiskAssessment error', error);
    throw new Error(error.message);
  }
  revalidatePath(buildPath(payload.patientId, payload.intakeId, 'risk'));
  revalidatePath(buildPath(payload.patientId, payload.intakeId));
}

export async function deleteRiskAssessment(patientId: string, intakeId: string, riskId: string) {
  const supabase = await getSupabase();
  const { error } = await supabase.from('risk_assessments').delete().eq('id', riskId);
  if (error) {
    console.error('deleteRiskAssessment error', error);
    throw new Error(error.message);
  }
  revalidatePath(buildPath(patientId, intakeId, 'risk'));
  revalidatePath(buildPath(patientId, intakeId));
}

// ---------------- Anamneses ----------------
export async function getAnamneses(intakeId: string) {
  const supabase = await getSupabase();
  const { data, error } = await supabase
    .from('anamneses')
    .select('*')
    .eq('intake_id', intakeId)
    .order('anamnese_date', { ascending: false });
  if (error) {
    console.error('getAnamneses error', error);
    throw new Error('Kon anamneses niet ophalen');
  }
  return data || [];
}

export interface AnamnesePayload {
  patientId: string;
  intakeId: string;
  date: string;
  type: string;
  content: string;
  notes?: string;
}

export async function createAnamnese(payload: AnamnesePayload) {
  const supabase = await getSupabase();
  const { error } = await supabase.from('anamneses').insert({
    intake_id: payload.intakeId,
    anamnese_date: payload.date,
    anamnese_type: payload.type,
    content: payload.content,
    notes: payload.notes,
  });
  if (error) {
    console.error('createAnamnese error', error);
    throw new Error(error.message);
  }
  revalidatePath(buildPath(payload.patientId, payload.intakeId, 'anamnese'));
  revalidatePath(buildPath(payload.patientId, payload.intakeId));
}

export async function deleteAnamnese(patientId: string, intakeId: string, anamneseId: string) {
  const supabase = await getSupabase();
  const { error } = await supabase.from('anamneses').delete().eq('id', anamneseId);
  if (error) {
    console.error('deleteAnamnese error', error);
    throw new Error(error.message);
  }
  revalidatePath(buildPath(patientId, intakeId, 'anamnese'));
  revalidatePath(buildPath(patientId, intakeId));
}

// ---------------- Examinations (including ROM) ----------------
export async function getExaminations(intakeId: string) {
  const supabase = await getSupabase();
  const { data, error } = await supabase
    .from('examinations')
    .select('*')
    .eq('intake_id', intakeId)
    .order('examination_date', { ascending: false });
  if (error) {
    console.error('getExaminations error', error);
    throw new Error('Kon onderzoeken niet ophalen');
  }
  return data || [];
}

export interface ExaminationPayload {
  patientId: string;
  intakeId: string;
  date: string;
  type: string;
  findings: string;
  performer?: string;
  reason?: string;
  notes?: string;
  isRom?: boolean;
}

export async function createExamination(payload: ExaminationPayload) {
  const supabase = await getSupabase();
  const { error } = await supabase.from('examinations').insert({
    intake_id: payload.intakeId,
    examination_date: payload.date,
    examination_type: payload.isRom ? 'ROM' : payload.type,
    findings: payload.findings,
    performed_by: payload.performer,
    reason: payload.reason,
    notes: payload.notes,
  });
  if (error) {
    console.error('createExamination error', error);
    throw new Error(error.message);
  }
  const tab = payload.isRom ? 'rom' : 'examination';
  revalidatePath(buildPath(payload.patientId, payload.intakeId, tab));
  revalidatePath(buildPath(payload.patientId, payload.intakeId));
}

export async function deleteExamination(patientId: string, intakeId: string, examinationId: string) {
  const supabase = await getSupabase();
  const { error } = await supabase.from('examinations').delete().eq('id', examinationId);
  if (error) {
    console.error('deleteExamination error', error);
    throw new Error(error.message);
  }
  revalidatePath(buildPath(patientId, intakeId, 'examination'));
  revalidatePath(buildPath(patientId, intakeId, 'rom'));
  revalidatePath(buildPath(patientId, intakeId));
}

// ---------------- Diagnoses ----------------
export async function getDiagnoses(intakeId: string) {
  const supabase = await getSupabase();
  const { data, error } = await supabase
    .from('conditions')
    .select('*')
    .eq('encounter_id', intakeId)
    .order('recorded_date', { ascending: false });
  if (error) {
    console.error('getDiagnoses error', error);
    throw new Error('Kon diagnoses niet ophalen');
  }
  return data || [];
}

export interface DiagnosisPayload {
  patientId: string;
  intakeId: string;
  code: string;
  description: string;
  severity?: string;
  status?: string;
  notes?: string;
}

export async function createDiagnosis(payload: DiagnosisPayload) {
  const supabase = await getSupabase();
  const { error } = await supabase.from('conditions').insert({
    patient_id: payload.patientId,
    encounter_id: payload.intakeId,
    code_code: payload.code,
    code_display: payload.description,
    code_system: 'DSM-5',
    clinical_status: 'active',
    severity_display: payload.severity || null,
    note: payload.notes,
    recorded_date: new Date().toISOString(),
  });
  if (error) {
    console.error('createDiagnosis error', error);
    throw new Error(error.message);
  }
  revalidatePath(buildPath(payload.patientId, payload.intakeId, 'diagnosis'));
  revalidatePath(buildPath(payload.patientId, payload.intakeId));
}

export async function deleteDiagnosis(patientId: string, intakeId: string, diagnosisId: string) {
  const supabase = await getSupabase();
  const { error } = await supabase.from('conditions').delete().eq('id', diagnosisId);
  if (error) {
    console.error('deleteDiagnosis error', error);
    throw new Error(error.message);
  }
  revalidatePath(buildPath(patientId, intakeId, 'diagnosis'));
  revalidatePath(buildPath(patientId, intakeId));
}

// ---------------- Treatment Advice ----------------
export async function getTreatmentAdvice(intakeId: string) {
  const supabase = await getSupabase();
  const { data, error } = await supabase
    .from('intakes')
    .select('treatment_advice')
    .eq('id', intakeId)
    .maybeSingle();
  if (error) {
    console.error('getTreatmentAdvice error', error);
    throw new Error('Kon behandeladvies niet ophalen');
  }
  return (data?.treatment_advice as Record<string, any>) || {};
}

export interface TreatmentAdvicePayload {
  patientId: string;
  intakeId: string;
  advice: string;
  department?: string;
  program?: string;
  notes?: string;
  psychologist?: string;
  finalize?: boolean;
  outcome?: 'in_zorg' | 'doorverwijzing' | 'extra_diagnostiek';
  outcomeNotes?: string;
}

export async function saveTreatmentAdvice(payload: TreatmentAdvicePayload) {
  const supabase = await getSupabase();
  const updates: Record<string, unknown> = {
    treatment_advice: {
      advice: payload.advice,
      department: payload.department,
      program: payload.program,
      notes: payload.notes,
      psychologist: payload.psychologist,
      outcome: payload.outcome,
      outcomeNotes: payload.outcomeNotes,
      updatedAt: new Date().toISOString(),
    },
  };

  if (payload.finalize) {
    updates.status = 'afgerond';
    updates.end_date = new Date().toISOString().split('T')[0];
  }

  const { error } = await supabase
    .from('intakes')
    .update(updates)
    .eq('id', payload.intakeId);
  if (error) {
    console.error('saveTreatmentAdvice error', error);
    throw new Error(error.message);
  }
  revalidatePath(buildPath(payload.patientId, payload.intakeId, 'behandeladvies'));
  revalidatePath(buildPath(payload.patientId, payload.intakeId));
}
