package demo;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@Repository
class ItemRepository {
    List<String> findAll() { return List.of("pen", "book", "lamp"); }
}

@Service
class ItemService {
    private final ItemRepository repo;
    ItemService(ItemRepository repo) { this.repo = repo; }
    List<String> items() { return repo.findAll(); }
}

interface Notifier { String send(String msg); }

@Component
@Primary
class EmailNotifier implements Notifier { public String send(String m) { return "email:" + m; } }

@Component("sms")
class SmsNotifier implements Notifier { public String send(String m) { return "sms:" + m; } }

@Configuration
class AppConfig {
    @Bean
    String appName() { return "annotation-demo"; }
}

@ConfigurationProperties(prefix = "app")
@Validated
record AppProps(@NotBlank @Size(max = 40) String greeting, int maxItems) {}

@Configuration
@EnableConfigurationProperties(AppProps.class)
class PropsConfig {}

@Component
@Profile("dev")
class DevOnly { }

@RestController
@RequestMapping("/api")
class ItemController {
    private final ItemService service;
    private final Notifier primary;
    private final Notifier sms;
    private final AppProps props;
    @Value("${app.greeting}") String greeting;

    ItemController(ItemService service, Notifier primary, @Qualifier("sms") Notifier sms, AppProps props) {
        this.service = service; this.primary = primary; this.sms = sms; this.props = props;
    }

    @GetMapping("/items")
    List<String> items() { return service.items(); }

    @GetMapping("/items/{index}")
    String one(@PathVariable int index, @RequestParam(defaultValue = "plain") String style) {
        return style + ":" + service.items().get(index);
    }

    @PostMapping("/echo")
    Map<String, String> echo(@RequestBody Map<String, String> body) { return body; }

    @GetMapping("/notify")
    Map<String, String> notify(@RequestParam String msg) {
        return Map.of("primary", primary.send(msg), "qualified", sms.send(msg));
    }

    @GetMapping("/config")
    Map<String, Object> config() {
        return Map.of("value", greeting, "props.greeting", props.greeting(), "props.maxItems", props.maxItems());
    }
}
