// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
//
// SPDX-License-Identifier: AGPL-3.0-or-later

package lunatask

import "time"

// TaskBuilder provides a fluent interface for constructing CreateTaskRequest.
type TaskBuilder struct {
	req CreateTaskRequest
}

// NewTask creates a new TaskBuilder with the required name field.
func NewTask(name string) *TaskBuilder {
	return &TaskBuilder{req: CreateTaskRequest{Name: name}}
}

// InArea sets the area ID for the task.
func (b *TaskBuilder) InArea(areaID string) *TaskBuilder {
	b.req.AreaID = &areaID
	return b
}

// InGoal sets the goal ID for the task.
func (b *TaskBuilder) InGoal(goalID string) *TaskBuilder {
	b.req.GoalID = &goalID
	return b
}

// WithNote sets the note/description for the task.
func (b *TaskBuilder) WithNote(note string) *TaskBuilder {
	b.req.Note = &note
	return b
}

// WithStatus sets the task status (later, next, started, waiting, completed).
func (b *TaskBuilder) WithStatus(status string) *TaskBuilder {
	b.req.Status = &status
	return b
}

// WithMotivation sets the motivation (must, should, want).
func (b *TaskBuilder) WithMotivation(motivation string) *TaskBuilder {
	b.req.Motivation = &motivation
	return b
}

// WithEstimate sets the time estimate in minutes (0-720).
func (b *TaskBuilder) WithEstimate(minutes int) *TaskBuilder {
	b.req.Estimate = &minutes
	return b
}

// WithPriority sets the priority (-2 to 2: lowest, low, neutral, high, highest).
func (b *TaskBuilder) WithPriority(priority int) *TaskBuilder {
	b.req.Priority = &priority
	return b
}

// WithEisenhower sets the Eisenhower matrix category (0-4).
func (b *TaskBuilder) WithEisenhower(eisenhower int) *TaskBuilder {
	b.req.Eisenhower = &eisenhower
	return b
}

// ScheduledOn sets the scheduled date for the task.
func (b *TaskBuilder) ScheduledOn(date Date) *TaskBuilder {
	b.req.ScheduledOn = &date
	return b
}

// CompletedAt sets the completion timestamp.
func (b *TaskBuilder) CompletedAt(t time.Time) *TaskBuilder {
	b.req.CompletedAt = &t
	return b
}

// FromSource sets the external source integration.
func (b *TaskBuilder) FromSource(source, sourceID string) *TaskBuilder {
	b.req.Source = &source
	b.req.SourceID = &sourceID
	return b
}

// Build returns the constructed CreateTaskRequest.
func (b *TaskBuilder) Build() *CreateTaskRequest {
	return &b.req
}

// TaskUpdateBuilder provides a fluent interface for constructing UpdateTaskRequest.
type TaskUpdateBuilder struct {
	req UpdateTaskRequest
}

// NewTaskUpdate creates a new TaskUpdateBuilder.
func NewTaskUpdate() *TaskUpdateBuilder {
	return &TaskUpdateBuilder{}
}

// Name sets the task name.
func (b *TaskUpdateBuilder) Name(name string) *TaskUpdateBuilder {
	b.req.Name = &name
	return b
}

// InArea sets the area ID for the task.
func (b *TaskUpdateBuilder) InArea(areaID string) *TaskUpdateBuilder {
	b.req.AreaID = &areaID
	return b
}

// InGoal sets the goal ID for the task.
func (b *TaskUpdateBuilder) InGoal(goalID string) *TaskUpdateBuilder {
	b.req.GoalID = &goalID
	return b
}

// WithNote sets the note/description for the task.
func (b *TaskUpdateBuilder) WithNote(note string) *TaskUpdateBuilder {
	b.req.Note = &note
	return b
}

// WithStatus sets the task status (later, next, started, waiting, completed).
func (b *TaskUpdateBuilder) WithStatus(status string) *TaskUpdateBuilder {
	b.req.Status = &status
	return b
}

// WithMotivation sets the motivation (must, should, want).
func (b *TaskUpdateBuilder) WithMotivation(motivation string) *TaskUpdateBuilder {
	b.req.Motivation = &motivation
	return b
}

// WithEstimate sets the time estimate in minutes (0-720).
func (b *TaskUpdateBuilder) WithEstimate(minutes int) *TaskUpdateBuilder {
	b.req.Estimate = &minutes
	return b
}

// WithPriority sets the priority (-2 to 2: lowest, low, neutral, high, highest).
func (b *TaskUpdateBuilder) WithPriority(priority int) *TaskUpdateBuilder {
	b.req.Priority = &priority
	return b
}

// WithEisenhower sets the Eisenhower matrix category (0-4).
func (b *TaskUpdateBuilder) WithEisenhower(eisenhower int) *TaskUpdateBuilder {
	b.req.Eisenhower = &eisenhower
	return b
}

