import type { messagingApi } from "@line/bot-sdk";
import {
  datetimePickerAction,
  messageAction,
  postbackAction,
  uriAction,
  type Action,
} from "./actions.js";

export { datetimePickerAction, messageAction, postbackAction, uriAction };

type TemplateMessage = messagingApi.TemplateMessage;
type ConfirmTemplate = messagingApi.ConfirmTemplate;
type ButtonsTemplate = messagingApi.ButtonsTemplate;
type CarouselTemplate = messagingApi.CarouselTemplate;
type CarouselColumn = messagingApi.CarouselColumn;
type ImageCarouselTemplate = messagingApi.ImageCarouselTemplate;
type ImageCarouselColumn = messagingApi.ImageCarouselColumn;

type TemplatePayloadAction = {
  type?: "uri" | "postback" | "message";
  uri?: string;
  data?: string;
  label: string;
};

function buildTemplatePayloadAction(action: TemplatePayloadAction): Action {
  if (action.type === "uri" && action.uri) {
    return uriAction(action.label, action.uri);
  }
  if (action.type === "postback" && action.data) {
    return postbackAction(action.label, action.data, action.label);
  }
  return messageAction(action.label, action.data ?? action.label);
}

/**
 * Create a confirm template (yes/no style dialog)
 */
export function createConfirmTemplate(
  text: string,
  confirmAction: Action,
  cancelAction: Action,
  altText?: string,
): TemplateMessage {
  const template: ConfirmTemplate = {
    type: "confirm",
    text: text.slice(0, 240), // LINE limit
    actions: [confirmAction, cancelAction],
  };

  return {
    type: "template",
    altText: altText?.slice(0, 400) ?? text.slice(0, 400),
    template,
  };
}

/**
 * Create a button template with title, text, and action buttons
 */
export function createButtonTemplate(
  title: string,
  text: string,
  actions: Action[],
  options?: {
    thumbnailImageUrl?: string;
    imageAspectRatio?: "rectangle" | "square";
    imageSize?: "cover" | "contain";
    imageBackgroundColor?: string;
    defaultAction?: Action;
    altText?: string;
  },
): TemplateMessage {
  const hasThumbnail = Boolean(options?.thumbnailImageUrl?.trim());
  const textLimit = hasThumbnail ? 160 : 60;
  const template: ButtonsTemplate = {
    type: "buttons",
    title: title.slice(0, 40), // LINE limit
    text: text.slice(0, textLimit), // LINE limit (60 if no thumbnail, 160 with thumbnail)
    actions: actions.slice(0, 4), // LINE limit: max 4 actions
    thumbnailImageUrl: options?.thumbnailImageUrl,
    imageAspectRatio: options?.imageAspectRatio ?? "rectangle",
    imageSize: options?.imageSize ?? "cover",
    imageBackgroundColor: options?.imageBackgroundColor,
    defaultAction: options?.defaultAction,
  };

  return {
    type: "template",
    altText: options?.altText?.slice(0, 400) ?? `${title}: ${text}`.slice(0, 400),
    template,
  };
}

/**
 * Create a carousel template with multiple columns
 */
export function createTemplateCarousel(
  columns: CarouselColumn[],
  options?: {
    imageAspectRatio?: "rectangle" | "square";
    imageSize?: "cover" | "contain";
    altText?: string;
  },
): TemplateMessage {
  const template: CarouselTemplate = {
    type: "carousel",
    columns: columns.slice(0, 10), // LINE limit: max 10 columns
    imageAspectRatio: options?.imageAspectRatio ?? "rectangle",
    imageSize: options?.imageSize ?? "cover",
  };

  return {
    type: "template",
    altText: options?.altText?.slice(0, 400) ?? "View carousel",
    template,
  };
}

/**
 * Create a carousel column for use with createTemplateCarousel
 */
export function createCarouselColumn(params: {
  title?: string;
  text: string;
  actions: Action[];
  thumbnailImageUrl?: string;
  imageBackgroundColor?: string;
  defaultAction?: Action;
}): CarouselColumn {
  return {
    title: params.title?.slice(0, 40),
    text: params.text.slice(0, 120), // LINE limit
    actions: params.actions.slice(0, 3), // LINE limit: max 3 actions per column
    thumbnailImageUrl: params.thumbnailImageUrl,
    imageBackgroundColor: params.imageBackgroundColor,
    defaultAction: params.defaultAction,
  };
}

/**
 * Create an image carousel template (simpler, image-focused carousel)
 */
export function createImageCarousel(
  columns: ImageCarouselColumn[],
  altText?: string,
): TemplateMessage {
  const template: ImageCarouselTemplate = {
    type: "image_carousel",
    columns: columns.slice(0, 10), // LINE limit: max 10 columns
  };

  return {
    type: "template",
    altText: altText?.slice(0, 400) ?? "View images",
    template,
  };
}

/**
 * Create an image carousel column for use with createImageCarousel
 */
export function createImageCarouselColumn(imageUrl: string, action: Action): ImageCarouselColumn {
  return {
    imageUrl,
    action,
  };
}

// ============================================================================
// Action Helpers (same as rich-menu but re-exported for convenience)
// ============================================================================

