package dto

import "encoding/json"

// The kundali payload is grouped the way the app screens are: one key per tab,
// with the sub-sections nested underneath it. Every leaf holds the *unwrapped*
// "response" of its VedicAstroAPI endpoint, passed through untouched, so the
// vendor's own field names are what the client sees.
//
// Partial failure is by design. A leaf whose upstream call failed is omitted and
// named in CompleteKundaliResponse.Errors; the rest of the kundali still
// returns. Clients must treat any missing leaf as normal.
//
// A few sections are deliberately repeated across groups — personal
// characteristics under both Chart and Reports, mahadasha under both Dasha and
// Others — because that is how the screens read them. Each is fetched once and
// referenced twice.
type KundaliDetails struct {
	BasicDetails *KundaliBasicSection `json:"basic_details,omitempty"`

	Chart *KundaliChartSection `json:"chart,omitempty"`

	KP *KundaliKPSection `json:"kp,omitempty"`

	Ashtakvarga *KundaliAshtakvargaSection `json:"ashtakvarga,omitempty"`

	Dasha *KundaliDashaSection `json:"dasha,omitempty"`

	Reports *KundaliReportsSection `json:"reports,omitempty"`

	Others *KundaliOthersSection `json:"others,omitempty"`
}

//////////////////////////////////////////////////////////////
// Basic Details
//////////////////////////////////////////////////////////////

type KundaliBasicSection struct {

	// Request echoes the birth details the chart was cast from.
	Request *KundaliBirthDetails `json:"request"`

	Panchang json.RawMessage `json:"panchang,omitempty"`

	Ashtakvarga json.RawMessage `json:"ashtakvarga,omitempty"`

	ManglikDosh json.RawMessage `json:"manglik_dosh,omitempty"`
}

// KundaliBirthDetails is what the kundali was cast from, echoed back so the app
// can render the Basic Details header without keeping the request around.
type KundaliBirthDetails struct {
	Name string `json:"name"`

	Gender string `json:"gender"`

	BirthDate string `json:"birthDate"`

	BirthTime string `json:"birthTime"`

	BirthPlace string `json:"birthPlace"`

	Latitude float64 `json:"latitude"`

	Longitude float64 `json:"longitude"`

	Timezone float64 `json:"timezone"`

	Lang string `json:"lang"`

	ChartStyle string `json:"chart_style"`
}

//////////////////////////////////////////////////////////////
// Chart
//////////////////////////////////////////////////////////////

type KundaliChartSection struct {

	// Lagna (D1) chart image, plus every division fetched, keyed "D1"/"D9"/"D10".
	// Both point at this API's own chart-image proxy, never at VedicAstroAPI:
	// the upstream URL has to carry our API key, and these responses go to
	// unauthenticated clients.
	ChartImage string `json:"chart_image,omitempty"`

	ChartImages map[string]string `json:"chart_images,omitempty"`

	PlanetDetails json.RawMessage `json:"planet_details,omitempty"`

	PersonalCharacteristics json.RawMessage `json:"personal_characteristics,omitempty"`
}

//////////////////////////////////////////////////////////////
// KP
//////////////////////////////////////////////////////////////

type KundaliKPSection struct {
	KPHouses json.RawMessage `json:"kp_houses,omitempty"`

	KPPlanets json.RawMessage `json:"kp_planets,omitempty"`
}

//////////////////////////////////////////////////////////////
// Ashtakvarga
//////////////////////////////////////////////////////////////

type KundaliAshtakvargaSection struct {
	AshtakvargaChartImage string `json:"ashtakvarga_chart_image,omitempty"`

	Ashtakvarga json.RawMessage `json:"ashtakvarga,omitempty"`
}

//////////////////////////////////////////////////////////////
// Dasha
//////////////////////////////////////////////////////////////

type KundaliDashaSection struct {
	Vimshottari *KundaliVimshottariDasha `json:"vimshottari,omitempty"`

	Yogini *KundaliYoginiDasha `json:"yogini,omitempty"`
}

type KundaliVimshottariDasha struct {
	Mahadasha json.RawMessage `json:"mahadasha,omitempty"`

	MahadashaPredictions json.RawMessage `json:"mahadasha_predictions,omitempty"`
}

