import { AUTOMATION_ACTION_OPTIONS, AUTOMATION_TRIGGER_VALUES } from "@/lib/automations/catalog";
import type {
  AutomationActionConfig,
  AutomationActionType,
  AutomationScheduleFrequency,
  AutomationStep,
  AutomationTaskDeadlineState,
  AutomationTriggerMode,
  AutomationRuleConditions,
  Priority,
  ProjectHealth,
  TaskStatus,
  WebhookEventType,
} from "@/types";

const AUTOMATION_ACTION_VALUES = AUTOMATION_ACTION_OPTIONS.map((option) => option.value);
const AUTOMATION_TRIGGER_MODE_VALUES: AutomationTriggerMode[] = ["event", "schedule"];
const AUTOMATION_SCHEDULE_FREQUENCY_VALUES: AutomationScheduleFrequency[] = [
  "daily",
  "weekly",
];
const TASK_STATUS_VALUES: TaskStatus[] = ["todo", "in_progress", "done", "cancelled"];
const PRIORITY_VALUES: Priority[] = ["urgent", "high", "medium", "low", "none"];
const PROJECT_HEALTH_VALUES: ProjectHealth[] = ["on_track", "at_risk", "stuck"];
const TASK_DEADLINE_STATE_VALUES: AutomationTaskDeadlineState[] = [
  "has_deadline",
  "no_deadline",
  "overdue",
];

export function parseAutomationTriggerMode(value: unknown) {
  return typeof value === "string" &&
    AUTOMATION_TRIGGER_MODE_VALUES.includes(value as AutomationTriggerMode)
    ? (value as AutomationTriggerMode)
    : null;
}

export function parseAutomationScheduleFrequency(value: unknown) {
  return typeof value === "string" &&
    AUTOMATION_SCHEDULE_FREQUENCY_VALUES.includes(value as AutomationScheduleFrequency)
    ? (value as AutomationScheduleFrequency)
    : null;
}

export function parseAutomationTriggerEvent(value: unknown) {
  return typeof value === "string" &&
    AUTOMATION_TRIGGER_VALUES.includes(value as WebhookEventType)
    ? (value as WebhookEventType)
    : null;
}

export function parseAutomationActionType(value: unknown) {
  return typeof value === "string" &&
    AUTOMATION_ACTION_VALUES.includes(value as AutomationActionType)
    ? (value as AutomationActionType)
    : null;
}

export function sanitizeAutomationConditions(value: unknown): AutomationRuleConditions {
  const raw =
    value && typeof value === "object" && !Array.isArray(value)
      ? (value as Record<string, unknown>)
      : {};

  return {
    title_contains:
      typeof raw.title_contains === "string" && raw.title_contains.trim()
        ? raw.title_contains.trim()
        : null,
    task_status_is:
      typeof raw.task_status_is === "string" &&
      TASK_STATUS_VALUES.includes(raw.task_status_is as TaskStatus)
        ? (raw.task_status_is as TaskStatus)
        : null,
    task_status_changed_to:
      typeof raw.task_status_changed_to === "string" &&
      TASK_STATUS_VALUES.includes(raw.task_status_changed_to as TaskStatus)
        ? (raw.task_status_changed_to as TaskStatus)
        : null,
    task_priority_is:
      typeof raw.task_priority_is === "string" &&
      PRIORITY_VALUES.includes(raw.task_priority_is as Priority)
        ? (raw.task_priority_is as Priority)
        : null,
    project_health_is:
      typeof raw.project_health_is === "string" &&
      PROJECT_HEALTH_VALUES.includes(raw.project_health_is as ProjectHealth)
        ? (raw.project_health_is as ProjectHealth)
        : null,
    task_deadline_state:
      typeof raw.task_deadline_state === "string" &&
      TASK_DEADLINE_STATE_VALUES.includes(
        raw.task_deadline_state as AutomationTaskDeadlineState
      )
        ? (raw.task_deadline_state as AutomationTaskDeadlineState)
        : null,
    task_tag_id:
      typeof raw.task_tag_id === "string" && raw.task_tag_id.trim()
        ? raw.task_tag_id.trim()
        : null,
    project_id:
      typeof raw.project_id === "string" && raw.project_id.trim()
        ? raw.project_id.trim()
        : null,
    goal_id:
      typeof raw.goal_id === "string" && raw.goal_id.trim()
        ? raw.goal_id.trim()
        : null,
    assignee_id:
      typeof raw.assignee_id === "string" && raw.assignee_id.trim()
        ? raw.assignee_id.trim()
        : null,
    reviewer_id:
      typeof raw.reviewer_id === "string" && raw.reviewer_id.trim()
        ? raw.reviewer_id.trim()
        : null,
  };
}

