/**
 * API модуль для домашних заданий
 */

import apiClient from '@/lib/api-client';

export interface HomeworkMentor {
  id: number;
  email: string;
  first_name: string;
  last_name: string;
}

/** Файл задания/решения (ментор прикрепляет к заданию, ученик видит и скачивает). */
export interface HomeworkFileItem {
  id: number;
  file_type: 'assignment' | 'submission' | 'feedback';
  file: string;
  filename: string;
  file_size: number;
  /** Признак изображения по расширению (с бэкенда) — показывать превью и открывать в модалке. */
  is_image?: boolean;
  uploaded_by?: { id: number; first_name: string; last_name: string } | null;
  created_at: string;
}

export interface Homework {
  id: number;
  title: string;
  description?: string;
  mentor: HomeworkMentor;
  lesson: number | null;
  deadline: string | null;
  max_score: number;
  passing_score: number;
  status: 'draft' | 'published' | 'archived';
  /** Черновик «заполнить позже» — создан при завершении урока, нужно дописать задание. */
  fill_later?: boolean;
  total_submissions: number;
  checked_submissions: number;
  returned_submissions: number;
  average_score: number;
  is_overdue: boolean;
  created_at: string;
  published_at: string | null;
  /** Файл задания (один), URL для скачивания. */
  attachment?: string | null;
  /** Ссылка на материал (внешняя). */
  attachment_url?: string | null;
  /** Дополнительные файлы задания (ментор прикрепляет несколько). */
  files?: HomeworkFileItem[] | null;
  students?: { id: number; first_name: string; last_name: string; score: number | null; status: string }[] | null;
  student_score?: { score: number | null; max_score: number; status: string } | null;
  /** Только для ментора: количество решений с черновиком от ИИ (status=pending, ai_checked_at задано). */
  ai_draft_count?: number;
}

export interface HomeworkSubmission {
  id: number;
  homework: { id: number; title: string; description?: string; max_score: number };
  student: { id: number; first_name: string; last_name: string; email: string };
  status: string;
  content?: string;
  /** Основной файл решения (URL для скачивания). */
  attachment?: string | null;
  attachment_url?: string | null;
  /** Доп. файлы решения (студент прикрепляет несколько). */
  files?: HomeworkFileItem[] | null;
  score?: number | null;
  feedback?: string;
  /** HTML комментария проверки (markdown → HTML). */
  feedback_html?: string;
  submitted_at: string;
  checked_at?: string | null;
  ai_score?: number | null;
  ai_feedback?: string;
  /** HTML превью черновика ИИ (markdown → HTML). */
  ai_feedback_html?: string;
  ai_checked_at?: string | null;
  /** True, если оценка опубликована автоматически через ИИ. */
  graded_by_ai?: boolean;
  checked_by?: { id: number; first_name: string; last_name: string } | null;
}

export async function getHomework(params?: {
  status?: string;
  page_size?: number;
  child_id?: string;
}): Promise<{ results: Homework[]; count: number }> {
  const q = new URLSearchParams();
  if (params?.status) q.append('status', params.status);
  if (params?.page_size) q.append('page_size', String(params.page_size || 1000));
  if (params?.child_id) q.append('child_id', params.child_id);
  const query = q.toString();
  const url = `/homework/homeworks/${query ? `?${query}` : ''}`;
  const res = await apiClient.get<{ results: Homework[]; count: number } | Homework[]>(url);
  const data = res.data;
  if (Array.isArray(data)) {
    return { results: data, count: data.length };
  }
  return {
    results: data?.results ?? [],
    count: data?.count ?? 0,
  };
}

export async function getHomeworkById(id: string | number): Promise<Homework> {
  const res = await apiClient.get<Homework>(`/homework/homeworks/${id}/`);
  return res.data;
}

/** Создать домашнее задание (в т.ч. черновик для «заполнить позже»). По умолчанию макс. балл 5, проходной 1 (не учитывается). */
export async function createHomework(data: {
  title: string;
  description?: string;
  lesson_id?: number;
  status?: 'draft' | 'published';
  /** Пометить как «заполнить позже» — отображается в колонке «Ожидают заполнения» у ментора. */
  fill_later?: boolean;
  /** Максимальный балл (1–5 по умолчанию). По умолчанию 5. */
  max_score?: number;
  /** Проходной балл (по умолчанию 1, не учитывается). */
  passing_score?: number;
}): Promise<Homework> {
  const payload = {
    ...data,
    max_score: data.max_score ?? 5,
    passing_score: data.passing_score ?? 1,
  };
  const res = await apiClient.post<Homework>('/homework/homeworks/', payload);
  return res.data;
}

/** Опции запроса списка решений (например, отключить кэш для актуальных данных). */
export interface GetHomeworkSubmissionsOptions {
  cache?: boolean;
  /** Для родителя: user_id ребёнка — вернуть решения этого ребёнка. */
  child_id?: string | null;
}

export async function getHomeworkSubmissions(
  homeworkId: string | number,
  options?: GetHomeworkSubmissionsOptions
): Promise<HomeworkSubmission[]> {
  const params = new URLSearchParams({ homework_id: String(homeworkId) });
  if (options?.child_id) params.append('child_id', options.child_id);
  const res = await apiClient.get<{ results: HomeworkSubmission[] } | HomeworkSubmission[]>(
    `/homework/submissions/?${params.toString()}`,
    { cache: options?.cache ?? false }
  );
  const data = res.data;
  if (Array.isArray(data)) return data;
  return data?.results ?? [];
}

