import type { AutoLeadNotification, ConfiguredCampaign, RotationRow, SalesTeamRotationResponse, SmsCampaign, SmsPoolRow, SmsTemplate } from './interface';
import { getCities } from '@/app/cities/service';
import axiosInstance from '@/utills/axiosInstance';

export interface ActiveCity {
  id: number;
  name: string;
}

/* Real API — same active-cities endpoint used by MasterCities.tsx elsewhere in the app. */
export async function getActiveCities(): Promise<ActiveCity[]> {
  const res = await getCities({ is_default: true, sortColumn: 'name', sortOrder: 'asc' });
  return (res?.data?.data || []).map((c: { id: string | number; name: string }) => ({
    id: Number(c.id),
    name: c.name,
  }));
}

/* Which backend a rotation belongs to — picks the /facebook-campaigns or /google-campaigns API. */
export type RotationSource = 'facebook' | 'google';

const campaignApi = (source: RotationSource): string => `/api/v1/${source}-campaigns`;

/*
  Real backend API — GET /api/v1/{facebook|google}-campaigns (see the
  autoLeadAssignment / autoLeadAssignmentGoogle campaign controllers). Returns
  the raw axios response — callers read the actual body at res.data.
 */
export async function getCampaigns(source: RotationSource, params: { page?: number; pageSize?: number; search?: string }): Promise<any> {
  return axiosInstance.get(campaignApi(source), { params });
}

export interface ConfiguredCampaignsResult {
  data: ConfiguredCampaign[];
  total: number;
  page: number;
  pageSize: number;
}

/*
  Real backend API — GET /api/v1/facebook-campaigns/configured. One row per
  distinct campaign/city combination that already has a saved rotation in
  auto_lead_round_robin — this is what the Campaigns list page shows.
  Filtering (source/city/search) and pagination are both applied server-side.
 */
export async function getConfiguredCampaigns(params: {
  page?: number;
  pageSize?: number;
  source?: string;
  city_id?: number;
  search?: string;
}): Promise<ConfiguredCampaignsResult> {
  const res = await axiosInstance.get('/api/v1/facebook-campaigns/configured', { params });
  const body = res?.data || {};
  const rows = body.data || [];
  return {
    data: rows.map((r: any) => ({
      campaign_id: r.campaign_id,
      name: r.campaign_name,
      source: r.source,
      city_id: r.city_id,
      city_name: r.city_name,
      is_active: r.is_active === undefined ? true : !!r.is_active,
    })),
    total: body.total ?? rows.length,
    page: body.page ?? params.page ?? 1,
    pageSize: body.pageSize ?? params.pageSize ?? 5,
  };
}

/*
  Real backend API — GET /api/v1/auto-lead-assignment/notifications. Unread
  duplicate-lead notifications for the logged-in sales person; polled by
  DuplicateLeadNotifier the same way the existing follow-up reminder is.
 */
export async function getAutoLeadNotifications(): Promise<AutoLeadNotification[]> {
  const res = await axiosInstance.get('/api/v1/auto-lead-assignment/notifications');
  return res?.data?.data || [];
}

/* Real backend API — POST /api/v1/auto-lead-assignment/notifications/{id}/read. */
export async function markAutoLeadNotificationRead(id: number): Promise<any> {
  return axiosInstance.post(`/api/v1/auto-lead-assignment/notifications/${id}/read`);
}

/*
  Real backend API — GET /api/v1/{facebook|google}-campaigns/{campaignId}. Reads
  from the local cache table, no live Graph/Google Ads call, so it works for the
  edit/view screens even if the campaign is no longer active.
 */
export async function getCampaignById(source: RotationSource, campaignId: string): Promise<any> {
  return axiosInstance.get(`${campaignApi(source)}/${campaignId}`);
}

/* What a rotation is tied to under a campaign: a lead form (Facebook) or a microsite URL (Google). */
export interface FormOption {
  key: string;
  label: string;
}

/*
  Real backend API — GET /api/v1/facebook-campaigns/{campaignId}/forms, or
  /api/v1/google-campaigns/{campaignId}/microsites. Same shape for both sources.
 */
export async function getCampaignForms(source: RotationSource, campaignId: string): Promise<FormOption[]> {
  if (source === 'google') {
    const res = await axiosInstance.get(`${campaignApi(source)}/${campaignId}/microsites`);
    return (res?.data?.data || []).map((m: { microsite_url: string }) => ({ key: m.microsite_url, label: m.microsite_url }));
  }
  const res = await axiosInstance.get(`${campaignApi(source)}/${campaignId}/forms`);
  return (res?.data?.data || []).map((f: { form_id: string; name: string }) => ({ key: f.form_id, label: f.name }));
}

