import type {
  ActionCompetenceObjectType,
  AssignmentAssignmentAssignmentTypeChoices,
  AssignmentCompletionObjectType,
  AssignmentCompletionStatus as AssignmentCompletionStatusGenerated,
  AssignmentObjectType,
  CircleObjectType,
  CourseSessionObjectType,
  CourseSessionUserObjectsType,
  LearningContentAssignmentObjectType,
  LearningContentAttendanceCourseObjectType,
  LearningContentDocumentListObjectType,
  LearningContentEdoniqTestObjectType,
  LearningContentFeedbackUkObjectType,
  LearningContentFeedbackVvObjectType,
  LearningContentKnowledgeAssessmentObjectType,
  LearningContentLearningModuleObjectType,
  LearningContentMediaLibraryObjectType,
  LearningContentPlaceholderObjectType,
  LearningContentRichTextObjectType,
  LearningContentVideoObjectType,
  LearningPathObjectType,
  LearningSequenceObjectType,
  LearningUnitObjectType,
  PerformanceCriteriaObjectType,
  TopicObjectType,
} from "@/gql/graphql";
import type { Component } from "vue";

export type LoginMethod = "local" | "sso";

export type CourseCompletionStatus = "UNKNOWN" | "FAIL" | "SUCCESS";

export type Completable = {
  completion_status?: CourseCompletionStatus;
  completion_status_updated_at?: string;
};

export interface BaseCourseWagtailPage {
  readonly id: string;
  readonly title: string;
  readonly slug: string;
  readonly content_type: string;
  readonly translation_key: string;
  readonly frontend_url: string;
}

export interface CircleLight {
  readonly id: string;
  readonly slug: string;
  readonly title: string;
}

// refine generated types
export type LearningContentAssignment = LearningContentAssignmentObjectType & {
  readonly content_type: "learnpath.LearningContentAssignment";
};

export type LearningContentAttendanceCourse =
  LearningContentAttendanceCourseObjectType & {
    readonly content_type: "learnpath.LearningContentAttendanceCourse";
  };

export type LearningContentDocumentList = LearningContentDocumentListObjectType & {
  readonly content_type: "learnpath.LearningContentDocumentList";
};

export type LearningContentEdoniqTest = LearningContentEdoniqTestObjectType & {
  readonly content_type: "learnpath.LearningContentEdoniqTest";
};

export type LearningContentFeedbackVV = LearningContentFeedbackVvObjectType & {
  readonly content_type: "learnpath.LearningContentFeedbackVV";
};

export type LearningContentFeedbackUK = LearningContentFeedbackUkObjectType & {
  readonly content_type: "learnpath.LearningContentFeedbackUK";
};

export type LearningContentLearningModule = LearningContentLearningModuleObjectType & {
  readonly content_type: "learnpath.LearningContentLearningModule";
};

export type LearningContentKnowledgeAssessment =
  LearningContentKnowledgeAssessmentObjectType & {
    readonly content_type: "learnpath.LearningContentKnowledgeAssessment";
  };

export type LearningContentMediaLibrary = LearningContentMediaLibraryObjectType & {
  readonly content_type: "learnpath.LearningContentMediaLibrary";
};

export type LearningContentPlaceholder = LearningContentPlaceholderObjectType & {
  readonly content_type: "learnpath.LearningContentPlaceholder";
};

export type LearningContentRichText = LearningContentRichTextObjectType & {
  readonly content_type: "learnpath.LearningContentRichText";
};

export type LearningContentVideo = LearningContentVideoObjectType & {
  readonly content_type: "learnpath.LearningContentVideo";
};

export type LearningContent =
  | LearningContentAssignment
  | LearningContentAttendanceCourse
  | LearningContentDocumentList
  | LearningContentEdoniqTest
  | LearningContentFeedbackUK
  | LearningContentFeedbackVV
  | LearningContentLearningModule
  | LearningContentKnowledgeAssessment
  | LearningContentMediaLibrary
  | LearningContentPlaceholder
  | LearningContentRichText
  | LearningContentVideo;

export type LearningContentWithCompletion = LearningContent &
  Completable & {
    continueUrl?: string;
    firstInCircle?: boolean;
    parentLearningUnit?: {
      id: string;
      slug: string;
      title: string;
    };
  };

export type LearningContentContentType = LearningContent["content_type"];

export type LearningUnit = Omit<
  LearningUnitObjectType,
  "content_type" | "learning_contents" | "performance_criteria"
> & {
  content_type: "learnpath.LearningUnit";
  learning_contents: LearningContentWithCompletion[];
  performance_criteria: LearningUnitPerformanceCriteria[];
  circle?: CircleLight;
};

export type LearningSequence = Omit<
  LearningSequenceObjectType,
  "content_type" | "learning_units"
> & {
  content_type: "learnpath.LearningSequence";
  learning_units: LearningUnit[];
};

export type CircleType = Omit<
  CircleObjectType,
  "content_type" | "learning_sequences"
> & {
  content_type: "learnpath.Circle";
  learning_sequences: LearningSequence[];
};

