from django.contrib import admin

from apps.rims.grants.models import (
    Application,
    ApplicantCommunityService,
    ApplicantEmployment,
    ApplicantFundingSource,
    ApplicantGroupMembership,
    ApplicantIncomeSource,
    ApplicantLeadershipPosition,
    ApplicantParent,
    ApplicantPriorEducation,
    ApplicantPublication,
    ApplicantReference,
    ApplicantTranscript,
    ApplicantVolunteering,
    ApplicationCollaborator,
    ApplicationDocument,
    ApplicationPartner,
    Award,
    AwardCloseoutRecord,
    AwardComment,
    AwardStudentMembership,
    BeneficiaryGroup,
    ChallengeApplicationProfile,
    ChallengeMilestoneReport,
    ConflictOfInterest,
    EligibilityRule,
    FellowshipProgressReport,
    FundingRecord,
    GrantBudgetLine,
    GrantCall,
    GrantCallDocument,
    HomeValidationEnumeratorDetail,
    HomeValidationParentDetail,
    HomeValidationRecord,
    ImplementationPlan,
    ImplementationPlanActivity,
    ImplementationPlanEvidence,
    ImplementationPlanIndicator,
    ImplementationPlanOutcome,
    ImplementationPlanOutput,
    MonitoringVisit,
    MonitoringVisitEvidence,
    PeriodicNarrativeReport,
    PsychometricAssessment,
    ReportComment,
    ReportLinkage,
    ReportPicture,
    Review,
    ReviewCriterion,
    RimsCapability,
)


class GrantCallDocumentInline(admin.TabularInline):
    model = GrantCallDocument
    extra = 0
    fields = ("label", "file", "is_guideline", "sort_order")


class EligibilityRuleInline(admin.TabularInline):
    model = EligibilityRule
    extra = 0


class GrantBudgetLineInline(admin.TabularInline):
    model = GrantBudgetLine
    extra = 0


class ReviewCriterionInline(admin.TabularInline):
    model = ReviewCriterion
    extra = 1
    fields = ("name", "scoring_method", "max_score", "weight", "sort_order", "description")


@admin.register(FundingRecord)
class FundingRecordAdmin(admin.ModelAdmin):
    list_display = ("public_grant_id", "title", "status", "amount", "currency", "start_date", "end_date")
    list_filter = ("status", "currency")
    search_fields = ("title", "public_grant_id")
    readonly_fields = ("created_at", "updated_at")
    inlines = [GrantBudgetLineInline]


@admin.register(AwardCloseoutRecord)
class AwardCloseoutRecordAdmin(admin.ModelAdmin):
    list_display = ("award", "updated_at")
    readonly_fields = ("created_at", "updated_at")


@admin.register(GrantCall)
class GrantCallAdmin(admin.ModelAdmin):
    list_display = ("title", "slug", "call_type", "status", "funding_record", "partner", "opens_at", "closes_at")
    list_filter = ("status", "call_type")
    # FSMField(protected=True): direct assignment forbidden — use model transitions, not the form.
    readonly_fields = ("status",)
    prepopulated_fields = {"slug": ("title",)}
    search_fields = ("title", "slug")
    autocomplete_fields = ("funding_record", "partner", "mou", "created_by")
    inlines = [GrantCallDocumentInline, EligibilityRuleInline, ReviewCriterionInline]
    filter_horizontal = ("institutions_scope",)


class ApplicationDocumentInline(admin.TabularInline):
    model = ApplicationDocument
    extra = 0


class ApplicationCollaboratorInline(admin.TabularInline):
    model = ApplicationCollaborator
    extra = 0


class ApplicationPartnerInline(admin.TabularInline):
    model = ApplicationPartner
    extra = 0


class ApplicantEmploymentInline(admin.TabularInline):
    model = ApplicantEmployment
    extra = 0


class ApplicantLeadershipPositionInline(admin.TabularInline):
    model = ApplicantLeadershipPosition
    extra = 0


class ApplicantParentInline(admin.TabularInline):
    model = ApplicantParent
    extra = 0


class ApplicantPublicationInline(admin.TabularInline):
    model = ApplicantPublication
    extra = 0


class ApplicantCommunityServiceInline(admin.TabularInline):
    model = ApplicantCommunityService
    extra = 0


class ApplicantVolunteeringInline(admin.TabularInline):
    model = ApplicantVolunteering
    extra = 0


class ApplicantGroupMembershipInline(admin.TabularInline):
    model = ApplicantGroupMembership
    extra = 0


class ApplicantIncomeSourceInline(admin.TabularInline):
    model = ApplicantIncomeSource
    extra = 0