// ScheduledOn sets the scheduled date for the task.
func (b *TaskUpdateBuilder) ScheduledOn(date Date) *TaskUpdateBuilder {
	b.req.ScheduledOn = &date
	return b
}

// CompletedAt sets the completion timestamp.
func (b *TaskUpdateBuilder) CompletedAt(t time.Time) *TaskUpdateBuilder {
	b.req.CompletedAt = &t
	return b
}

// Build returns the constructed UpdateTaskRequest.
func (b *TaskUpdateBuilder) Build() *UpdateTaskRequest {
	return &b.req
}

// NoteBuilder provides a fluent interface for constructing CreateNoteRequest.
type NoteBuilder struct {
	req CreateNoteRequest
}

// NewNote creates a new NoteBuilder.
func NewNote() *NoteBuilder {
	return &NoteBuilder{}
}

// WithName sets the note name/title.
func (b *NoteBuilder) WithName(name string) *NoteBuilder {
	b.req.Name = &name
	return b
}

// WithContent sets the note content.
func (b *NoteBuilder) WithContent(content string) *NoteBuilder {
	b.req.Content = &content
	return b
}

// InNotebook sets the notebook ID.
func (b *NoteBuilder) InNotebook(notebookID string) *NoteBuilder {
	b.req.NotebookID = &notebookID
	return b
}

// FromSource sets the external source integration.
func (b *NoteBuilder) FromSource(source, sourceID string) *NoteBuilder {
	b.req.Source = &source
	b.req.SourceID = &sourceID
	return b
}

// Build returns the constructed CreateNoteRequest.
func (b *NoteBuilder) Build() *CreateNoteRequest {
	return &b.req
}

// JournalEntryBuilder provides a fluent interface for constructing CreateJournalEntryRequest.
type JournalEntryBuilder struct {
	req CreateJournalEntryRequest
}

// NewJournalEntry creates a new JournalEntryBuilder with the required date.
func NewJournalEntry(date Date) *JournalEntryBuilder {
	return &JournalEntryBuilder{req: CreateJournalEntryRequest{DateOn: date}}
}

// WithName sets the entry title (defaults to weekday name if omitted).
func (b *JournalEntryBuilder) WithName(name string) *JournalEntryBuilder {
	b.req.Name = &name
	return b
}

// WithContent sets the Markdown content.
func (b *JournalEntryBuilder) WithContent(content string) *JournalEntryBuilder {
	b.req.Content = &content
	return b
}

// Build returns the constructed CreateJournalEntryRequest.
func (b *JournalEntryBuilder) Build() *CreateJournalEntryRequest {
	return &b.req
}

// PersonBuilder provides a fluent interface for constructing CreatePersonRequest.
type PersonBuilder struct {
	req CreatePersonRequest
}

// NewPerson creates a new PersonBuilder.
func NewPerson() *PersonBuilder {
	return &PersonBuilder{}
}

// WithFirstName sets the person's first name.
func (b *PersonBuilder) WithFirstName(name string) *PersonBuilder {
	b.req.FirstName = &name
	return b
}

// WithLastName sets the person's last name.
func (b *PersonBuilder) WithLastName(name string) *PersonBuilder {
	b.req.LastName = &name
	return b
}

// WithRelationshipStrength sets the relationship strength category.
func (b *PersonBuilder) WithRelationshipStrength(strength string) *PersonBuilder {
	b.req.RelationshipStrength = &strength
	return b
}

// FromSource sets the external source integration.
func (b *PersonBuilder) FromSource(source, sourceID string) *PersonBuilder {
	b.req.Source = &source
	b.req.SourceID = &sourceID
	return b
}

// Build returns the constructed CreatePersonRequest.
func (b *PersonBuilder) Build() *CreatePersonRequest {
	return &b.req
}

// TimelineNoteBuilder provides a fluent interface for constructing CreatePersonTimelineNoteRequest.
type TimelineNoteBuilder struct {
	req CreatePersonTimelineNoteRequest
}

// NewTimelineNote creates a new TimelineNoteBuilder with the required person ID.
func NewTimelineNote(personID string) *TimelineNoteBuilder {
	return &TimelineNoteBuilder{req: CreatePersonTimelineNoteRequest{PersonID: personID}}
}

// OnDate sets the date for the timeline note.
func (b *TimelineNoteBuilder) OnDate(date Date) *TimelineNoteBuilder {
	b.req.DateOn = &date
	return b
}

// WithContent sets the Markdown content.
func (b *TimelineNoteBuilder) WithContent(content string) *TimelineNoteBuilder {
	b.req.Content = &content
	return b
}

// Build returns the constructed CreatePersonTimelineNoteRequest.
func (b *TimelineNoteBuilder) Build() *CreatePersonTimelineNoteRequest {
	return &b.req
}
