import { getAuthToken } from "./auth-token";

export type HoroscopePeriod =
  | "daily"
  | "weekly"
  | "monthly"
  | "yearly";

export type HoroscopeEndpoint =
  | HoroscopePeriod
  | "daily-moon"
  | "daily-nakshatra"
  | "feedback";

/*
|--------------------------------------------------------------------------
| Date Helpers
|--------------------------------------------------------------------------
*/

export function formatDate(
  date: Date
): string {
  const year = date.getFullYear();

  const month = String(
    date.getMonth() + 1
  ).padStart(2, "0");

  const day = String(
    date.getDate()
  ).padStart(2, "0");

  return `${year}-${month}-${day}`;
}

export function getTodayDate(): string {
  return formatDate(new Date());
}

export function getTomorrowDate(): string {
  const date = new Date();

  date.setDate(
    date.getDate() + 1
  );

  return formatDate(date);
}

export function getYesterdayDate(): string {
  const date = new Date();

  date.setDate(
    date.getDate() - 1
  );

  return formatDate(date);
}

export function formatLongDate(
  date: Date
): string {
  return date.toLocaleDateString(
    "en-US",
    {
      weekday: "long",
      day: "numeric",
      month: "long",
      year: "numeric",
    }
  );
}

function formatDayMonth(date: Date): string {
  const day = String(date.getDate()).padStart(2, "0");

  const month = date.toLocaleDateString(
    "en-US",
    { month: "short" }
  );

  return `${day} ${month}`;
}

/** Sunday–Saturday range containing today. */
export function getThisWeekRange(): {
  start: Date;
  end: Date;
} {
  const today = new Date();

  const start = new Date(today);
  start.setDate(today.getDate() - today.getDay());

  const end = new Date(start);
  end.setDate(start.getDate() + 6);

  return { start, end };
}

export function formatWeekRange(
  start: Date,
  end: Date
): string {
  return `${formatDayMonth(start)} – ${formatDayMonth(end)} ${end.getFullYear()}`;
}

/*
|--------------------------------------------------------------------------
| Horoscope Request
|--------------------------------------------------------------------------
*/

export async function horoscopeRequest(
  endpoint: HoroscopeEndpoint,
  body: Record<string, any>
) {
  const token = getAuthToken();

  if (!token) {
    return {
      authenticated: false,
      success: false,
      data: null,
      message:
        "Please login first.",
    };
  }

  try {
    const response = await fetch(
      `/api/horoscope/${endpoint}`,
      {
        method: "POST",

        headers: {
          "Content-Type":
            "application/json",

          Accept: "application/json",

          Authorization:
            `Bearer ${token}`,
        },

        body: JSON.stringify(body),

        cache: "no-store",
      }
    );

    const result =
      await response.json();

    // console.log(
    //   "Horoscope response:",
    //   result
    // );

    if (response.status === 401) {
      return {
        authenticated: false,
        success: false,
        data: null,
        message:
          result?.message ||
          "Authentication expired.",
      };
    }

    if (
      !response.ok ||
      result?.status !== true
    ) {
      return {
        authenticated: true,
        success: false,
        data: null,
        message:
          result?.message ||
          "Horoscope request failed.",
      };
    }

    return {
      authenticated: true,
      success: true,
      data: result.data,
      message: result.message,
    };
  } catch (error) {
    console.error(
      "Horoscope request error:",
      error
    );

    return {
      authenticated: true,
      success: false,
      data: null,
      message:
        "Unable to connect to horoscope API.",
    };
  }
}

/*
|--------------------------------------------------------------------------
| Signs — GET /user/horoscope/signs, confirmed live to need no
| Authorization header at all (unlike every other horoscope endpoint
| below). Returns the 12 signs with a real image/svg_image per sign —
| no date-range field, so the local zodiacSigns table in app/lib/
| zodiac.ts still supplies id/slug/date-range/element; this just
| supplies the real image to merge in on top of it.
|--------------------------------------------------------------------------
*/

export interface HoroscopeSignApi {
  zodiac: number;
  sign_id: number;
  name: string;
  image: string;
  image_path: string;
  svg_image: string;
}

