package logistica

import (
	"context"

	"photum-backend/internal/config"
	"photum-backend/internal/db/generated"
	"photum-backend/internal/notification"

	"github.com/google/uuid"
	"github.com/jackc/pgx/v5/pgtype"
)

type Service struct {
	queries      *generated.Queries
	notification *notification.Service
	cfg          *config.Config
}

func NewService(queries *generated.Queries, notification *notification.Service, cfg *config.Config) *Service {
	return &Service{
		queries:      queries,
		notification: notification,
		cfg:          cfg,
	}
}

type CreateCarroInput struct {
	AgendaID       string  `json:"agenda_id"`
	MotoristaID    *string `json:"motorista_id"`
	NomeMotorista  *string `json:"nome_motorista"`
	HorarioChegada *string `json:"horario_chegada"`
	Observacoes    *string `json:"observacoes"`
}

func (s *Service) CreateCarro(ctx context.Context, input CreateCarroInput) (*generated.LogisticaCarro, error) {
	agendaID, err := uuid.Parse(input.AgendaID)
	if err != nil {
		return nil, err
	}

	params := generated.CreateCarroParams{
		AgendaID: pgtype.UUID{Bytes: agendaID, Valid: true},
	}

	if input.MotoristaID != nil && *input.MotoristaID != "" {
		if parsed, err := uuid.Parse(*input.MotoristaID); err == nil {
			params.MotoristaID = pgtype.UUID{Bytes: parsed, Valid: true}
		}
	}
	if input.NomeMotorista != nil {
		params.NomeMotorista = pgtype.Text{String: *input.NomeMotorista, Valid: true}
	}
	if input.HorarioChegada != nil {
		params.HorarioChegada = pgtype.Text{String: *input.HorarioChegada, Valid: true}
	}
	if input.Observacoes != nil {
		params.Observacoes = pgtype.Text{String: *input.Observacoes, Valid: true}
	}

	carro, err := s.queries.CreateCarro(ctx, params)
	if err != nil {
		return nil, err
	}

	// Reset notification timestamp
	if err := s.queries.ResetLogisticsNotificationTimestamp(ctx, params.AgendaID); err != nil {
		// log error
	}

	return &carro, nil
}

func (s *Service) ListCarros(ctx context.Context, agendaID string) ([]generated.ListCarrosByAgendaIDRow, error) {
	parsedUUID, err := uuid.Parse(agendaID)
	if err != nil {
		return nil, err
	}
	return s.queries.ListCarrosByAgendaID(ctx, pgtype.UUID{Bytes: parsedUUID, Valid: true})
}

func (s *Service) DeleteCarro(ctx context.Context, id string) error {
	parsedUUID, err := uuid.Parse(id)
	if err != nil {
		return err
	}
	// Changed to capture AgendaID
	agendaID, err := s.queries.DeleteCarro(ctx, pgtype.UUID{Bytes: parsedUUID, Valid: true})
	if err != nil {
		return err
	}

	// Reset notification timestamp
	if err := s.queries.ResetLogisticsNotificationTimestamp(ctx, agendaID); err != nil {
		// Log error but don't fail the operation
		// log.Printf("Error resetting timestamp: %v", err)
	}

	return nil
}

// UpdateCarroInput matches the update fields
type UpdateCarroInput struct {
	MotoristaID    *string `json:"motorista_id"`
	NomeMotorista  *string `json:"nome_motorista"`
	HorarioChegada *string `json:"horario_chegada"`
	Observacoes    *string `json:"observacoes"`
}

func (s *Service) UpdateCarro(ctx context.Context, id string, input UpdateCarroInput) (*generated.LogisticaCarro, error) {
	parsedUUID, err := uuid.Parse(id)
	if err != nil {
		return nil, err
	}

	params := generated.UpdateCarroParams{
		ID: pgtype.UUID{Bytes: parsedUUID, Valid: true},
	}

	if input.MotoristaID != nil {
		if *input.MotoristaID == "" {
			params.MotoristaID = pgtype.UUID{Valid: false}
		} else {
			if parsed, err := uuid.Parse(*input.MotoristaID); err == nil {
				params.MotoristaID = pgtype.UUID{Bytes: parsed, Valid: true}
			}
		}
	}
	if input.NomeMotorista != nil {
		params.NomeMotorista = pgtype.Text{String: *input.NomeMotorista, Valid: true}
	}
	if input.HorarioChegada != nil {
		params.HorarioChegada = pgtype.Text{String: *input.HorarioChegada, Valid: true}
	}
	if input.Observacoes != nil {
		params.Observacoes = pgtype.Text{String: *input.Observacoes, Valid: true}
	}

	carro, err := s.queries.UpdateCarro(ctx, params)
	if err != nil {
		return nil, err
	}
	return &carro, nil
}