export interface CampaignLaunchMappingRow {
  /** False when the campaign's saved rotation is inactive (the campaign can then be used for a new rotation). */
  rotation_active: boolean;
  form_key: string;
  city_id: number;
  launch_id: number;
  launch_name: string;
}

/*
  Real backend API — GET /api/v1/{facebook|google}-campaigns/{campaignId}/launch-mapping.
  What the incoming-lead webhook reads to know which launch(es) a campaign+form
  (or microsite) routes a lead to. Used to restore the saved form/launch
  selection on the edit/view screens.
 */
export async function getCampaignLaunchMapping(source: RotationSource, campaignId: string): Promise<CampaignLaunchMappingRow[]> {
  const res = await axiosInstance.get(`${campaignApi(source)}/${campaignId}/launch-mapping`);
  return (res?.data?.data || []).map((r: any) => ({
    rotation_active: r.rotation_active !== false,
    form_key: source === 'google' ? r.microsite_url : r.form_id,
    city_id: r.city_id,
    launch_id: r.launch_id,
    launch_name: r.launch_name,
  }));
}

/*
  Real backend API — GET /api/v1/facebook-campaigns/cities/{cityId}/launches.
  Paginated (10 per page by default) — a city can have hundreds of launches,
  so LaunchMultiSelect loads them incrementally via scroll.
 */
export async function getLaunchesByCity(
  cityId: number,
  params: { page?: number; pageSize?: number; search?: string } = {}
): Promise<any> {
  return axiosInstance.get(`/api/v1/facebook-campaigns/cities/${cityId}/launches`, { params });
}

/*
  Real backend API — GET /api/v1/{facebook|google}-campaigns/launches/{launchId}/roster.
  The active members of the launch's team (launch_sales), already de-duplicated
  and filtered on the backend (users.status = 'active') — this is the roster a
  new rotation gets seeded from before anything's been saved for it. Both
  sources return the same thing; `source` only picks which namespace to call.
 */
export async function getLaunchSalesRoster(launchId: number, source: RotationSource): Promise<RotationRow[]> {
  const res = await axiosInstance.get(`${campaignApi(source)}/launches/${launchId}/roster`);
  const members: Array<{ user_id: number; name: string; role: RotationRow['role'] }> = res?.data?.data || [];

  return members.map((m) => ({ user_id: m.user_id, name: m.name, role: m.role, leads_per_round: 1 }));
}

/*
  Real backend API — PATCH /api/v1/{facebook|google}-campaigns/{campaignId}/rotation-status.
  Switches a campaign's rotation on or off; while off it takes no new leads.
 */
export async function setRotationActive(source: RotationSource, campaignId: string, isActive: boolean): Promise<any> {
  return axiosInstance.patch(`${campaignApi(source)}/${campaignId}/rotation-status`, { is_active: isActive });
}

/*
  Real backend API — GET /api/v1/{facebook|google}-campaigns/launches/{launchId}/sales-team.
  The saved rotation of this launch under ONE campaign + form (or microsite) —
  the same launch can hold a different rotation in every campaign. Reshaped from
  the flat `auto_lead_round_robin` rows into the SalesTeamRotationResponse shape
  RotationList expects. Returns an empty rotation if nothing is saved yet.
 */
export async function getRotationSalesTeam(
  source: RotationSource,
  launchId: number | string,
  campaignId: string,
  formKey: string
): Promise<any> {
  const res = await axiosInstance.get(`${campaignApi(source)}/launches/${launchId}/sales-team`, {
    params: source === 'google' ? { campaign_id: campaignId, microsite_url: formKey } : { campaign_id: campaignId, form_id: formKey },
  });
  const body = res?.data || {};
  const salesTeam: Array<{
    seller_id: number;
    seller_name: string;
    role: string;
    lead_priority: number;
    no_of_lead: number;
    assigned_count: number;
  }> = body.sales_team || [];

  const response: SalesTeamRotationResponse = {
    launch_id: String(launchId),
    sales_team: salesTeam.map((s) => ({
      field_sales_id: s.seller_id,
      field_sales_name: s.seller_name,
      field_sales_leads: s.no_of_lead,
    })),
    rotation: {
      cycle: salesTeam.length ? 1 : 0,
      cycle_status: salesTeam.length ? 'in-progress' : 'not-started',
      target: salesTeam.map((s) => ({ user_id: s.seller_id, role: s.role as any, lead: s.no_of_lead, assigned: s.assigned_count })),
    },
    next_up: body.next_up ? { user_id: body.next_up.seller_id, role: body.next_up.role } : null,
  };

  return { success: true, ...response };
}

/*
  Real backend API — POST /api/v1/{facebook|google}-campaigns/launches/sales-team/bulk.
  Saves the campaign/form (or microsite)→launch mapping AND every listed
  launch's rotation in one request, one transaction. Only this campaign + form's
  rotation is replaced; other campaigns using the same launches are untouched.
 */