export type TopicType = Omit<TopicObjectType, "content_type" | "circles"> & {
  content_type: "learnpath.Topic";
  circles: CircleType[];
};

export type LearningPathType = Omit<
  LearningPathObjectType,
  "content_type" | "topics"
> & {
  content_type: "learnpath.LearningPath";
  topics: TopicType[];
};

export type LearningUnitPerformanceCriteria = Omit<
  PerformanceCriteriaObjectType,
  "content_type"
> &
  Completable & {
    readonly content_type: "competence.PerformanceCriteria";
    circle?: CircleLight;
  };

export interface CourseCompletion {
  readonly id: string;
  created_at: string;
  updated_at: string;
  readonly user: number;
  readonly page_id: string;
  readonly page_type: string;
  readonly course_session_id: string;
  completion_status: CourseCompletionStatus;
  additional_json_data: unknown;
}

export interface Course {
  id: string;
  title: string;
  category_name: string;
  slug: string;
  enable_circle_documents: boolean;
}

export interface CourseCategory {
  id: string;
  name: string;
  general: boolean;
}

export type MediaLibraryContentBlockValue = {
  title: string;
  description: string;
  icon_url: string;
  link_display_text: string;
  url: string;
  open_window: boolean;
};

export interface LearnMediaBlock {
  type: "learn_media";
  id: string;
  value: MediaLibraryContentBlockValue;
}

export interface ExternalLinkBlock {
  type: "external_link";
  id: string;
  value: MediaLibraryContentBlockValue;
}

export interface InternalLinkBlock {
  type: "internal_link";
  id: string;
  value: MediaLibraryContentBlockValue;
}

export interface RelativeLinkBlock {
  type: "relative_link";
  id: string;
  value: MediaLibraryContentBlockValue;
}

export type MediaBlock =
  | LearnMediaBlock
  | ExternalLinkBlock
  | InternalLinkBlock
  | RelativeLinkBlock;

export type MediaBlockType = MediaBlock["type"];

export interface MediaContentCollection {
  type: "content_collection";
  value: {
    title: string;
    description: string;
    contents: MediaBlock[];
  };
}

export interface MediaLibraryContentPage extends BaseCourseWagtailPage {
  readonly content_type: "media_library.MediaLibraryContentPage";
  readonly icon_overview_url: string;
  readonly icon_detail_url: string;
  readonly description: string;
  readonly body: string;
}

export interface MediaLibraryCategoryPage extends BaseCourseWagtailPage {
  readonly content_type: "media_library.MediaLibraryCategoryPage";
  readonly icon_url: string;
  readonly description: string;
  readonly children: MediaLibraryContentPage[];
}

export interface MediaLibraryUrlPage extends BaseCourseWagtailPage {
  readonly content_type: "media_library.MediaLibraryUrlPage";
  readonly icon_url: string;
  readonly content_url: string;
  readonly url_open_blank: boolean;
  readonly description: string;
}

export type MediaLibraryPageChild = MediaLibraryCategoryPage | MediaLibraryUrlPage;

export interface MediaLibraryPage extends BaseCourseWagtailPage {
  readonly content_type: "media_library.MediaLibraryPage";
  readonly course: Course;
  readonly description: string;
  readonly children: MediaLibraryPageChild[];
}

export interface AssignmentPerformanceObjective {
  readonly type: "performance_objective";
  readonly id: string;
  readonly value: {
    text: string;
  };
}

export interface AssignmentTaskBlockExplanation {
  readonly type: "explanation";
  readonly id: string;
  readonly value: {
    readonly text: string;
  };
}

export interface AssignmentTaskBlockUserConfirmation {
  readonly type: "user_confirmation";
  readonly id: string;
  readonly value: {
    readonly text: string;
  };
}

export interface AssignmentTaskBlockUserTextInput {
  readonly type: "user_text_input";
  readonly id: string;
  readonly value: {
    readonly text?: string;
  };
}

export type AssignmentTaskBlock =
  | AssignmentTaskBlockExplanation
  | AssignmentTaskBlockUserConfirmation
  | AssignmentTaskBlockUserTextInput;

export interface AssignmentTask {
  readonly type: "task";
  readonly id: string;
  readonly value: {
    title: string;
    file_submission_required: boolean;
    content: AssignmentTaskBlock[];
  };
}

export interface AssignmentEvaluationSubTask {
  readonly type: "task";
  readonly id: string;
  readonly value: {
    title: string;
    description: string;
    points: number;
  };
}

export interface AssignmentEvaluationTask {
  readonly type: "task";
  readonly id: string;
  readonly value: {
    title: string;
    description: string;
    max_points: number;
    sub_tasks?: AssignmentEvaluationSubTask[];
  };
}

export type AssignmentType = AssignmentAssignmentAssignmentTypeChoices;

export type Assignment = Omit<
  AssignmentObjectType,
  "content_type" | "performance_objectives" | "tasks" | "evaluation_tasks"
> & {
  readonly content_type: "assignment.Assignment";
  readonly performance_objectives: AssignmentPerformanceObjective[];
  readonly tasks: AssignmentTask[];
  readonly evaluation_tasks: AssignmentEvaluationTask[];
};

