package models

import "odoo-go/pkg/orm"

// initAccountRecurring registers account.move.recurring — recurring entry templates.
// Mirrors: odoo/addons/account/models/account_move.py (recurring entries feature)
//
// Allows defining templates that automatically generate journal entries
// on a schedule (daily, weekly, monthly, quarterly, yearly).
func initAccountRecurring() {
	m := orm.NewModel("account.move.recurring", orm.ModelOpts{
		Description: "Recurring Entry",
		Order:       "name",
	})

	m.AddFields(
		orm.Char("name", orm.FieldOpts{String: "Name", Required: true}),
		orm.Many2one("journal_id", "account.journal", orm.FieldOpts{String: "Journal", Required: true}),
		orm.Many2one("company_id", "res.company", orm.FieldOpts{String: "Company"}),
		orm.Selection("period", []orm.SelectionItem{
			{Value: "daily", Label: "Daily"},
			{Value: "weekly", Label: "Weekly"},
			{Value: "monthly", Label: "Monthly"},
			{Value: "quarterly", Label: "Quarterly"},
			{Value: "yearly", Label: "Yearly"},
		}, orm.FieldOpts{String: "Period", Required: true, Default: "monthly"}),
		orm.Date("date_next", orm.FieldOpts{String: "Next Date", Required: true}),
		orm.Date("date_end", orm.FieldOpts{String: "End Date"}),
		orm.Many2one("template_move_id", "account.move", orm.FieldOpts{String: "Template Entry"}),
		orm.Boolean("active", orm.FieldOpts{String: "Active", Default: true}),
		orm.Selection("state", []orm.SelectionItem{
			{Value: "draft", Label: "Draft"},
			{Value: "running", Label: "Running"},
			{Value: "done", Label: "Done"},
		}, orm.FieldOpts{String: "Status", Default: "draft"}),
	)

	// action_start: draft -> running
	m.RegisterMethod("action_start", func(rs *orm.Recordset, args ...interface{}) (interface{}, error) {
		env := rs.Env()
		for _, id := range rs.IDs() {
			env.Tx().Exec(env.Ctx(),
				`UPDATE account_move_recurring SET state = 'running' WHERE id = $1 AND state = 'draft'`, id)
		}
		return true, nil
	})

	// action_done: running -> done
	m.RegisterMethod("action_done", func(rs *orm.Recordset, args ...interface{}) (interface{}, error) {
		env := rs.Env()
		for _, id := range rs.IDs() {
			env.Tx().Exec(env.Ctx(),
				`UPDATE account_move_recurring SET state = 'done' WHERE id = $1`, id)
		}
		return true, nil
	})

	// action_generate: create journal entries from the template and advance next date.
	// Mirrors: odoo/addons/account/models/account_move.py _cron_recurring_entries()
	m.RegisterMethod("action_generate", func(rs *orm.Recordset, args ...interface{}) (interface{}, error) {
		env := rs.Env()
		for _, recID := range rs.IDs() {
			var templateID *int64
			var dateNext, period string
			var dateEnd *string
			err := env.Tx().QueryRow(env.Ctx(),
				`SELECT template_move_id, date_next::text, period, date_end::text
				 FROM account_move_recurring WHERE id = $1 AND state = 'running'`, recID,
			).Scan(&templateID, &dateNext, &period, &dateEnd)
			if err != nil {
				continue // not running or not found
			}

			if templateID == nil || *templateID == 0 {
				continue
			}

			// Check if past end date
			if dateEnd != nil && dateNext > *dateEnd {
				env.Tx().Exec(env.Ctx(),
					`UPDATE account_move_recurring SET state = 'done' WHERE id = $1`, recID)
				continue
			}

			// Copy the template move with the next date
			templateRS := env.Model("account.move").Browse(*templateID)
			newMove, err := templateRS.Copy(orm.Values{"date": dateNext})
			if err != nil {
				continue
			}
			_ = newMove

			// Advance next date based on period
			var interval string
			switch period {
			case "daily":
				interval = "1 day"
			case "weekly":
				interval = "7 days"
			case "monthly":
				interval = "1 month"
			case "quarterly":
				interval = "3 months"
			case "yearly":
				interval = "1 year"
			default:
				interval = "1 month"
			}

			env.Tx().Exec(env.Ctx(),
				`UPDATE account_move_recurring SET date_next = date_next + $1::interval WHERE id = $2`,
				interval, recID)
		}
		return true, nil
	})
}
