import { createClient } from "@supabase/supabase-js";

const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;

export const supabase = createClient(supabaseUrl, supabaseAnonKey);

/** Common headers for Edge Function calls (includes JWT auth) */
const fnHeaders = () => ({
  "Content-Type": "application/json",
  "Authorization": `Bearer ${supabaseAnonKey}`,
});

export async function generateMarketingReport(url: string, clinicName?: string) {
  const response = await fetch(
    `${supabaseUrl}/functions/v1/generate-report`,
    {
      method: "POST",
      headers: fnHeaders(),
      body: JSON.stringify({ url, clinicName }),
    }
  );

  if (!response.ok) {
    throw new Error(`Report generation failed: ${response.statusText}`);
  }

  return response.json();
}

export async function fetchReportById(reportId: string) {
  const { data, error } = await supabase
    .from("marketing_reports")
    .select("*")
    .eq("id", reportId)
    .single();

  if (error) throw new Error(`Failed to fetch report: ${error.message}`);
  return data;
}

/**
 * Fetch pipeline status for a report.
 * Used by AnalysisLoadingPage to resume interrupted pipelines.
 */
export interface PipelineStatus {
  reportId: string;
  clinicId?: string;
  runId?: string;
  status: string;
  clinicName?: string;
  hasChannelData: boolean;
  hasReport: boolean;
}

export async function fetchPipelineStatus(reportId: string): Promise<PipelineStatus> {
  const { data, error } = await supabase
    .from("marketing_reports")
    .select("id, status, clinic_name, channel_data, report")
    .eq("id", reportId)
    .single();

  if (error || !data) throw new Error(`Report not found: ${error?.message}`);

  return {
    reportId: data.id,
    status: data.status || "unknown",
    clinicName: data.clinic_name,
    hasChannelData: !!data.channel_data && Object.keys(data.channel_data).length > 0,
    hasReport: !!data.report && Object.keys(data.report).length > 0,
  };
}

export interface EnrichChannelsRequest {
  reportId: string;
  clinicName: string;
  instagramHandle?: string;
  instagramHandles?: string[];
  youtubeChannelId?: string;
  facebookHandle?: string;
  address?: string;
}

/**
 * Fire-and-forget: triggers background channel enrichment.
 * Returns enrichment result when the Edge Function completes (~27s).
 */
export async function enrichChannels(params: EnrichChannelsRequest) {
  const response = await fetch(
    `${supabaseUrl}/functions/v1/enrich-channels`,
    {
      method: "POST",
      headers: fnHeaders(),
      body: JSON.stringify(params),
    }
  );

  if (!response.ok) {
    throw new Error(`Channel enrichment failed: ${response.statusText}`);
  }

  return response.json();
}

export async function scrapeWebsite(url: string, clinicName?: string) {
  const response = await fetch(
    `${supabaseUrl}/functions/v1/scrape-website`,
    {
      method: "POST",
      headers: fnHeaders(),
      body: JSON.stringify({ url, clinicName }),
    }
  );

  if (!response.ok) {
    throw new Error(`Scraping failed: ${response.statusText}`);
  }

  return response.json();
}

// ─── Pipeline V2 API Functions ───

/**
 * Phase 1: Discover & verify social channels from website URL.
 * Returns verified handles + reportId for subsequent phases.
 */
export async function discoverChannels(url: string, clinicName?: string) {
  const response = await fetch(
    `${supabaseUrl}/functions/v1/discover-channels`,
    {
      method: "POST",
      headers: fnHeaders(),
      body: JSON.stringify({ url, clinicName }),
    }
  );

  const data = await response.json();

  if (!response.ok) {
    const err = new Error(data.error || `Channel discovery failed: ${response.statusText}`);
    (err as Error & { code?: string; domain?: string }).code = data.error;
    (err as Error & { code?: string; domain?: string }).domain = data.domain;
    throw err;
  }

  return data;
}

/**
 * Phase 2: Collect all channel data using verified handles.
 * Reads verified_channels from DB, runs parallel API calls.
 */
export async function collectChannelData(reportId: string, clinicId?: string, runId?: string) {
  const response = await fetch(
    `${supabaseUrl}/functions/v1/collect-channel-data`,
    {
      method: "POST",
      headers: fnHeaders(),
      body: JSON.stringify({ reportId, clinicId, runId }),
    }
  );

  if (!response.ok) {
    throw new Error(`Data collection failed: ${response.statusText}`);
  }

  return response.json();
}

/**
 * Phase 3: Generate AI report using real collected data from DB.
 */
export async function generateReportV2(reportId: string, clinicId?: string, runId?: string) {
  const response = await fetch(
    `${supabaseUrl}/functions/v1/generate-report`,
    {
      method: "POST",
      headers: fnHeaders(),
      body: JSON.stringify({ reportId, clinicId, runId }),
    }
  );

  if (!response.ok) {
    throw new Error(`Report generation failed: ${response.statusText}`);
  }

  return response.json();
}

// ─── Pipeline V2 Phase 4: Content Plan ───

/**
 * Phase 4: Generate AI content strategy and calendar.
 * Reads report data from DB, calls Perplexity for strategy generation,
 * stores result in content_plans table.
 */
export async function generateContentPlan(reportId: string, clinicId?: string, runId?: string) {
  const response = await fetch(
    `${supabaseUrl}/functions/v1/generate-content-plan`,
    {
      method: "POST",
      headers: fnHeaders(),
      body: JSON.stringify({ reportId, clinicId, runId }),
    }
  );

  if (!response.ok) {
    throw new Error(`Content plan generation failed: ${response.statusText}`);
  }

  return response.json();
}

/**
 * Fetch the active content plan for a clinic.
 * Returns the most recent is_active=true plan with all JSONB columns.
 */
export async function fetchActiveContentPlan(clinicId: string) {
  const { data, error } = await supabase
    .from("content_plans")
    .select("*")
    .eq("clinic_id", clinicId)
    .eq("is_active", true)
    .order("created_at", { ascending: false })
    .limit(1)
    .single();

  if (error) return null;
  return data;
}

/**
 * Update a single calendar entry within a content plan's JSONB.
 * Uses Postgres JSONB path update.
 */
export async function updateCalendarEntry(
  planId: string,
  entryId: string,
  updates: Record<string, unknown>,
) {
  // Read current calendar
  const { data: plan, error: readErr } = await supabase
    .from("content_plans")
    .select("calendar")
    .eq("id", planId)
    .single();

  if (readErr || !plan) throw new Error(`Plan not found: ${readErr?.message}`);

  const calendar = plan.calendar as { weeks: { entries: Record<string, unknown>[] }[] };

  // Find and update entry
  for (const week of calendar.weeks) {
    for (let i = 0; i < week.entries.length; i++) {
      if (week.entries[i].id === entryId) {
        week.entries[i] = { ...week.entries[i], ...updates, isManualEdit: true };
        break;
      }
    }
  }

  const { error: writeErr } = await supabase
    .from("content_plans")
    .update({ calendar })
    .eq("id", planId);

  if (writeErr) throw new Error(`Update failed: ${writeErr.message}`);
}

/**
 * Trigger strategy adjustment for a clinic.
 * Compares current vs previous channel_snapshots, generates AI recommendations.
 */
export async function triggerStrategyAdjustment(clinicId: string) {
  const response = await fetch(
    `${supabaseUrl}/functions/v1/adjust-strategy`,
    {
      method: "POST",
      headers: fnHeaders(),
      body: JSON.stringify({ clinicId }),
    }
  );

  if (!response.ok) {
    throw new Error(`Strategy adjustment failed: ${response.statusText}`);
  }

  return response.json();
}