export async function saveRotation(
  source: RotationSource,
  data: {
    campaign_id: string;
    campaign_name?: string;
    form_key: string;
    city_id: number;
    /** True when creating a rotation — the backend refuses it if the campaign already has one. */
    is_new: boolean;
    launches: Array<{
      launch_id: number;
      sales_team: Array<{ user_id: number; role: string; leads_per_round: number }>;
    }>;
  }
): Promise<any> {
  const { form_key, ...rest } = data;
  const body = source === 'google' ? { ...rest, microsite_url: form_key } : { ...rest, source: 'Facebook', form_id: form_key };
  return axiosInstance.post(`${campaignApi(source)}/launches/sales-team/bulk`, body);
}

/* ============================================================
 * SMS lead source
 * An SMS rotation has no ad-platform campaign — the project itself plays
 * that role, and the sales-team pool is derived (not configured) from the
 * project's own seller list. See helpers/autoLeadAssignment/housieyCampaign.helper.js
 * and controller/api/v1/autoLeadAssignmentSms/smsCampaign.controller.js.
 * ============================================================ */

/*
  Real backend API — GET /api/v1/sms-campaigns/projects. Paginated active
  projects for the "Project" dropdown, filtered by city and an optional name
  search — same page/pageSize/search contract as getLaunchesByCity.
 */
export async function getProjects(params: { city_id?: number; search?: string; page?: number; pageSize?: number }): Promise<any> {
  return axiosInstance.get('/api/v1/sms-campaigns/projects', { params });
}

/*
  Real backend API — GET /api/v1/sms-campaigns/projects/{projectId}/template.
  The saved template if one exists, else the default pattern resolved for
  this project, either way with the char/segment count a bulk-SMS gateway
  would actually bill.
 */
export async function getSmsTemplate(projectId: number): Promise<SmsTemplate> {
  const res = await axiosInstance.get(`/api/v1/sms-campaigns/projects/${projectId}/template`);
  return res?.data?.data;
}

export interface SmsRotationPreviewResult {
  data: SmsPoolRow[];
  total_sellers: number;
  eligible_count: number;
  empty_reason: string | null;
}

/*
  Real backend API — GET /api/v1/sms-campaigns/projects/{projectId}/rotation-preview.
  Read-only: the seller pool this project's SMS leads will rotate across right
  now. Nothing here is configurable from this screen — it's derived from
  projects.seller_id, the same way an incoming lead derives it.
 */
export async function getSmsRotationPreview(projectId: number): Promise<SmsRotationPreviewResult> {
  const res = await axiosInstance.get(`/api/v1/sms-campaigns/projects/${projectId}/rotation-preview`);
  const body = res?.data || {};
  return { data: body.data || [], total_sellers: body.total_sellers || 0, eligible_count: body.eligible_count || 0, empty_reason: body.empty_reason ?? null };
}

/*
  Real backend API — POST /api/v1/sms-campaigns. Creates or updates the
  project's SMS campaign row (template + name) and re-syncs its derived
  seller pool in the same call.
 */
export async function saveSmsCampaign(data: { project_id: number; city_id?: number; campaign_name: string; template: string }): Promise<any> {
  return axiosInstance.post('/api/v1/sms-campaigns', data);
}

export interface SmsConfiguredResult {
  data: SmsCampaign[];
  total: number;
  page: number;
  pageSize: number;
}

/* Real backend API — GET /api/v1/sms-campaigns/configured. Used by the SMS edit/view screens; the Rotations list itself gets SMS rows from the unioned /facebook-campaigns/configured. */
export async function getConfiguredSmsCampaigns(params: { page?: number; pageSize?: number; city_id?: number; search?: string }): Promise<SmsConfiguredResult> {
  const res = await axiosInstance.get('/api/v1/sms-campaigns/configured', { params });
  const body = res?.data || {};
  return { data: body.data || [], total: body.total ?? 0, page: body.page ?? params.page ?? 1, pageSize: body.pageSize ?? params.pageSize ?? 5 };
}

/* Real backend API — GET /api/v1/sms-campaigns/{projectId}. For the edit/view screens. */
export async function getSmsCampaignById(projectId: string | number): Promise<SmsCampaign | null> {
  const res = await axiosInstance.get(`/api/v1/sms-campaigns/${projectId}`);
  return res?.data?.data || null;
}

/* Real backend API — PATCH /api/v1/sms-campaigns/{projectId}/rotation-status. */
export async function setSmsRotationActive(projectId: string | number, isActive: boolean): Promise<any> {
  return axiosInstance.patch(`/api/v1/sms-campaigns/${projectId}/rotation-status`, { is_active: isActive });
}
