package kr.itn.itnhub.org;

import kr.itn.itnhub.AbstractDbTest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

class OrganizationMapperTest extends AbstractDbTest {

    @Autowired
    OrganizationMapper mapper;

    @Autowired
    JdbcTemplate jdbc;

    @BeforeEach
    void clean() {
        jdbc.update("delete from organization");
    }

    private Organization seedRow(String orgNo, String orgName, String dept) {
        Organization org = new Organization();
        org.setOrgNo(orgNo);
        org.setOrgName(orgName);
        org.setChannelSlug(orgNo);
        org.setDeptName(dept);
        org.setManagerName("담당자");
        org.setManagerTitle("과장");
        org.setManagerPhone("02-0000-0000");
        org.setManagerEmail("a@b.kr");
        return org;
    }

    @Test
    void 신규_기관을_넣고_다시_읽는다() {
        mapper.upsertBySeed(seedRow("001", "국제방송교류재단", "데이터정보화팀"));

        List<Organization> all = mapper.findAll();

        assertThat(all).hasSize(1);
        assertThat(all.get(0).getOrgNo()).isEqualTo("001");
        assertThat(all.get(0).getOrgName()).isEqualTo("국제방송교류재단");
        assertThat(all.get(0).getStatus()).isEqualTo(OrgStatus.READY);
    }

    @Test
    void 연번이_같아도_기관명이_다르면_별도_행이다() {
        mapper.upsertBySeed(seedRow("008", "경찰청", "데이터정책계"));
        mapper.upsertBySeed(seedRow("008", "경찰청_치안정책연구소", "연구지원과"));

        assertThat(mapper.findAll()).hasSize(2);
    }

    @Test
    void 시드_재실행은_기존_채널ID를_지우지_않는다() {
        mapper.upsertBySeed(seedRow("001", "국제방송교류재단", "데이터정보화팀"));
        Long id = mapper.findAll().get(0).getId();
        mapper.updateChannelIdMj(id, "chan-mj");
        mapper.updateChannelIdLaw(id, "chan-law");

        mapper.upsertBySeed(seedRow("001", "국제방송교류재단", "데이터정보화팀"));

        Organization after = mapper.findById(id);
        assertThat(after.getChannelIdMj()).isEqualTo("chan-mj");
        assertThat(after.getChannelIdLaw()).isEqualTo("chan-law");
        assertThat(after.getStatus()).isEqualTo(OrgStatus.ACTIVE);
    }

    @Test
    void 시드_재실행은_사람이_입력한_값을_덮어쓰지_않는다() {
        mapper.upsertBySeed(seedRow("001", "국제방송교류재단", "데이터정보화팀"));
        Organization org = mapper.findAll().get(0);
        org.setDeptName("사람이 고친 부서");
        mapper.updateContact(org);

        Organization reseeded = seedRow("001", "국제방송교류재단", "시트에 있던 부서");
        mapper.upsertBySeed(reseeded);

        assertThat(mapper.findById(org.getId()).getDeptName())
                .isEqualTo("사람이 고친 부서");
    }

    @Test
    void 시드_재실행은_비어_있던_칸만_채운다() {
        Organization blank = new Organization();
        blank.setOrgNo("009");
        blank.setOrgName("서울도서관");
        blank.setChannelSlug("009");
        mapper.upsertBySeed(blank);

        mapper.upsertBySeed(seedRow("009", "서울도서관", "정보서비스과"));

        Organization after = mapper.findAll().get(0);
        assertThat(after.getDeptName()).isEqualTo("정보서비스과");
        assertThat(after.getManagerEmail()).isEqualTo("a@b.kr");
    }

    @Test
    void 채널ID를_한쪽만_저장할_수_있다() {
        mapper.upsertBySeed(seedRow("002", "세종학당재단", "콘텐츠개발팀"));
        Long id = mapper.findAll().get(0).getId();

        mapper.updateChannelIdMj(id, "only-mj");

        Organization after = mapper.findById(id);
        assertThat(after.getChannelIdMj()).isEqualTo("only-mj");
        assertThat(after.getChannelIdLaw()).isNull();
        assertThat(after.getStatus()).isEqualTo(OrgStatus.PARTIAL);
    }

    @Test
    void 목록은_연번_오름차순이다() {
        mapper.upsertBySeed(seedRow("010", "국립아시아문화전당", "기획운영과"));
        mapper.upsertBySeed(seedRow("002", "세종학당재단", "콘텐츠개발팀"));
        mapper.upsertBySeed(seedRow("001", "국제방송교류재단", "데이터정보화팀"));

        assertThat(mapper.findAll())
                .extracting(Organization::getOrgNo)
                .containsExactly("001", "002", "010");
    }
}