export async function getMySubmission(
  homeworkId: string | number,
  options?: GetHomeworkSubmissionsOptions
): Promise<HomeworkSubmission | null> {
  const list = await getHomeworkSubmissions(homeworkId, options);
  return list.length > 0 ? list[0] : null;
}

/** Получить одно решение по ID (для детального просмотра). */
export async function getHomeworkSubmission(
  submissionId: string | number
): Promise<HomeworkSubmission> {
  const res = await apiClient.get<HomeworkSubmission>(
    `/homework/submissions/${submissionId}/`
  );
  return res.data;
}

/**
 * ДЗ с оценками по предмету для графика прогресса.
 * GET /api/homework/submissions/by_subject/
 */
export async function getHomeworkSubmissionsBySubject(params: {
  subject: string;
  start_date?: string;
  end_date?: string;
  child_id?: string;
}): Promise<{ count: number; results: HomeworkSubmission[] }> {
  const q = new URLSearchParams();
  q.append('subject', params.subject);
  if (params.start_date) q.append('start_date', params.start_date);
  if (params.end_date) q.append('end_date', params.end_date);
  if (params.child_id) q.append('child_id', params.child_id);
  const res = await apiClient.get<{ count: number; results: HomeworkSubmission[] }>(
    `/homework/submissions/by_subject/?${q}`
  );
  return res.data;
}

export async function gradeSubmission(
  submissionId: string | number,
  data: { score: number; feedback?: string }
): Promise<unknown> {
  const res = await apiClient.post(`/homework/submissions/${submissionId}/grade/`, data);
  return res.data;
}

/** Использование токенов за один запрос (если API вернул). */
export interface TokenUsage {
  prompt_tokens: number;
  completion_tokens: number;
  total_tokens: number;
}

export interface CheckWithAiResponse {
  success: boolean;
  ai_score: number;
  ai_feedback: string;
  /** HTML для отображения комментария ИИ (markdown + LaTeX → HTML). */
  ai_feedback_html?: string;
  ai_checked_at?: string;
  message?: string;
  /** Токены за эту проверку (потрачено). Остаток лимита — в кабинете Timeweb. */
  usage?: TokenUsage;
}

/** Проверить решение через ИИ. Ментор: задание + решение → комментарий и оценка 1–5. */
export async function checkSubmissionWithAi(
  submissionId: string | number
): Promise<CheckWithAiResponse> {
  const res = await apiClient.post<CheckWithAiResponse>(
    `/homework/submissions/${submissionId}/check_with_ai/`
  );
  return res.data;
}

export async function returnSubmissionForRevision(
  submissionId: string | number,
  feedback: string
): Promise<unknown> {
  const res = await apiClient.post(`/homework/submissions/${submissionId}/return_for_revision/`, { feedback });
  return res.data;
}

/** Удалить своё решение (студент). Задание снова переходит в ожидание загрузки. */
export async function deleteSubmission(submissionId: string | number): Promise<void> {
  await apiClient.delete(`/homework/submissions/${submissionId}/`);
}

const MAX_HOMEWORK_FILE_SIZE = 50 * 1024 * 1024; // 50 МБ
const MAX_HOMEWORK_FILES = 10;

export function validateHomeworkFiles(files: File[]): { valid: boolean; error?: string } {
  if (files.length === 0) return { valid: true };
  if (files.length > MAX_HOMEWORK_FILES) {
    return { valid: false, error: `Максимум ${MAX_HOMEWORK_FILES} файлов` };
  }
  for (const f of files) {
    if (f.size > MAX_HOMEWORK_FILE_SIZE) {
      return { valid: false, error: `Файл "${f.name}" больше 50 МБ` };
    }
  }
  return { valid: true };
}

/**
 * Обновить домашнее задание (для черновиков fill_later).
 * PATCH /api/homework/homeworks/{id}/
 */
export async function updateHomework(
  homeworkId: string | number,
  data: {
    title?: string;
    description?: string;
    deadline?: string | null;
    status?: 'draft' | 'published';
    fill_later?: boolean;
  }
): Promise<Homework> {
  const res = await apiClient.patch<Homework>(`/homework/homeworks/${homeworkId}/`, data);
  return res.data;
}

/**
 * Опубликовать домашнее задание (из черновика в published).
 * POST /api/homework/homeworks/{id}/publish/
 */
export async function publishHomework(homeworkId: string | number): Promise<Homework> {
  const res = await apiClient.post<Homework>(`/homework/homeworks/${homeworkId}/publish/`);
  return res.data;
}

export async function submitHomework(
  homeworkId: string | number,
  data: { content?: string; text?: string; files?: File[] },
  onUploadProgress?: (percent: number) => void
): Promise<unknown> {
  const hasFiles = data.files && data.files.length > 0;
  if (hasFiles) {
    const formData = new FormData();
    formData.append('homework_id', String(homeworkId));
    if (data.content) formData.append('content', data.content);
    if (data.text) formData.append('content', data.text);
    data.files!.forEach((f) => formData.append('attachment', f));
    const res = await apiClient.post(`/homework/submissions/`, formData, {
      onUploadProgress:
        onUploadProgress &&
        (function (event: { loaded: number; total?: number }) {
          if (event.total && event.total > 0) {
            const percent = Math.round((event.loaded / event.total) * 100);
            onUploadProgress(Math.min(percent, 100));
          }
        }),
    });
    return res.data;
  }
  const res = await apiClient.post(`/homework/submissions/`, {
    homework_id: homeworkId,
    content: data.content || data.text || '',
  });
  return res.data;
}