export async function getHoroscopeSigns() {
  try {
    const response = await fetch("/api/horoscope/signs", {
      method: "GET",
      headers: { Accept: "application/json" },
      cache: "no-store",
    });

    const result = await response.json();

    if (!response.ok || result?.status !== true) {
      return {
        success: false,
        data: [] as HoroscopeSignApi[],
        message: result?.message || "Unable to load zodiac signs.",
      };
    }

    return {
      success: true,
      data: (result.data ?? []) as HoroscopeSignApi[],
      message: result.message,
    };
  } catch (error) {
    console.error("Horoscope signs request error:", error);

    return {
      success: false,
      data: [] as HoroscopeSignApi[],
      message: "Unable to connect to horoscope API.",
    };
  }
}

/*
|--------------------------------------------------------------------------
| Daily
|--------------------------------------------------------------------------
*/

export async function getDailyHoroscope(
  zodiacId: number,
  date: string,
  lang: string = "en",
  options?: { type?: "big" | "small"; split?: boolean }
) {
  return horoscopeRequest(
    "daily",
    {
      zodiac: zodiacId,
      date: date,
      type: options?.type ?? "big",
      ...(options?.split !== undefined ? { split: options.split } : {}),
      lang,
    }
  );
}

/*
|--------------------------------------------------------------------------
| Daily Moon — same score/bot_response shape as daily, confirmed live
| (adds its own "zodiac" name field inside data.data).
|--------------------------------------------------------------------------
*/

export async function getDailyMoonHoroscope(
  zodiacId: number,
  date: string,
  lang: string = "en"
) {
  return horoscopeRequest(
    "daily-moon",
    {
      zodiac: zodiacId,
      date: date,
      lang,
    }
  );
}

/*
|--------------------------------------------------------------------------
| Daily Nakshatra — takes a nakshatra id (1-27), not a zodiac id.
| Confirmed live: same score/bot_response shape as daily, adds its own
| "nakshatra" name field inside data.data.
|--------------------------------------------------------------------------
*/

export async function getDailyNakshatraHoroscope(
  nakshatraId: number,
  date: string,
  lang: string = "en"
) {
  return horoscopeRequest(
    "daily-nakshatra",
    {
      nakshatra: nakshatraId,
      date: date,
      lang,
    }
  );
}

/*
|--------------------------------------------------------------------------
| Tomorrow
|--------------------------------------------------------------------------
*/

export async function getTomorrowHoroscope(
  zodiacId: number,
  lang: string = "en"
) {
  return getDailyHoroscope(
    zodiacId,
    getTomorrowDate(),
    lang
  );
}

/*
|--------------------------------------------------------------------------
| Yesterday
|--------------------------------------------------------------------------
*/

export async function getYesterdayHoroscope(
  zodiacId: number,
  lang: string = "en"
) {
  return getDailyHoroscope(
    zodiacId,
    getYesterdayDate(),
    lang
  );
}

/*
|--------------------------------------------------------------------------
| Weekly
|--------------------------------------------------------------------------
*/

export async function getWeeklyHoroscope(
  zodiacId: number,
  lang: string = "en"
) {
  return horoscopeRequest(
    "weekly",
    {
      zodiac: zodiacId,
      week: "thisweek",
      show_same: true,
      lang,
    }
  );
}

/*
|--------------------------------------------------------------------------
| Yearly
|--------------------------------------------------------------------------
*/

export async function getYearlyHoroscope(
  zodiacId: number,
  year: number,
  lang: string = "en"
) {
  return horoscopeRequest(
    "yearly",
    {
      zodiac: zodiacId,
      year: year,
      lang,
    }
  );
}

/*
|--------------------------------------------------------------------------
| Feedback — confirmed live: POST /user/horoscope/feedback returns
| {data: null, message: "Feedback submitted", status: true}. feedback
| text is optional (max 1000 chars per the spec); horoscope_type is the
| period this feedback is about ("daily"/"weekly"/"yearly" etc).
|--------------------------------------------------------------------------
*/

export type HoroscopeFeedbackType = "Great" | "Average" | "Poor";

export async function submitHoroscopeFeedback(params: {
  feedbacktype: HoroscopeFeedbackType;
  zodiac: number;
  horoscopeType: HoroscopePeriod | "daily-moon" | "daily-nakshatra";
  feedback?: string;
}) {
  return horoscopeRequest(
    "feedback",
    {
      feedbacktype: params.feedbacktype,
      zodiac: params.zodiac,
      horoscope_type: params.horoscopeType,
      ...(params.feedback ? { feedback: params.feedback.slice(0, 1000) } : {}),
    }
  );
}