/**
 * Live Tracking Feature - Type Definitions
 * Single source of truth for all TypeScript interfaces and constants
 */

// -----------------------------------------------------------------------
// Raw DB row from hubspotDealData table
// New CRM-synced fields are nullable — populated by HubSpot sync
// -----------------------------------------------------------------------
export type HubspotDeal = {
  id: string;
  dealId: string;
  dealname: string | null;
  dealstage: string | null;
  companyId: string | null;
  projectCode: string | null;
  landlordPropertyId: string | null;
  uprn: string | null;
  outcome: string | null;
  outcomeNotes: string | null;
  majorConditionIssueDescription: string | null;
  majorConditionIssuePhotos: string | null;
  majorConditionIssuePhotosS3: string | null;
  coordinationStatus: string | null;
  designStatus: string | null;
  bookingStatus: string | null;

  // ── CRM-synced additions ──────────────────────────────────────────────
  pashubLink: string | null;
  sharepointLink: string | null;
  dampMouldFlag: string | null;           // coordinator-stage damp/mould flag
  dampMouldAndRepairComments: string | null; // coordinator damp/mould comments
  coordinationComments: string | null;
  domnasurveyRequired: boolean | null;
  preSapScore: string | null;             // kept as text (HubSpot returns strings)
  coordinator: string | null;
  ioeV1Date: Date | null;
  ioeV2Date: Date | null;
  ioeV3Date: Date | null;
  proposedMeasures: string | null;
  approvedPackage: string | null;
  designer: string | null;
  designDate: Date | null;
  actualMeasuresInstalled: string | null;
  installer: string | null;
  installerHandover: string | null;
  lodgementStatus: string | null;
  measuresLodgementDate: Date | null;
  fullLodgementDate: Date | null;
  confirmedSurveyDate: Date | null;
  confirmedSurveyTime: string | null;
  surveyedDate: Date | null;
  designType: string | null;
  eiScore: string | null;
  eiScorePotential: string | null;
  epcSapScore: string | null;
  potentialPostSapScoreDropdown: string | null;
  epcPrn: string | null;

  // ── New per-deal workflow fields (issue #249 slice) ────────────────────
  surveyType: string | null;
  measuresForPibiOrdered: string | null;
  pibiOrderDate: Date | null;
  pibiCompletedDate: Date | null;
  propertyHaltedDate: Date | null;
  propertyHaltedReason: string | null;
  technicalApprovedMeasuresForInstall: string | null;
  domnaSurveyType: string | null;
  domnaSurveyDate: Date | null;

  batch: string | null;
  batchDescription: string | null;

  // ── Planning fields (issue: extra PM columns) ─────────────────────────
  planningAuthority: string | null;
  designatedArea: string | null;
  article4PdRights: string | null;
  listedBuilding: string | null;
  designConstraints: string | null;
  planningComments: string | null;
  planningStatus: string | null;
  planningSuggestedApproach: string | null;

  createdAt: Date;
  updatedAt: Date;
};

// -----------------------------------------------------------------------
// Stage classification result — human-readable display labels
// Full end-to-end pipeline: assessment → coordination → design →
// install → lodgement → completed (funded)
// -----------------------------------------------------------------------
export type DisplayStage =
  | "Scope & Planning"
  | "Booking in Progress"
  | "Assessment in Progress"
  | "Coordination in Progress"
  | "Design in Progress"
  | "Installation in Progress"
  | "Installation Complete"
  | "At Lodgement"
  | "At Post Survey"
  | "Project Complete"
  | "Queries"
  | "Removed from Bookings"
  | "Removed from Program"
  | "Unknown Stage";

// -----------------------------------------------------------------------
// A classified deal — original row plus its resolved display stage
// -----------------------------------------------------------------------
export type ClassifiedDeal = HubspotDeal & {
  displayStage: DisplayStage;
};

// -----------------------------------------------------------------------
// One entry in the stage progress bar list
// -----------------------------------------------------------------------
export type StageProgressItem = {
  stage: DisplayStage;
  count: number;
  percentage: number; // out of non-query total
  deals: ClassifiedDeal[];
};

// -----------------------------------------------------------------------
// Damp & mould risk comparison (survey-stage vs coordination-stage flags)
// -----------------------------------------------------------------------
export type DampMouldRiskData = {
  surveyFlagCount: number;         // majorConditionIssuePhotosS3 not null
  coordinatorFlagCount: number;    // dampMouldFlag not null/non-empty
  bothFlaggedCount: number;        // flagged at both stages (highest risk)
  totalDeals: number;
  surveyFlagDeals: ClassifiedDeal[];
  coordinatorFlagDeals: ClassifiedDeal[];
};

// -----------------------------------------------------------------------
// Pipeline funnel data — dual counts per stage
// -----------------------------------------------------------------------
export type FunnelStage = {
  stage: DisplayStage;
  currentCount: number;     // deals at exactly this stage right now
  currentPct: number;       // as % of non-query total
  cumulativeCount: number;  // deals that have reached this stage or beyond
  cumulativePct: number;
};

