export interface Company {
  id: number;
  name: string;
  location?: string;
  source?: string;
  recruiterName?: string;
  recruiterEmail?: string;
  recruiterLinkedIn?: string;
  lastContactedAt?: string;
  nextContactAt?: string;
  pipelineStage?: string;
}

export type WorkflowActionKey = "package-work" | "follow-up" | "interview-prep" | "review-readiness";
export type WorkflowWorkspaceTab = "tailored-cv" | "follow-up" | "interview-prep" | "readiness";

export interface WorkflowSignal {
  actionKey: WorkflowActionKey;
  reason: string;
  workspaceTab: WorkflowWorkspaceTab;
  followMode?: string | null;
  needsAttention: boolean;
  hasPackageGap: boolean;
  needsInterviewPrep: boolean;
  needsFollowUpAction: boolean;
  hasTailoredCv: boolean;
  hasSavedApplicationAnswerDraft: boolean;
  hasInterviewPrepNotes: boolean;
}

export interface TailoredCvExperienceItem {
  title?: string | null;
  company?: string | null;
  location?: string | null;
  start?: string | null;
  end?: string | null;
  isCurrent?: boolean;
  bullets: string[];
}

export interface TailoredCvEducationItem {
  qualification?: string | null;
  qualificationLevel?: string | null;
  institution?: string | null;
  location?: string | null;
  start?: string | null;
  end?: string | null;
  details: string[];
}

export interface TailoredCvCustomSection {
  title?: string | null;
  items: string[];
}

export interface TailoredCvRenderOptions {
  showPhoto: boolean;
  pageMode: string;
  accentColor: string;
  sectionOrder: string[];
  bulletDensity: string;
}

export interface TailoredCvDraft {
  id?: number | null;
  canonicalProfileVersion?: number | null;
  templateId: string;
  headline?: string | null;
  summary: string[];
  selectedSkills: string[];
  experience: TailoredCvExperienceItem[];
  education: TailoredCvEducationItem[];
  customSections: TailoredCvCustomSection[];
  renderOptions: TailoredCvRenderOptions;
  generationContextHash?: string | null;
  lastGeneratedAtUtc?: string | null;
  lastEditedAtUtc?: string | null;
  status: string;
  renderedText: string;
  isLegacyFallback: boolean;
}

export interface JobApplication {
  id: number;
  jobTitle: string;
  company: Company;
  companyId?: number;
  status: string;
  // Null while the job sits in a pre-application stage (Saved/Interested/Preparing): nothing has
  // been submitted, so there is no applied date. Render "—", never a fabricated date.
  dateApplied: string | null;
  // When the user captured the job. Always set — use it wherever a job needs a date to sort or
  // show regardless of whether it has been applied to.
  savedAt: string;
  location?: string;
  salary?: string;
  salaryMin?: number | null;
  salaryMax?: number | null;
  salaryCurrency?: string | null;
  salaryPeriod?: string | null;
  nextAction?: string;
  followUpAt?: string;
  feedbackRequestedAt?: string;
  responseReceived: boolean;
  responseDate?: string;
  description?: string;
  translatedDescription?: string;
  descriptionLanguage?: string;
  tags?: string; // JSON array string
  deadline?: string;
  notes?: string;
  coverLetterText?: string;
  recruiterMessageDraft?: string | null;
  jobUrl?: string;
  shortSummary?: string;
  fullSummary?: string | null;
  tailoredCvText?: string | null;
  tailoredCvUpdatedAt?: string | null;
  workflowSignal?: WorkflowSignal | null;

  hasResume?: boolean;
  hasCoverLetter?: boolean;
  hasPortfolio?: boolean;
  hasOtherAttachment?: boolean;

  // Null when dateApplied is null — there is no elapsed time to report before applying.
  daysSince: number | null;
  isDeleted?: boolean;
  deletedAt?: string;
  needsFollowUp?: boolean;
  followUpReason?: string | null;
}

export interface CandidateFitChannelGuidance {
  cv: string[];
  coverLetter: string[];
  interview: string[];
  recruiterMessage: string[];
}

export interface MatchScoreSectionCoverage {
  section: string;
  matched: number;
  total: number;
}

export interface LearningRecommendation {
  id: number;
  keyword: string;
  status: "pending" | "done" | "dismissed";
}

export interface StatusSuggestion {
  hasSuggestion: boolean;
  suggestedStatus?: string | null;
  currentStatus?: string | null;
  signal?: string | null;
  confidence?: string | null;
  messageDate?: string | null;
  messageSubject?: string | null;
}

