package com.mvrent.carrental.service;

import com.mvrent.carrental.model.*;
import com.mvrent.carrental.repository.CategoryRepository;
import com.mvrent.carrental.repository.OrganizationRepository;
import com.mvrent.carrental.repository.SystemConfigRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Central access to the Organization profile, SystemConfig singleton and the
 * category masters. The singletons are created on first read so the rest of the
 * app can always assume they exist.
 */
@Service
@RequiredArgsConstructor
public class ConfigService {

    private final OrganizationRepository organizationRepository;
    private final SystemConfigRepository systemConfigRepository;
    private final CategoryRepository categoryRepository;

    /* ---------- Organization ---------- */

    @Transactional
    public Organization getOrganization() {
        return organizationRepository.findAll().stream().findFirst()
                .orElseGet(() -> organizationRepository.save(
                        Organization.builder().name("MV Rent").currencyCode("INR").build()));
    }

    @Transactional
    public Organization saveOrganization(Organization form) {
        Organization org = getOrganization();
        org.setName(form.getName());
        org.setLegalName(form.getLegalName());
        org.setLogoUrl(form.getLogoUrl());
        org.setAddress(form.getAddress());
        org.setGstNumber(form.getGstNumber());
        org.setContactEmail(form.getContactEmail());
        org.setPhone(form.getPhone());
        org.setCurrencyCode(form.getCurrencyCode());
        return organizationRepository.save(org);
    }

    /* ---------- System config ---------- */

    @Transactional
    public SystemConfig getSystemConfig() {
        return systemConfigRepository.findAll().stream().findFirst()
                .orElseGet(() -> systemConfigRepository.save(SystemConfig.builder().build()));
    }

    @Transactional
    public SystemConfig saveSystemConfig(SystemConfig form) {
        SystemConfig cfg = getSystemConfig();
        cfg.setCurrencyCode(form.getCurrencyCode());
        cfg.setDefaultTaxPercent(form.getDefaultTaxPercent());
        cfg.setDefaultCommissionPercent(form.getDefaultCommissionPercent());
        cfg.setDefaultDriverDailyCharge(form.getDefaultDriverDailyCharge());
        cfg.setInvoicePrefix(form.getInvoicePrefix());
        cfg.setSettlementCycle(form.getSettlementCycle());
        return systemConfigRepository.save(cfg);
    }

    /* ---------- Categories ---------- */

    public List<Category> allCategories() {
        return categoryRepository.findAllByOrderByTypeAscNameAsc();
    }

    public List<Category> categoriesOfType(CategoryType type) {
        return categoryRepository.findByTypeAndActiveTrueOrderByName(type);
    }

    public Category findCategory(Long id) {
        return id == null ? null : categoryRepository.findById(id).orElse(null);
    }

    @Transactional
    public Category addCategory(CategoryType type, String name, String description) {
        if (categoryRepository.existsByTypeAndName(type, name)) {
            throw new IllegalArgumentException(type + " category '" + name + "' already exists");
        }
        return categoryRepository.save(Category.builder()
                .type(type).name(name).description(description).active(true).build());
    }

    @Transactional
    public void toggleCategory(Long id) {
        Category c = categoryRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("Category not found: " + id));
        c.setActive(!c.isActive());
    }

    @Transactional
    public void deleteCategory(Long id) {
        categoryRepository.deleteById(id);
    }
}