// -----------------------------------------------------------------------
// All computed data for the ProgressOverview component
// -----------------------------------------------------------------------
export type ProjectProgressData = {
  stageProgress: StageProgressItem[];
  queriesDeals: ClassifiedDeal[];
  completedDeals: ClassifiedDeal[];
  completedCount: number;
  completedPercentage: number; // out of non-query total
  nonQueryTotal: number;
  totalDeals: number;
  dampMouldRisk: DampMouldRiskData;
  funnelStages: FunnelStage[];
};

// -----------------------------------------------------------------------
// What LiveTracker receives from page.tsx for one project
// -----------------------------------------------------------------------
export type ProjectData = {
  projectCode: string;
  progress: ProjectProgressData;
  allDeals: ClassifiedDeal[]; // for table drill-downs within project
};

// -----------------------------------------------------------------------
// Portfolio capability for the current viewing user
// -----------------------------------------------------------------------
export type PortfolioCapabilityType = ("approver" | "contractor")[];

// Approved measure names per HubSpot deal ID
export type ApprovalsByDeal = Record<string, string[]>;

export type EffectiveRemovalState = "none" | "pending_removal" | "removed" | "pending_re_addition";
export type RemovalStatusByDeal = Record<string, EffectiveRemovalState>;

// -----------------------------------------------------------------------
// Removal request record returned by the API
// -----------------------------------------------------------------------
export type RemovalRequest = {
  id: string;
  hubspotDealId: string;
  type: "removal" | "re_addition";
  status: "pending" | "approved" | "declined";
  reason: string;
  requestedByEmail: string;
  requestedAt: string;
  reviewedByEmail: string | null;
  reviewedAt: string | null;
};

// -----------------------------------------------------------------------
// Top-level props for LiveTracker (client root)
// -----------------------------------------------------------------------
export type InstructedMeasuresByDeal = Record<string, string[]>;

export type LiveTrackerProps = {
  projects: ProjectData[];
  totalDeals: number;
  majorConditionDeals: ClassifiedDeal[]; // for Awaab's Law card
  docStatusMap: DocStatusMap;
  userCapability: PortfolioCapabilityType;
  approvalsByDeal: ApprovalsByDeal;
  instructedMeasuresByDeal: InstructedMeasuresByDeal;
  removalStatusByDeal: RemovalStatusByDeal;
  portfolioId: string;
  userRole: string;
  userEmail: string;
};

// -----------------------------------------------------------------------
// Table drill-down shape (stays in LiveTracker state)
// columns can include computed ClassifiedDeal fields (e.g. displayStage)
// -----------------------------------------------------------------------
export type TableModal = {
  stage: string;
  data: ClassifiedDeal[];
  columns: (keyof ClassifiedDeal)[];
  columnLabels: Partial<Record<keyof ClassifiedDeal, string>>;
  breakdown?: Record<string, ClassifiedDeal[]>;
};

// -----------------------------------------------------------------------
// Document drawer types
// -----------------------------------------------------------------------
export type PropertyDocument = {
  id: string;
  s3FileKey: string;            // S3 object key — used directly for presigned URL
  s3FileBucket: string;         // S3 bucket name
  docType: string;              // fileType enum value
  s3UploadTimestamp: string;    // ISO string
  uprn: string | null;
  landlordPropertyId: string | null;
  measureName: string | null;   // set for install docs
};

// Mandatory retrofit assessment doc types (used for completeness check — ecmk types are optional)
export const EXPECTED_RETROFIT_ASSESSMENT_DOC_TYPES = [
  "photo_pack",
  "site_note",
  "rd_sap_site_note",
  "pas_2023_ventilation",
  "pas_2023_condition",
  "pas_2023_property",
  "pas_2023_occupancy",
] as const;

// All survey-adjacent types (including optional ecmk docs) — used for display categorisation
export const SURVEY_ALL_DOC_TYPES = new Set<string>([
  ...EXPECTED_RETROFIT_ASSESSMENT_DOC_TYPES,
  "ecmk_site_note",
  "ecmk_rd_sap_site_note",
  "ecmk_survey_xml",
  "pas_significance",
  "par_photo_pack",
]);

// Coordination doc types
export const COORDINATION_DOC_TYPES = new Set<string>([
  "improvement_option_evaluation",
  "medium_term_improvement_plan"
]);

// Design doc types
export const DESIGN_DOC_TYPES = new Set<string>([
  "retrofit_design_doc"
]);

// Per-measure document upload progress
export type MeasureDocProgress = {
  measureName: string;
  required: string[];    // required fileType values for this measure
  uploaded: string[];    // required fileType values that have been uploaded
  isComplete: boolean;
  uploadedCount: number;
  requiredCount: number;
};