export interface MatchScore {
  score: number;
  band: string;
  matchedCount: number;
  totalKeywords: number;
  matchedKeywords: string[];
  missingKeywords: string[];
  sectionCoverage: MatchScoreSectionCoverage[];
  hasEnoughSignal: boolean;
  learningRecommendations: LearningRecommendation[];
}

export interface CandidateFit {
  matchSummary: string;
  fitLevel: string;
  matchScore: number;
  strengths: string[];
  gaps: string[];
  mention: string[];
  avoid: string[];
  cvImprovements: string[];
  missingKeywords: string[];
  interviewPrep: string[];
  tailoredPitch: string;
  guidance: CandidateFitChannelGuidance;
  coverLetterDraft?: string | null;
  recruiterMessageDraft?: string | null;
}

export interface FocusPlanResponse {
  immediatePriorities: string[];
  cvBulletIdeas: string[];
  proofPointsToLeadWith: string[];
  coverLetterAngles: string[];
  followUpApproach: string[];
  strategicSummary: string;
}

export interface UserOperation {
  id: string;
  taskType: string;
  status: "queued" | "running" | "waiting_for_retry" | "waiting_for_external_fallback" | "succeeded" | "failed" | "cancelled";
  subjectType?: string | null;
  createdAtUtc: string;
  startedAtUtc?: string | null;
  completedAtUtc?: string | null;
  deadlineAtUtc?: string | null;
  cancellationRequestedAtUtc?: string | null;
  progressStage?: string | null;
  progressPercent?: number | null;
  failureCategory?: string | null;
  canCancel: boolean;
  canRetry: boolean;
}

export interface StrategySnapshotOperationResponse {
  operation: UserOperation;
  statusUrl: string;
  created: boolean;
}

export interface InterviewPrepResponse {
  summary: string;
  talkingPoints: string[];
  likelyQuestions: string[];
  weakSpots: string[];
}

export interface ReadinessResponse {
  score: number;
  level: string;
  completed: string[];
  missing: string[];
  reminders: string[];
  workflowSignal: WorkflowSignal;
}

export interface FollowUpDraft {
  subject: string;
  body: string;
  reason: string;
  suggestedSendOn: string;
  contextSummary: string;
  contextSignals: string[];
  threadSubject?: string | null;
  lastCorrespondenceFrom?: string | null;
  lastCorrespondenceAt?: string | null;
}

export interface ApplicationPackageResponse {
  tailoredCvText: string;
  coverLetterDraft?: string | null;
  applicationAnswerDraft?: string | null;
  recruiterMessageDraft?: string | null;
  keyPoints: string[];
  attachmentSignals: string[];
  attachmentFilesUsed: string[];
  coverLetterVariants: string[];
  recruiterMessageVariants: string[];
}

export interface SaveApplicationDraftsRequest {
  coverLetterText?: string | null;
  notes?: string | null;
  recruiterMessageDraft?: string | null;
}

export interface CorrespondenceAttachmentMetadata {
  fileName?: string | null;
  mimeType?: string | null;
  sizeBytes?: number | null;
  gmailAttachmentId?: string | null;
  inline?: boolean;
}

export interface CorrespondenceMessage {
  id: number;
  jobApplicationId: number;
  from: string;
  direction?: string | null;
  content: string;
  subject?: string;
  channel?: string;
  date: string;
  externalMessageId?: string | null;
  externalThreadId?: string | null;
  externalFrom?: string | null;
  externalTo?: string | null;
  externalLabelsJson?: string | null;
  attachmentMetadataJson?: string | null;
}

export interface AttachmentItem {
  id: number;
  fileName: string;
  uploadDate: string;
  fileType: string;
  fileSize: number;
  purpose?: string | null;
  useForAi: boolean;
}

export interface GmailJobMatchReason {
  label: string;
  value: string;
}

export interface GmailJobMatchedMessage {
  id: string;
  threadId: string;
  subject: string;
  from: string;
  to: string;
  date?: string;
  snippet: string;
  score: number;
  confidence: string;
  alreadyImported: boolean;
  matchReasons: GmailJobMatchReason[];
}

export interface GmailJobMatchedThread {
  threadId: string;
  subject: string;
  score: number;
  confidence: string;
  hasImportedMessages: boolean;
  messageCount: number;
  latestDate?: string;
  matchReasons: GmailJobMatchReason[];
  messages: GmailJobMatchedMessage[];
}

export interface GmailJobMatchesResponse {
  jobApplicationId: number;
  jobTitle: string;
  companyName: string;
  recruiterName?: string | null;
  recruiterEmail?: string | null;
  queries: string[];
  threads: GmailJobMatchedThread[];
}

