from datetime import date, time

from django.core.management.base import BaseCommand

from apps.attendance.models import AttendanceDevice
from apps.leave.models import LeaveType
from apps.organization.models import Branch, Company, CompanyPolicy, Department, Designation, Shift
from apps.payroll.models import SalaryComponent


class Command(BaseCommand):
    help = "Create safe reference/master data for the first Shohoj Shop setup."

    def handle(self, *args, **options):
        company, _ = Company.objects.get_or_create(
            code="SHOHOJ",
            defaults={
                "name": "Shohoj Shop Clothing Ltd.",
                "legal_name": "Shohoj Shop Clothing Ltd.",
                "address": "23/8 Khilji Road, Block B, Mohammadpur, Dhaka 1207",
                "currency_code": "BDT",
                "timezone": "Asia/Dhaka",
            },
        )
        branch, _ = Branch.objects.get_or_create(
            company=company,
            code="HO",
            defaults={"name": "Head Office", "address": company.address},
        )
        for code, name in [
            ("PROD", "Production"), ("SALES", "Sales & Marketing"),
            ("HR", "HR & Admin"), ("ACC", "Accounts & Finance"),
            ("STORE", "Store"), ("IT", "IT"),
        ]:
            Department.objects.get_or_create(company=company, code=code, defaults={"name": name})
        for code, name in [
            ("MD", "Managing Director"), ("HRM", "HR Manager"),
            ("HRE", "HR Executive"), ("ACCO", "Accounts Officer"),
            ("PRODO", "Production Officer"), ("SALESE", "Sales Executive"),
            ("STOREO", "Store Officer"), ("ITS", "IT Support"),
        ]:
            Designation.objects.get_or_create(company=company, code=code, defaults={"name": name})
        Shift.objects.get_or_create(
            company=company, code="GEN",
            defaults={"name": "General Shift", "start_time": time(9, 0), "end_time": time(18, 0), "grace_minutes": 10, "break_minutes": 60},
        )
        for code, name, allocation, paid in [
            ("CL", "Casual Leave", 10, True), ("SL", "Sick Leave", 14, True),
            ("AL", "Annual Leave", 18, True), ("UL", "Unpaid Leave", 0, False),
        ]:
            LeaveType.objects.get_or_create(
                company=company, code=code,
                defaults={"name": name, "yearly_allocation": allocation, "is_paid": paid},
            )
        for code, name, kind, calc_type in [
            ("BASIC", "Basic Salary", "EARNING", "FIXED"),
            ("HOUSE", "House Rent / Gross Balance", "EARNING", "FORMULA"),
            ("MED", "Medical Allowance", "EARNING", "FIXED"),
            ("CONV", "Conveyance", "EARNING", "FIXED"),
            ("PF", "Provident Fund", "DEDUCTION", "FIXED"),
            ("TAX", "Tax", "DEDUCTION", "FIXED"),
        ]:
            component, _ = SalaryComponent.objects.get_or_create(
                company=company, code=code,
                defaults={"name": name, "kind": kind, "calculation_type": calc_type},
            )
            if component.calculation_type != calc_type:
                component.calculation_type = calc_type
                component.save(update_fields=["calculation_type", "updated_at"])
        CompanyPolicy.objects.get_or_create(
            company=company,
            effective_from=date(2020, 1, 1),
            defaults={
                "salary_day_divisor": 30,
                "monthly_working_hours": 208,
                "salary_proration_method": CompanyPolicy.ProrationMethod.ACTUAL_CALENDAR,
                "missing_workday_is_absent": True,
                "missing_punch_action": CompanyPolicy.MissingPunchAction.BLOCK,
                "half_day_deduction_fraction": 0.50,
                "ot_minimum_minutes": 30,
                "ot_rounding_minutes": 30,
                "ot_default_rate_multiplier": 1.50,
                "ot_weekly_off_multiplier": 2.00,
                "ot_holiday_multiplier": 2.00,
                "leave_manager_approval_required": True,
                "request_reference_prefix": "REQ",
                "payroll_reference_prefix": "PAY",
                "loan_reference_prefix": "LOAN",
                "notes": "Initial Local UAT policy. Review before production go-live.",
            },
        )
        AttendanceDevice.objects.get_or_create(
            company=company, branch=branch, name="FO-M1 Test Device",
            defaults={"vendor": "ZKTeco", "model": "FO-M1", "connection_mode": "TCP/IP", "port": 4370},
        )
        self.stdout.write(self.style.SUCCESS("Reference/master data is ready."))
