package model

import (
	"errors"
	"time"

	"github.com/openaccounting/oa-server/core/model/types"
)

type AttachmentInterface interface {
	CreateAttachment(*types.Attachment) (*types.Attachment, error)
	GetAttachmentsByTransaction(string, string, string) ([]*types.Attachment, error)
	GetAttachment(string, string, string, string) (*types.Attachment, error)
	DeleteAttachment(string, string, string, string) error
}

func (model *Model) CreateAttachment(attachment *types.Attachment) (*types.Attachment, error) {
	if attachment.Id == "" {
		return nil, errors.New("attachment ID required")
	}

	if attachment.TransactionId == "" {
		return nil, errors.New("transaction ID required")
	}

	if attachment.OrgId == "" {
		return nil, errors.New("organization ID required")
	}

	if attachment.UserId == "" {
		return nil, errors.New("user ID required")
	}

	if attachment.FileName == "" {
		return nil, errors.New("file name required")
	}

	if attachment.FilePath == "" {
		return nil, errors.New("file path required")
	}

	// Set upload timestamp
	attachment.Uploaded = time.Now()
	attachment.Deleted = false

	// Save to database
	err := model.db.InsertAttachment(attachment)
	if err != nil {
		return nil, err
	}

	return attachment, nil
}

func (model *Model) GetAttachmentsByTransaction(transactionId, orgId, userId string) ([]*types.Attachment, error) {
	if transactionId == "" {
		return nil, errors.New("transaction ID required")
	}

	if orgId == "" {
		return nil, errors.New("organization ID required")
	}

	if userId == "" {
		return nil, errors.New("user ID required")
	}

	// First verify the user has access to the transaction
	tx, err := model.GetTransaction(transactionId, orgId, userId)
	if err != nil {
		return nil, err
	}
	if tx == nil {
		return nil, errors.New("transaction not found or access denied")
	}

	// Get attachments for the transaction
	attachments, err := model.db.GetAttachmentsByTransaction(transactionId, orgId)
	if err != nil {
		return nil, err
	}

	return attachments, nil
}

func (model *Model) GetAttachment(attachmentId, transactionId, orgId, userId string) (*types.Attachment, error) {
	if attachmentId == "" {
		return nil, errors.New("attachment ID required")
	}

	if transactionId == "" {
		return nil, errors.New("transaction ID required")
	}

	if orgId == "" {
		return nil, errors.New("organization ID required")
	}

	if userId == "" {
		return nil, errors.New("user ID required")
	}

	// First verify the user has access to the transaction
	tx, err := model.GetTransaction(transactionId, orgId, userId)
	if err != nil {
		return nil, err
	}
	if tx == nil {
		return nil, errors.New("transaction not found or access denied")
	}

	// Get the attachment
	attachment, err := model.db.GetAttachment(attachmentId, transactionId, orgId)
	if err != nil {
		return nil, err
	}

	return attachment, nil
}

func (model *Model) DeleteAttachment(attachmentId, transactionId, orgId, userId string) error {
	if attachmentId == "" {
		return errors.New("attachment ID required")
	}

	if transactionId == "" {
		return errors.New("transaction ID required")
	}

	if orgId == "" {
		return errors.New("organization ID required")
	}

	if userId == "" {
		return errors.New("user ID required")
	}

	// First verify the user has access to the transaction
	tx, err := model.GetTransaction(transactionId, orgId, userId)
	if err != nil {
		return err
	}
	if tx == nil {
		return errors.New("transaction not found or access denied")
	}

	// Verify the attachment exists and belongs to the transaction
	attachment, err := model.db.GetAttachment(attachmentId, transactionId, orgId)
	if err != nil {
		return err
	}
	if attachment == nil {
		return errors.New("attachment not found")
	}

	// Soft delete the attachment
	err = model.db.DeleteAttachment(attachmentId, transactionId, orgId)
	if err != nil {
		return err
	}

	return nil
}