package com.developx.szpitale.ingest;

import com.developx.szpitale.load.CanonicalReader;
import com.developx.szpitale.model.*;
import com.developx.szpitale.model.enums.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

class OrganizationCompanyRoundTripTest {

    @TempDir
    Path tempDir;

    @Test
    void write_thenRead_preservesOrganizationsAndCompanies() throws Exception {
        Organization organization = new Organization(
            "org:fundacja-xyz",
            "Fundacja XYZ",
            "0000123456",
            null,
            List.of("https://ems.ms.gov.pl/fundacja-xyz")
        );

        Company company = new Company(
            "company:abc-sp-zoo",
            "ABC sp. z o.o.",
            "0000654321",
            "1234567890",
            "CEIDG123",
            List.of("https://wyszukiwarka-krs.ms.gov.pl/abc")
        );

        Person person = new Person(
            "person:jan-kochanowicz",
            "Jan Kochanowicz",
            "prof. dr hab. Jan Kochanowicz",
            List.of("prof.", "dr hab."),
            List.of("https://uskwb.pl/"),
            "prof. dr hab.",
            null
        );

        PersonOrganizationLink pol = new PersonOrganizationLink(
            "person:jan-kochanowicz",
            "org:fundacja-xyz",
            "Prezes Zarządu",
            LinkBasis.KRS,
            List.of("https://ems.ms.gov.pl/fundacja-xyz")
        );

        PersonCompanyLink pcl = new PersonCompanyLink(
            "person:jan-kochanowicz",
            "company:abc-sp-zoo",
            "Wspólnik",
            LinkBasis.KRS,
            List.of("https://wyszukiwarka-krs.ms.gov.pl/abc")
        );

        OrganizationLink orgLink = new OrganizationLink(
            "org:fundacja-xyz",
            "org:inna-fundacja",
            LinkBasis.NIP,
            "wspolny adres",
            List.of("https://ems.ms.gov.pl/fundacja-xyz")
        );

        CanonicalDataset dataset = new CanonicalDataset(
            "1.0",
            "podlaskie",
            LocalDateTime.now(),
            List.of(),
            List.of(person),
            List.of(),
            List.of(),
            List.of(),
            List.of(organization),
            List.of(company),
            List.of(pol),
            List.of(orgLink),
            List.of(pcl)
        );

        Path outputFile = tempDir.resolve("test-canonical.json");
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JavaTimeModule());
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        mapper.writeValue(outputFile.toFile(), dataset);

        CanonicalDataset readResult = CanonicalReader.readDataset(outputFile.toFile());

        assertNotNull(readResult.organizations());
        assertNotNull(readResult.companies());
        assertNotNull(readResult.personOrganizationLinks());
        assertNotNull(readResult.organizationLinks());
        assertNotNull(readResult.personCompanyLinks());

        assertEquals(1, readResult.organizations().size());
        assertEquals("org:fundacja-xyz", readResult.organizations().get(0).id());
        assertEquals("Fundacja XYZ", readResult.organizations().get(0).name());
        assertEquals("0000123456", readResult.organizations().get(0).krs());

        assertEquals(1, readResult.companies().size());
        assertEquals("company:abc-sp-zoo", readResult.companies().get(0).id());
        assertEquals("ABC sp. z o.o.", readResult.companies().get(0).name());
        assertEquals("1234567890", readResult.companies().get(0).nip());
        assertEquals("CEIDG123", readResult.companies().get(0).ceidgId());

        assertEquals(1, readResult.personOrganizationLinks().size());
        assertEquals("person:jan-kochanowicz", readResult.personOrganizationLinks().get(0).personId());
        assertEquals("org:fundacja-xyz", readResult.personOrganizationLinks().get(0).organizationId());
        assertEquals(LinkBasis.KRS, readResult.personOrganizationLinks().get(0).basis());

        assertEquals(1, readResult.organizationLinks().size());
        assertEquals("org:fundacja-xyz", readResult.organizationLinks().get(0).fromOrganizationId());
        assertEquals("org:inna-fundacja", readResult.organizationLinks().get(0).toOrganizationId());
        assertEquals(LinkBasis.NIP, readResult.organizationLinks().get(0).basis());

        assertEquals(1, readResult.personCompanyLinks().size());
        assertEquals("person:jan-kochanowicz", readResult.personCompanyLinks().get(0).personId());
        assertEquals("company:abc-sp-zoo", readResult.personCompanyLinks().get(0).companyId());
        assertEquals(LinkBasis.KRS, readResult.personCompanyLinks().get(0).basis());
    }
}