export type DocStatus = {
  // Retrofit assessment docs
  presentSurveyTypes: string[];
  hasSurveyDocs: boolean;
  isSurveyComplete: boolean; // all 8 EXPECTED_RETROFIT_ASSESSMENT_DOC_TYPES present (ecmk not counted)
  // Install docs
  hasInstallDocs: boolean;
  installStatus: "none" | "partial" | "hasDocs" | "all";
  // "all"     = all required docs uploaded for every proposed measure
  // "partial" = some (but not all) proposed measures have complete docs
  // "hasDocs" = has install docs but no measures defined on the deal
  // "none"    = no install docs at all
  measureProgress: MeasureDocProgress[]; // one entry per proposed measure
};

export type DocStatusMap = Record<string, DocStatus>; // keyed by dealId string

export type DocumentDrawerState = {
  open: boolean;
  dealId: string | null;
  uprn: string | null;
  landlordPropertyId: string | null;
  dealname: string | null;
  batch: string | null;
  batchDescription: string | null;
};

// -----------------------------------------------------------------------
// Surveyor outcome constants (single source of truth)
// -----------------------------------------------------------------------
export const SURVEYOR_OUTCOMES = [
  "Surveyed",
  "Surveyed - Pending Upload",
  "EPC Completed",
  "Tenant Refusal",
  "Other",
  "Not Viable",
  "Not Attempted",
  "No Answer",
  "Cancelled / No Show",
  "Rescheduled",
] as const;

export type SurveyorOutcome = (typeof SURVEYOR_OUTCOMES)[number];

// Outcomes that represent real completed survey history. Take precedence over
// a "Do Not Book" booking status — the property stays in the normal pipeline.
export const SUCCESSFUL_SURVEY_OUTCOMES: ReadonlySet<string> = new Set([
  "Surveyed",
  "Surveyed - Pending Upload",
  "EPC Completed",
]);

export const MAJOR_CONDITION_STAGE_ID = "3061261536" as const;

// Order of stages for grouping/display (queries excluded from this list)
export const STAGE_ORDER: DisplayStage[] = [
  "Scope & Planning",
  "Booking in Progress",
  "Assessment in Progress",
  "Coordination in Progress",
  "Design in Progress",
  "Installation in Progress",
  "Installation Complete",
  "At Lodgement",
  "At Post Survey",
  "Project Complete",
];

// -----------------------------------------------------------------------
// Stage colour mapping — used for badges (PropertyTable) and funnel bars (AnalyticsView)
// -----------------------------------------------------------------------
export const STAGE_COLORS: Record<
  DisplayStage,
  { bg: string; text: string; border: string; dot: string }
> = {
  "Scope & Planning": {
    bg: "bg-slate-100",
    text: "text-slate-700",
    border: "border-slate-200",
    dot: "bg-slate-400",
  },
  "Booking in Progress": {
    bg: "bg-sky-50",
    text: "text-sky-700",
    border: "border-sky-200",
    dot: "bg-sky-400",
  },
  "Assessment in Progress": {
    bg: "bg-blue-100",
    text: "text-blue-900",
    border: "border-blue-400",
    dot: "bg-blue-700",
  },
  "Coordination in Progress": {
    bg: "bg-indigo-50",
    text: "text-indigo-700",
    border: "border-indigo-200",
    dot: "bg-indigo-400",
  },
  "Design in Progress": {
    bg: "bg-blue-50",
    text: "text-blue-700",
    border: "border-blue-200",
    dot: "bg-blue-400",
  },
  "Installation in Progress": {
    bg: "bg-indigo-50",
    text: "text-indigo-600",
    border: "border-indigo-200",
    dot: "bg-indigo-300",
  },
  "Installation Complete": {
    bg: "bg-teal-50",
    text: "text-teal-700",
    border: "border-teal-200",
    dot: "bg-teal-400",
  },
  "At Lodgement": {
    bg: "bg-cyan-50",
    text: "text-cyan-700",
    border: "border-cyan-200",
    dot: "bg-cyan-400",
  },
  "At Post Survey": {
    bg: "bg-violet-50",
    text: "text-violet-700",
    border: "border-violet-200",
    dot: "bg-violet-400",
  },
  "Project Complete": {
    bg: "bg-emerald-50",
    text: "text-emerald-700",
    border: "border-emerald-200",
    dot: "bg-emerald-500",
  },
  Queries: {
    bg: "bg-red-50",
    text: "text-red-600",
    border: "border-red-200",
    dot: "bg-red-400",
  },
  "Removed from Bookings": {
    bg: "bg-slate-50",
    text: "text-slate-600",
    border: "border-slate-200",
    dot: "bg-slate-400",
  },
  "Removed from Program": {
    bg: "bg-slate-100",
    text: "text-slate-700",
    border: "border-slate-300",
    dot: "bg-slate-500",
  },
  "Unknown Stage": {
    bg: "bg-gray-50",
    text: "text-gray-500",
    border: "border-gray-100",
    dot: "bg-gray-300",
  },
};