export type PerformanceCriteria = Omit<PerformanceCriteriaObjectType, "content_type"> &
  Completable & {
    readonly content_type: "competence.PerformanceCriteria";
    circle: CircleLight;
  };

export type ActionCompetence = Omit<
  ActionCompetenceObjectType,
  "content_type" | "performance_criteria"
> & {
  readonly content_type: "competence.ActionCompetence";
  performance_criteria: PerformanceCriteria[];
};

export interface CompetenceCertificateAssignment extends BaseCourseWagtailPage {
  assignment_type: "CASEWORK" | "EDONIQ_TEST";
  max_points: number;
  learning_content:
    | (BaseCourseWagtailPage & {
        circle: CircleLight;
      })
    | null;
  completion: {
    id: string;
    completion_status: AssignmentCompletionStatus;
    evaluation_submitted_at: string | null;
    evaluation_points: number | null;
    evaluation_max_points: number | null;
    evaluation_passed: boolean | null;
  } | null;
}

export interface CompetenceCertificate extends BaseCourseWagtailPage {
  readonly content_type: "competence.CompetenceCertificate";
  readonly assignments: CompetenceCertificateAssignment[];
}

// dropdown
export interface DropdownListItem {
  title: string;
  icon: Component | string;
  data: object;
}

export interface DropdownSelectable {
  id: number | string;
  name: string;
  iconName?: string;
}

export interface CircleExpert {
  user_id: string;
  user_email: string;
  user_first_name: string;
  user_last_name: string;
  circle_id: string;
  circle_slug: string;
  circle_translation_key: string;
}

export interface CircleDocument {
  id: string;
  name: string;
  file_name: string;
  url: string;
  learning_sequence: {
    id: string;
    title: string;
    circle: CircleLight;
  };
}

export interface CourseSession {
  id: string;
  created_at: string;
  updated_at: string;
  course: Course;
  title: string;
  start_date: string;
  end_date: string;
  due_dates: DueDate[];
}

export type CourseSessionUser = CourseSessionUserObjectsType;

export interface ExpertSessionUser extends CourseSessionUser {
  role: "EXPERT";
}

export type CourseSessionDetail = CourseSessionObjectType;

// document upload
export interface DocumentUploadData {
  file: File | null;
  name: string;
  learningSequence: {
    id: string;
    name: string;
  };
}

// notifications

export type NotificationCategory = "USER_INTERACTION" | "PROGRESS" | "INFORMATION";

export interface Notification {
  // given by AbstractNotification model
  id: string;
  timestamp: string;
  unread: boolean;
  actor: string | null;
  verb: string;
  target: string | null;
  action_object: string | null;
  // given by Notification model
  notification_category: NotificationCategory;
  target_url: string | null;
  actor_avatar_url: string | null;
  course: string | null;
}

export type AssignmentCompletionStatus = AssignmentCompletionStatusGenerated;

export interface UserDataText {
  text: string;
}

export interface UserDataConfirmation {
  confirmation: boolean;
}

export interface UserDataFile {
  fileId?: string;
  fileInfo?: UserDataFileInfo;
}

export interface UserDataFileInfo {
  id: string;
  name: string;
  url: string;
}

export interface ExpertData {
  points?: number;
  text?: string;
}

export interface AssignmentCompletionData {
  // {
  //    "<user_text_input:uuid>": {"user_data": {"text": "some text from user"}},
  //    "<user_confirmation:uuid>": {"user_data": {"confirmation": true}},
  // }
  [key: string]: {
    user_data?: UserDataText | UserDataConfirmation | UserDataFile;
    expert_data?: ExpertData;
  };
}

export interface AssignmentTaskCompletionData {
  // {
  //    "<user_text_input:uuid>": {"user_data": {"text": "some text from user"}},
  //    "<user_confirmation:uuid>": {"user_data": {"confirmation": true}},
  // }
  [key: string]: {
    user_data?: UserDataFile;
  };
}

export type AssignmentCompletion = AssignmentCompletionObjectType & {
  // assignment_user: Pick<UserObjectType, "id" | "__typename">;
  // evaluation_user: Pick<UserObjectType, "id" | "__typename">;
  completion_data: AssignmentCompletionData;
  task_completion_data: AssignmentTaskCompletionData;
};

export interface UserAssignmentCompletionStatus {
  id: string;
  assignment_user_id: string;
  completion_status: AssignmentCompletionStatus;
  evaluation_points: number | null;
  evaluation_max_points: number | null;
  evaluation_passed: boolean;
  learning_content_page_id: string;
}

export type SimpleDueDate = {
  id: string;
  start: string;
  end?: string;
};

export type DueDate = SimpleDueDate & {
  title: string;
  assignment_type_translation_key: string;
  date_type_translation_key: string;
  subtitle: string;
  url: string;
  url_expert: string;
  course_session_id: string;
  circle: CircleLight | null;
};

export type FeedbackType = "uk" | "vv";

export interface FeedbackData {
  amount: number;
  questions: {
    [key: string]: any;
  };
  feedbackType: FeedbackType;
}