type KundaliYoginiDasha struct {
	YoginiDashaMain json.RawMessage `json:"yoginiDashaMain,omitempty"`

	YoginiDashaSub json.RawMessage `json:"yoginiDashaSub,omitempty"`
}

//////////////////////////////////////////////////////////////
// Reports
//////////////////////////////////////////////////////////////

type KundaliReportsSection struct {
	General *KundaliGeneralReport `json:"general,omitempty"`

	Remedies *KundaliRemedyReport `json:"remedies,omitempty"`

	Dosha *KundaliDoshaReport `json:"dosha,omitempty"`
}

type KundaliGeneralReport struct {
	PersonalCharacteristics json.RawMessage `json:"personal_characteristics,omitempty"`

	// Per-planet narrative reports, keyed by planet ("Sun" ... "Ketu").
	PlanetReport map[string]json.RawMessage `json:"planet_report,omitempty"`

	MahadashaPredictions json.RawMessage `json:"mahadasha_predictions,omitempty"`

	ListOfYogas json.RawMessage `json:"list_of_yogas,omitempty"`
}

type KundaliRemedyReport struct {
	RudrakshSuggestion json.RawMessage `json:"rudraksh_suggestion,omitempty"`

	GemSuggestion json.RawMessage `json:"gem_suggestion,omitempty"`

	// Numerology table — the radical number and its remedies.
	NumeroTable json.RawMessage `json:"numero_table,omitempty"`
}

type KundaliDoshaReport struct {
	MangalDosh json.RawMessage `json:"mangal_dosh,omitempty"`

	KaalsarpDosh json.RawMessage `json:"kaalsarp_dosh,omitempty"`

	SadeSatiTable json.RawMessage `json:"sade_sati_table,omitempty"`

	CurrentSadeSati json.RawMessage `json:"current_sade_sati,omitempty"`
}

//////////////////////////////////////////////////////////////
// Others
//////////////////////////////////////////////////////////////

type KundaliOthersSection struct {
	ExtendedKundliDetails json.RawMessage `json:"extended_kundli_details,omitempty"`

	AscendantReport json.RawMessage `json:"ascendant_report,omitempty"`

	// Keyed by division: D1 (lagna), D9 (navamsa), D10 (dasamsa).
	DivisionalCharts map[string]json.RawMessage `json:"divisional_charts,omitempty"`

	// Per-planet binnashtakvarga, keyed by planet.
	Binnashtakvarga map[string]json.RawMessage `json:"binnashtakvarga,omitempty"`

	// Twelve months of prediction, which the vendor delivers as four quarters.
	// It is keyed on the moon sign taken from planet_details, so it is absent
	// when the planet details themselves could not be fetched.
	AI12MonthPrediction json.RawMessage `json:"ai_12_month_prediction,omitempty"`

	PlanetaryAspects json.RawMessage `json:"planetary_aspects,omitempty"`

	PlanetsInHouses json.RawMessage `json:"planets_in_houses,omitempty"`

	Mahadasha json.RawMessage `json:"mahadasha,omitempty"`

	Antardasha json.RawMessage `json:"antardasha,omitempty"`
}

//////////////////////////////////////////////////////////////
// Response Envelope
//////////////////////////////////////////////////////////////

// CompleteKundaliResponse is one generated kundali as the app receives it.
type CompleteKundaliResponse struct {

	// Saved record id, or 0 when nothing was persisted (guest requests).
	ID uint `json:"id"`

	Name string `json:"name"`

	BirthDetails *KundaliBirthDetails `json:"birth_details"`

	// Download link for the full report PDF, built from the sections below and
	// served from /uploads/kundli/. Empty only when generation failed — see
	// Errors["pdf"].
	PDFURL string `json:"pdf_url"`

	// The vendor's own PDF link, when their PDF endpoint is available.
	VedicPDFURL string `json:"vedic_pdf_url"`

	// True when the caller was not authenticated.
	IsGuest bool `json:"is_guest"`

	// True when this kundali, and its details JSON, were written to the
	// database. Always false for a guest: no account would own the row.
	Saved bool `json:"saved"`

	// True when the sections were served from the in-process cache instead of
	// being fetched from VedicAstroAPI again.
	Cached bool `json:"cached"`

	Details *KundaliDetails `json:"details"`

	// Section key -> upstream failure, for whatever did not come back.
	Errors map[string]string `json:"errors,omitempty"`
}