func (s *Service) AddPassageiro(ctx context.Context, carroID, profissionalID string) error {
	cID, err := uuid.Parse(carroID)
	if err != nil {
		return err
	}
	pID, err := uuid.Parse(profissionalID)
	if err != nil {
		return err
	}

	_, err = s.queries.AddPassageiro(ctx, generated.AddPassageiroParams{
		CarroID:        pgtype.UUID{Bytes: cID, Valid: true},
		ProfissionalID: pgtype.UUID{Bytes: pID, Valid: true},
	})
	if err != nil {
		return err
	}

	// Notification Logic - DISABLED (Moved to Manual Trigger)
	/*
		go func() {
			bgCtx := context.Background()

			// 1. Get Car Details (Driver, Time, AgendaID)
			carro, err := s.queries.GetCarroByID(bgCtx, pgtype.UUID{Bytes: cID, Valid: true})
			if err != nil {
				log.Printf("[Logistica Notification] Erro ao buscar carro: %v", err)
				return
			}

			// 2. Get Agenda Details (for Location)
			// We have agenda_id in carro, but need to fetch details
			agendaVal, err := s.queries.GetAgenda(bgCtx, carro.AgendaID)
			if err != nil {
				log.Printf("[Logistica Notification] Erro ao buscar agenda: %v", err)
				return
			}

			// 3. Get Professional (Passenger) Details
			prof, err := s.queries.GetProfissionalByID(bgCtx, pgtype.UUID{Bytes: pID, Valid: true})
			if err != nil {
				log.Printf("[Logistica Notification] Erro ao buscar passageiro: %v", err)
				return
			}

			if prof.Whatsapp.String == "" {
				return
			}

			// 4. Format Message
			motorista := "A definir"
			if carro.NomeMotorista.Valid {
				motorista = carro.NomeMotorista.String
			} else if carro.MotoristaNomeSistema.Valid {
				motorista = carro.MotoristaNomeSistema.String
			}

			horarioSaida := "A combinar"
			if carro.HorarioChegada.Valid {
				horarioSaida = carro.HorarioChegada.String
			}

			destino := "Local do Evento"
			if agendaVal.LocalEvento.Valid {
				destino = agendaVal.LocalEvento.String
			}

			msg := fmt.Sprintf("Olá *%s*! 🚐\n\nVocê foi adicionado à logística de transporte.\n\n*Motorista:* %s\n*Saída:* %s\n*Destino:* %s\n\nAcesse seu painel para mais detalhes.",
				prof.Nome,
				motorista,
				horarioSaida,
				destino,
			)

			if err := s.notification.SendWhatsApp(prof.Whatsapp.String, msg); err != nil {
				log.Printf("[Logistica Notification] Falha ao enviar: %v", err)
			}
		}()
	*/

	return nil
}

func (s *Service) RemovePassageiro(ctx context.Context, carroID, profissionalID string) error {
	cID, err := uuid.Parse(carroID)
	if err != nil {
		return err
	}
	pID, err := uuid.Parse(profissionalID)
	if err != nil {
		return err
	}
	return s.queries.RemovePassageiro(ctx, generated.RemovePassageiroParams{
		CarroID:        pgtype.UUID{Bytes: cID, Valid: true},
		ProfissionalID: pgtype.UUID{Bytes: pID, Valid: true},
	})
}

func (s *Service) ListPassageiros(ctx context.Context, carroID string) ([]generated.ListPassageirosByCarroIDRow, error) {
	cID, err := uuid.Parse(carroID)
	if err != nil {
		return nil, err
	}
	return s.queries.ListPassageirosByCarroID(ctx, pgtype.UUID{Bytes: cID, Valid: true})
}
