import type {
  Ticket,
  TicketDetail,
  TicketStats,
  TicketCategory,
  TicketStatusOption,
  TicketPriorityOption,
  UpdateTicketPayload,
  TicketAssignableUser,
  TicketMessage,
  TicketMessageKind,
  TicketDraft,
  TicketHistoryPage,
  CreateTicketMessagePayload,
  SupportInboxCounts,
} from "@/domain/entities/ticket";
import type {
  TicketRepository,
  TicketHistoryQueryParams,
} from "@/domain/repositories/ticket.repository";
import type { BackendPaginatedData, PaginationQueryParams } from "@/shared/types";
import { api } from "@/infrastructure/api/api-client";
import axios from "axios";

export class TicketRepositoryImpl implements TicketRepository {
  findAll(params: PaginationQueryParams) {
    return api.get<BackendPaginatedData<Ticket>>("/tickets", { params });
  }

  findById(id: number) {
    return api.get<TicketDetail>(`/tickets/${id}`);
  }

  update(id: number, payload: UpdateTicketPayload) {
    return api.put<TicketDetail>(`/tickets/${id}`, payload);
  }

  delete(id: number) {
    return api.delete(`/tickets/${id}`);
  }

  getStats() {
    return api.get<TicketStats>("/tickets/stats");
  }

  getCategories() {
    return api.get<TicketCategory[]>("/tickets/categories");
  }

  getStatusOptions() {
    return api.get<TicketStatusOption[]>("/tickets/options/statuses");
  }

  getPriorityOptions() {
    return api.get<TicketPriorityOption[]>("/tickets/options/priorities");
  }

  // PBI 1 — Assignment

  assign(id: number, userId: number | null) {
    return api.post<TicketDetail>(`/tickets/${id}/assign`, { user_id: userId });
  }

  getAssignableUsers(q?: string) {
    return api.get<TicketAssignableUser[]>("/tickets/assignees", {
      params: q ? { q } : undefined,
    });
  }

  // PBI 2 — Messages, drafts, mentions

  getMessages(ticketId: number, kind?: TicketMessageKind) {
    return api.get<TicketMessage[]>(`/tickets/${ticketId}/messages`, {
      params: kind ? { kind } : undefined,
    });
  }

  createMessage(ticketId: number, payload: CreateTicketMessagePayload) {
    const form = new FormData();
    form.append("kind", payload.kind);
    if (payload.body) form.append("body", payload.body);
    if (payload.attachments) {
      for (const file of payload.attachments) {
        form.append("attachments[]", file);
      }
    }
    if (payload.mentions) {
      for (const id of payload.mentions) {
        form.append("mentions[]", String(id));
      }
    }
    return api.post<TicketMessage>(`/tickets/${ticketId}/messages`, form);
  }

  updateMessage(ticketId: number, messageId: number, body: string) {
    return api.patch<TicketMessage>(`/tickets/${ticketId}/messages/${messageId}`, { body });
  }

  deleteMessage(ticketId: number, messageId: number) {
    return api.delete(`/tickets/${ticketId}/messages/${messageId}`);
  }

  async getDraft(ticketId: number, kind: TicketMessageKind) {
    try {
      return await api.get<TicketDraft>(`/tickets/${ticketId}/draft`, {
        params: { kind },
      });
    } catch (err) {
      if (axios.isAxiosError(err) && err.response?.status === 404) return null;
      throw err;
    }
  }

  upsertDraft(ticketId: number, kind: TicketMessageKind, body: string) {
    return api.put<TicketDraft>(`/tickets/${ticketId}/draft`, { kind, body });
  }

  deleteDraft(ticketId: number, kind: TicketMessageKind) {
    return api.delete(`/tickets/${ticketId}/draft`, { params: { kind } });
  }

  getMentionableUsers(q?: string) {
    return api.get<TicketAssignableUser[]>("/tickets/mentionable-users", {
      params: q ? { q } : undefined,
    });
  }

  // Support inbox

  getInboxCounts() {
    return api.get<SupportInboxCounts>("/tickets/inbox/counts");
  }

  markRead(ticketId: number) {
    return api.post<SupportInboxCounts>(`/tickets/${ticketId}/read`);
  }

  // PBI 3 — History

  getHistory(ticketId: number, params?: TicketHistoryQueryParams) {
    return api.get<TicketHistoryPage>(`/tickets/${ticketId}/history`, { params });
  }
}