class ApplicantFundingSourceInline(admin.TabularInline):
    model = ApplicantFundingSource
    extra = 0


class ApplicantReferenceInline(admin.TabularInline):
    model = ApplicantReference
    extra = 0


class ApplicantTranscriptInline(admin.TabularInline):
    model = ApplicantTranscript
    extra = 0


class ApplicantPriorEducationInline(admin.TabularInline):
    model = ApplicantPriorEducation
    extra = 0


@admin.register(Application)
class ApplicationAdmin(admin.ModelAdmin):
    list_display = ("call", "applicant", "status", "submitted_at")
    list_filter = ("status", "call")
    readonly_fields = ("status",)
    search_fields = ("applicant__email", "anonymized_code")
    inlines = [
        ApplicationDocumentInline,
        ApplicationCollaboratorInline,
        ApplicationPartnerInline,
        ApplicantEmploymentInline,
        ApplicantLeadershipPositionInline,
        ApplicantParentInline,
        ApplicantPublicationInline,
        ApplicantCommunityServiceInline,
        ApplicantVolunteeringInline,
        ApplicantGroupMembershipInline,
        ApplicantIncomeSourceInline,
        ApplicantFundingSourceInline,
        ApplicantReferenceInline,
        ApplicantTranscriptInline,
        ApplicantPriorEducationInline,
    ]


class AwardCommentInline(admin.TabularInline):
    model = AwardComment
    extra = 0
    readonly_fields = ("created_at",)


class AwardStudentMembershipInline(admin.TabularInline):
    model = AwardStudentMembership
    extra = 0


@admin.register(Award)
class AwardAdmin(admin.ModelAdmin):
    list_display = ("application", "amount", "currency", "project_end_date")
    inlines = [AwardCommentInline, AwardStudentMembershipInline]


@admin.register(Review)
class ReviewAdmin(admin.ModelAdmin):
    list_display = ("application", "reviewer", "total_score", "submitted_at")


@admin.register(ConflictOfInterest)
class ConflictOfInterestAdmin(admin.ModelAdmin):
    list_display = ("application", "reviewer", "has_conflict")


@admin.register(RimsCapability)
class RimsCapabilityAdmin(admin.ModelAdmin):
    """Holds RIMS permission definitions; rows are optional."""

    list_display = ("id",)

    def has_add_permission(self, request):
        return False

    def has_change_permission(self, request, obj=None):
        return False

    def has_delete_permission(self, request, obj=None):
        return False


@admin.register(ReviewCriterion)
class ReviewCriterionAdmin(admin.ModelAdmin):
    list_display = ("call", "name", "scoring_method", "max_score", "weight", "sort_order")
    list_filter = ("scoring_method", "call__call_type")
    search_fields = ("name", "call__title")
    ordering = ("call", "sort_order")


class HomeValidationEnumeratorDetailInline(admin.StackedInline):
    model = HomeValidationEnumeratorDetail
    extra = 0


class HomeValidationParentDetailInline(admin.StackedInline):
    model = HomeValidationParentDetail
    extra = 0


@admin.register(HomeValidationRecord)
class HomeValidationRecordAdmin(admin.ModelAdmin):
    list_display = ("application", "conducted_by", "visit_date", "recommendation", "recorded_at")
    list_filter = ("recommendation",)
    search_fields = ("application__applicant__email",)
    raw_id_fields = ("application", "conducted_by")
    inlines = [HomeValidationEnumeratorDetailInline, HomeValidationParentDetailInline]


@admin.register(BeneficiaryGroup)
class BeneficiaryGroupAdmin(admin.ModelAdmin):
    list_display = ("name",)
    search_fields = ("name",)


class ReportPictureInline(admin.TabularInline):
    model = ReportPicture
    extra = 0


class ReportLinkageInline(admin.TabularInline):
    model = ReportLinkage
    extra = 0


class ReportCommentInline(admin.TabularInline):
    model = ReportComment
    extra = 0
    readonly_fields = ("created_at",)


@admin.register(PeriodicNarrativeReport)
class PeriodicNarrativeReportAdmin(admin.ModelAdmin):
    list_display = ("award", "period_label", "status", "submitted_at", "accepted_at")
    list_filter = ("status",)
    search_fields = ("award__application__applicant__email", "period_label")
    raw_id_fields = ("award", "reporting_calendar_entry", "submitted_by", "accepted_by")
    # FSMField(protected=True): direct assignment forbidden — use model transitions, not the form.
    readonly_fields = ("status", "created_at", "updated_at")
    inlines = [ReportPictureInline, ReportLinkageInline, ReportCommentInline]