export interface GmailImportMessageResult {
  imported: number;
  skipped: number;
  messageId: string;
  threadId?: string | null;
  message?: CorrespondenceMessage | null;
}

export interface GmailImportThreadResult {
  imported: number;
  skipped: number;
  threadId?: string | null;
}

export interface GmailThreadRefreshThreadResult {
  threadId: string;
  imported: number;
  skipped: number;
  totalMessages: number;
  status: string;
  latestMessageDate?: string;
}

export interface GmailThreadRefreshResult {
  jobApplicationId: number;
  threadsChecked: number;
  imported: number;
  skipped: number;
  hasLinkedThreads: boolean;
  refreshedAt: string;
  threads: GmailThreadRefreshThreadResult[];
}

export interface GmailReviewJobCandidate {
  jobApplicationId: number;
  jobTitle: string;
  companyName: string;
  score: number;
  confidence: string;
  reasons: GmailJobMatchReason[];
}

export interface GmailReviewThread {
  threadId: string;
  subject: string;
  latestDate?: string;
  messageCount: number;
  routing: string;
  hasImportedMessages: boolean;
  decisionNote?: string | null;
  matchedQueries: string[];
  jobCandidates: GmailReviewJobCandidate[];
  messages: GmailJobMatchedMessage[];
}

export interface GmailReviewQueueResponse {
  queries: string[];
  candidateThreadCount: number;
  autoLinkThreadCount: number;
  reviewThreadCount: number;
  unmatchedThreadCount: number;
  threads: GmailReviewThread[];
}

export interface GmailStatus {
  connected: boolean;
  gmailAddress?: string;
  connectedAt?: string;
  lastSyncedAt?: string;
  lastSyncAttemptedAt?: string;
  lastSyncSucceededAt?: string;
  lastSyncMode?: string | null;
  lastSyncSource?: string | null;
  lastSyncStatus?: string | null;
  lastSyncError?: string | null;
}

export interface MicrosoftGraphStatus {
  connected: boolean;
  mailAddress?: string | null;
  connectedAt?: string;
  lastSyncedAt?: string;
  lastSyncAttemptedAt?: string;
  lastSyncSucceededAt?: string;
  lastSyncMode?: string | null;
  lastSyncSource?: string | null;
  lastSyncStatus?: string | null;
  lastSyncError?: string | null;
}

export interface ImapStatus {
  connected: boolean;
  host?: string | null;
  port?: number | null;
  useSsl?: boolean | null;
  username?: string | null;
  connectedAt?: string;
  lastSyncedAt?: string;
  lastSyncAttemptedAt?: string;
  lastSyncSucceededAt?: string;
  lastSyncMode?: string | null;
  lastSyncSource?: string | null;
  lastSyncStatus?: string | null;
  lastSyncError?: string | null;
}

export interface GmailManualSyncResult {
  queriesRun: number;
  candidateThreadCount: number;
  autoLinkedThreadCount: number;
  reviewThreadCount: number;
  unmatchedThreadCount: number;
  importedMessages: number;
  importedThreads: number;
  skippedMessages: number;
  lookbackDays: number;
  includeSpamTrash: boolean;
  syncedAt: string;
}

export interface GmailSuggestedJobCandidate {
  threadId: string;
  subject: string;
  latestDate?: string | null;
  companyName?: string | null;
  recruiterName?: string | null;
  recruiterEmail?: string | null;
  suggestedJobTitle?: string | null;
  routing: string;
  matchedQueries: string[];
  preview: string;
}

export interface GmailSuggestedJobsResponse {
  count: number;
  items: GmailSuggestedJobCandidate[];
}

export interface CreatedSuggestedGmailJobResult {
  jobApplicationId: number;
  companyId: number;
  threadId: string;
  imported: number;
  skipped: number;
}

export interface GmailRelinkResult {
  threadId: string;
  jobApplicationId: number;
  imported: number;
  skipped: number;
  unlinkedMessages: number;
}

export interface GmailUnlinkResult {
  threadId: string;
  jobApplicationId: number;
  removedMessages: number;
  decision: string;
}

export interface GmailMessageSummary {
  id: string;
  threadId: string;
  subject: string;
  from: string;
  to: string;
  date?: string;
  snippet: string;
}

export interface JobImportResult {
  title?: string;
  company?: string;
  location?: string;
  description?: string;
  translatedDescription?: string;
  language?: string;
  tags: string[];
  sourceUrl: string;
  source?: string;
  countryCode?: string;
  deadline?: string;
  success: boolean;
  parser?: string;
  error?: string;
}