export function sanitizeAutomationActionConfig(
  actionType: AutomationActionType,
  value: unknown
): AutomationActionConfig {
  const raw =
    value && typeof value === "object" && !Array.isArray(value)
      ? (value as Record<string, unknown>)
      : {};

  if (actionType === "create_task") {
    return {
      task_title_template:
        typeof raw.task_title_template === "string" && raw.task_title_template.trim()
          ? raw.task_title_template.trim()
          : null,
      task_description_template:
        typeof raw.task_description_template === "string" &&
        raw.task_description_template.trim()
          ? raw.task_description_template.trim()
          : null,
      task_priority:
        typeof raw.task_priority === "string" &&
        PRIORITY_VALUES.includes(raw.task_priority as Priority)
          ? (raw.task_priority as Priority)
          : "none",
      assignee_id:
        typeof raw.assignee_id === "string" && raw.assignee_id.trim()
          ? raw.assignee_id.trim()
          : null,
      reviewer_id:
        typeof raw.reviewer_id === "string" && raw.reviewer_id.trim()
          ? raw.reviewer_id.trim()
          : null,
    };
  }

  if (actionType === "create_note") {
    return {
      note_title_template:
        typeof raw.note_title_template === "string" && raw.note_title_template.trim()
          ? raw.note_title_template.trim()
          : null,
      note_content_template:
        typeof raw.note_content_template === "string" && raw.note_content_template.trim()
          ? raw.note_content_template.trim()
          : null,
      note_folder_id:
        typeof raw.note_folder_id === "string" && raw.note_folder_id.trim()
          ? raw.note_folder_id.trim()
          : null,
    };
  }

  if (actionType === "create_gmail_draft") {
    return {
      connection_id:
        typeof raw.connection_id === "string" && raw.connection_id.trim()
          ? raw.connection_id.trim()
          : null,
      email_to_template:
        typeof raw.email_to_template === "string" && raw.email_to_template.trim()
          ? raw.email_to_template.trim()
          : null,
      email_subject_template:
        typeof raw.email_subject_template === "string" && raw.email_subject_template.trim()
          ? raw.email_subject_template.trim()
          : null,
      email_body_template:
        typeof raw.email_body_template === "string" && raw.email_body_template.trim()
          ? raw.email_body_template.trim()
          : null,
    };
  }

  if (actionType === "ai_create_task") {
    return {
      task_title_template:
        typeof raw.task_title_template === "string" && raw.task_title_template.trim()
          ? raw.task_title_template.trim()
          : null,
      prompt_template:
        typeof raw.prompt_template === "string" && raw.prompt_template.trim()
          ? raw.prompt_template.trim()
          : null,
      task_priority:
        typeof raw.task_priority === "string" &&
        PRIORITY_VALUES.includes(raw.task_priority as Priority)
          ? (raw.task_priority as Priority)
          : "none",
      assignee_id:
        typeof raw.assignee_id === "string" && raw.assignee_id.trim()
          ? raw.assignee_id.trim()
          : null,
      reviewer_id:
        typeof raw.reviewer_id === "string" && raw.reviewer_id.trim()
          ? raw.reviewer_id.trim()
          : null,
    };
  }

  if (actionType === "ai_create_note") {
    return {
      note_title_template:
        typeof raw.note_title_template === "string" && raw.note_title_template.trim()
          ? raw.note_title_template.trim()
          : null,
      prompt_template:
        typeof raw.prompt_template === "string" && raw.prompt_template.trim()
          ? raw.prompt_template.trim()
          : null,
    };
  }

  return {
    connection_id:
      typeof raw.connection_id === "string" && raw.connection_id.trim()
        ? raw.connection_id.trim()
        : null,
  };
}

export function validateAutomationActionConfig(
  actionType: AutomationActionType,
  actionConfig: AutomationActionConfig
) {
  if (
    actionType !== "create_task" &&
    actionType !== "create_note" &&
    actionType !== "ai_create_task" &&
    actionType !== "ai_create_note" &&
    !actionConfig.connection_id
  ) {
    return "Choose a connection for this automation action.";
  }

  if (
    (actionType === "ai_create_task" || actionType === "ai_create_note") &&
    !actionConfig.prompt_template
  ) {
    return "Add an AI prompt template for this automation action.";
  }

  return null;
}

export function sanitizeAutomationSteps(value: unknown): AutomationStep[] {
  if (!Array.isArray(value)) return [];

  return value
    .map((item, index) => {
      const raw =
        item && typeof item === "object" && !Array.isArray(item)
          ? (item as Record<string, unknown>)
          : null;

      if (!raw) return null;

      const actionType = parseAutomationActionType(raw.action_type);
      if (!actionType) return null;

      return {
        id:
          typeof raw.id === "string" && raw.id.trim()
            ? raw.id.trim()
            : `step_${index + 1}`,
        action_type: actionType,
        action_config: sanitizeAutomationActionConfig(actionType, raw.action_config),
      } satisfies AutomationStep;
    })
    .filter((step): step is AutomationStep => Boolean(step));
}

export function validateAutomationSteps(steps: AutomationStep[]) {
  if (steps.length === 0) {
    return "Add at least one automation step.";
  }

  for (const step of steps) {
    const error = validateAutomationActionConfig(step.action_type, step.action_config);
    if (error) return error;
  }

  return null;
}

export function sanitizeScheduleTime(value: unknown) {
  if (typeof value !== "string") return null;
  const normalized = value.trim();
  return /^\d{2}:\d{2}$/.test(normalized) ? normalized : null;
}

export function sanitizeScheduleDayOfWeek(value: unknown) {
  if (typeof value !== "number" || !Number.isInteger(value)) return null;
  return value >= 0 && value <= 6 ? value : null;
}

export function sanitizeScheduleTimezone(value: unknown) {
  if (typeof value !== "string" || !value.trim()) return null;

  try {
    Intl.DateTimeFormat("en-US", { timeZone: value.trim() }).format(new Date());
    return value.trim();
  } catch {
    return null;
  }
}