@admin.register(PsychometricAssessment)
class PsychometricAssessmentAdmin(admin.ModelAdmin):
    list_display = ("application", "surname", "other_names", "submitted_at")
    search_fields = ("application__applicant__email", "surname", "other_names")
    raw_id_fields = ("application",)
    readonly_fields = ("created_at", "updated_at")


@admin.register(ChallengeApplicationProfile)
class ChallengeApplicationProfileAdmin(admin.ModelAdmin):
    list_display = ("application", "innovation_stage", "prototype_status", "team_size")
    list_filter = ("innovation_stage", "prototype_status")
    raw_id_fields = ("application",)


@admin.register(ApplicationPartner)
class ApplicationPartnerAdmin(admin.ModelAdmin):
    list_display = ("application", "organization_name", "contact_person", "email")
    search_fields = ("organization_name", "contact_person", "email")
    raw_id_fields = ("application",)


@admin.register(FellowshipProgressReport)
class FellowshipProgressReportAdmin(admin.ModelAdmin):
    list_display = ("award", "period_label", "status", "submitted_at")
    list_filter = ("status",)
    raw_id_fields = ("award", "submitted_by", "reviewed_by")


@admin.register(ChallengeMilestoneReport)
class ChallengeMilestoneReportAdmin(admin.ModelAdmin):
    list_display = ("award", "period_label", "status", "prototype_status", "submitted_at")
    list_filter = ("status", "prototype_status")
    raw_id_fields = ("award", "submitted_by", "reviewed_by")


class ImplementationPlanOutputInline(admin.TabularInline):
    model = ImplementationPlanOutput
    extra = 0


class ImplementationPlanOutcomeInline(admin.TabularInline):
    model = ImplementationPlanOutcome
    extra = 0


class ImplementationPlanIndicatorInline(admin.TabularInline):
    model = ImplementationPlanIndicator
    extra = 0


class ImplementationPlanActivityInline(admin.TabularInline):
    model = ImplementationPlanActivity
    extra = 0
    fk_name = "output"


class ImplementationPlanEvidenceInline(admin.TabularInline):
    model = ImplementationPlanEvidence
    extra = 0


@admin.register(ImplementationPlan)
class ImplementationPlanAdmin(admin.ModelAdmin):
    list_display = ("award", "status", "submitted_at", "approved_at")
    list_filter = ("status",)
    raw_id_fields = ("award", "results_framework", "submitted_by", "approved_by")
    # FSMField(protected=True): direct assignment forbidden — use model transitions, not the form.
    readonly_fields = ("status", "created_at", "updated_at")
    inlines = [ImplementationPlanOutcomeInline]


@admin.register(ImplementationPlanOutcome)
class ImplementationPlanOutcomeAdmin(admin.ModelAdmin):
    list_display = ("plan", "title", "order")
    raw_id_fields = ("plan",)
    inlines = [ImplementationPlanOutputInline, ImplementationPlanIndicatorInline]


@admin.register(ImplementationPlanOutput)
class ImplementationPlanOutputAdmin(admin.ModelAdmin):
    list_display = ("outcome", "title", "order")
    raw_id_fields = ("outcome",)
    inlines = [ImplementationPlanActivityInline, ImplementationPlanIndicatorInline]


@admin.register(ImplementationPlanIndicator)
class ImplementationPlanIndicatorAdmin(admin.ModelAdmin):
    list_display = ("name", "outcome", "output", "means_of_verification", "reporting_frequency", "mel_indicator")
    raw_id_fields = ("outcome", "output", "mel_indicator")


@admin.register(ImplementationPlanActivity)
class ImplementationPlanActivityAdmin(admin.ModelAdmin):
    list_display = ("title", "output", "status", "percent_complete", "responsible_person")
    list_filter = ("status",)
    raw_id_fields = ("output", "parent", "responsible_person", "mel_logframe_row")
    filter_horizontal = ("depends_on",)
    inlines = [ImplementationPlanEvidenceInline]


class MonitoringVisitEvidenceInline(admin.TabularInline):
    model = MonitoringVisitEvidence
    extra = 0


@admin.register(MonitoringVisit)
class MonitoringVisitAdmin(admin.ModelAdmin):
    list_display = ("award", "visit_type", "scheduled_for", "conducted_at", "is_locked")
    list_filter = ("visit_type",)
    raw_id_fields = ("award", "activity", "initiated_by")
    inlines = [MonitoringVisitEvidenceInline]

    def is_locked(self, obj):
        return obj.is_locked
    is_locked.boolean = True