// ============================================================================
// Convenience Builders
// ============================================================================

/**
 * Create a simple yes/no confirmation dialog
 */
export function createYesNoConfirm(
  question: string,
  options?: {
    yesText?: string;
    noText?: string;
    yesData?: string;
    noData?: string;
    altText?: string;
  },
): TemplateMessage {
  const yesAction: Action = options?.yesData
    ? postbackAction(options.yesText ?? "Yes", options.yesData, options.yesText ?? "Yes")
    : messageAction(options?.yesText ?? "Yes");

  const noAction: Action = options?.noData
    ? postbackAction(options.noText ?? "No", options.noData, options.noText ?? "No")
    : messageAction(options?.noText ?? "No");

  return createConfirmTemplate(question, yesAction, noAction, options?.altText);
}

/**
 * Create a button menu with simple text buttons
 */
export function createButtonMenu(
  title: string,
  text: string,
  buttons: Array<{ label: string; text?: string }>,
  options?: {
    thumbnailImageUrl?: string;
    altText?: string;
  },
): TemplateMessage {
  const actions = buttons.slice(0, 4).map((btn) => messageAction(btn.label, btn.text));

  return createButtonTemplate(title, text, actions, {
    thumbnailImageUrl: options?.thumbnailImageUrl,
    altText: options?.altText,
  });
}

/**
 * Create a button menu with URL links
 */
export function createLinkMenu(
  title: string,
  text: string,
  links: Array<{ label: string; url: string }>,
  options?: {
    thumbnailImageUrl?: string;
    altText?: string;
  },
): TemplateMessage {
  const actions = links.slice(0, 4).map((link) => uriAction(link.label, link.url));

  return createButtonTemplate(title, text, actions, {
    thumbnailImageUrl: options?.thumbnailImageUrl,
    altText: options?.altText,
  });
}

/**
 * Create a simple product/item carousel
 */
export function createProductCarousel(
  products: Array<{
    title: string;
    description: string;
    imageUrl?: string;
    price?: string;
    actionLabel?: string;
    actionUrl?: string;
    actionData?: string;
  }>,
  altText?: string,
): TemplateMessage {
  const columns = products.slice(0, 10).map((product) => {
    const actions: Action[] = [];

    // Add main action
    if (product.actionUrl) {
      actions.push(uriAction(product.actionLabel ?? "View", product.actionUrl));
    } else if (product.actionData) {
      actions.push(postbackAction(product.actionLabel ?? "Select", product.actionData));
    } else {
      actions.push(messageAction(product.actionLabel ?? "Select", product.title));
    }

    return createCarouselColumn({
      title: product.title,
      text: product.price
        ? `${product.description}\n${product.price}`.slice(0, 120)
        : product.description,
      thumbnailImageUrl: product.imageUrl,
      actions,
    });
  });

  return createTemplateCarousel(columns, { altText });
}

// ============================================================================
// ReplyPayload Conversion
// ============================================================================

import type { LineTemplateMessagePayload } from "./types.js";

/**
 * Convert a TemplateMessagePayload from ReplyPayload to a LINE TemplateMessage
 */
export function buildTemplateMessageFromPayload(
  payload: LineTemplateMessagePayload,
): TemplateMessage | null {
  switch (payload.type) {
    case "confirm": {
      const confirmAction = payload.confirmData.startsWith("http")
        ? uriAction(payload.confirmLabel, payload.confirmData)
        : payload.confirmData.includes("=")
          ? postbackAction(payload.confirmLabel, payload.confirmData, payload.confirmLabel)
          : messageAction(payload.confirmLabel, payload.confirmData);

      const cancelAction = payload.cancelData.startsWith("http")
        ? uriAction(payload.cancelLabel, payload.cancelData)
        : payload.cancelData.includes("=")
          ? postbackAction(payload.cancelLabel, payload.cancelData, payload.cancelLabel)
          : messageAction(payload.cancelLabel, payload.cancelData);

      return createConfirmTemplate(payload.text, confirmAction, cancelAction, payload.altText);
    }

    case "buttons": {
      const actions: Action[] = payload.actions
        .slice(0, 4)
        .map((action) => buildTemplatePayloadAction(action));

      return createButtonTemplate(payload.title, payload.text, actions, {
        thumbnailImageUrl: payload.thumbnailImageUrl,
        altText: payload.altText,
      });
    }

    case "carousel": {
      const columns: CarouselColumn[] = payload.columns.slice(0, 10).map((col) => {
        const colActions: Action[] = col.actions
          .slice(0, 3)
          .map((action) => buildTemplatePayloadAction(action));

        return createCarouselColumn({
          title: col.title,
          text: col.text,
          thumbnailImageUrl: col.thumbnailImageUrl,
          actions: colActions,
        });
      });

      return createTemplateCarousel(columns, { altText: payload.altText });
    }

    default:
      return null;
  }
}

// Re-export types
export type {
  TemplateMessage,
  ConfirmTemplate,
  ButtonsTemplate,
  CarouselTemplate,
  CarouselColumn,
  ImageCarouselTemplate,
  ImageCarouselColumn,
  Action,
};
