/**
 * Website Deployment Model
 *
 * Durable queue record for publishing a Website Planner site to a hosting provider —
 * a direct clone of LandingPageDeployment (which itself mirrors SocialMediaPublication).
 * The collection itself is the queue: the websiteDeployWorker ticks periodically, claims
 * `queued` deployments (respecting nextAttemptAt backoff and a workerLockedAt claim),
 * bundles the generated multi-page site into a standalone artifact, uploads it via the
 * provider adapter, and records the result.
 *
 * Entirely additive: replaces nothing. The website generator's existing in-memory job
 * flow is untouched; this is a separate, restart-safe deployment queue.
 */

import mongoose, { Schema, Document } from 'mongoose';
import { HostingProvider } from './HostingConnection';

export type DeploymentStatus =
  | 'draft'
  | 'queued'
  | 'bundling'
  | 'deploying'
  | 'live'
  | 'failed'
  | 'cancelled';

export interface IDeploymentError {
  code?: string;
  message?: string;
  at?: Date;
}

export interface IWebsiteDeployment extends Document {
  companyId: string;
  createdBy: string;         // owning admin — isolation anchor
  websiteId: string;         // id of the website inside ModuleData.data.websitePlanners[]
  websiteName?: string;

  provider: HostingProvider;
  connectionRef: string;     // HostingConnection _id (snapshot at creation)

  status: DeploymentStatus;
  attemptCount: number;
  nextAttemptAt?: Date | null;
  workerLockedAt?: Date | null;

  // Per-deploy options captured at enqueue time
  customDomain?: string;

  // Result
  deployUrl?: string;
  providerDeployId?: string;
  bundleHash?: string;
  fileCount?: number;
  publishedAt?: Date;

  lastError?: IDeploymentError;
  errorHistory: IDeploymentError[];

  createdAt: Date;
  updatedAt: Date;
}

const DeploymentErrorSchema = new Schema<IDeploymentError>({
  code: { type: String },
  message: { type: String },
  at: { type: Date },
}, { _id: false });

const WebsiteDeploymentSchema = new Schema<IWebsiteDeployment>({
  companyId: { type: String, required: true, index: true },
  createdBy: { type: String, required: true, index: true },
  websiteId: { type: String, required: true, index: true },
  websiteName: { type: String },

  provider: {
    type: String,
    enum: ['sftp', 'ftp', 'netlify', 'vercel', 'cloudflare-pages', 'github-pages', 's3', 'wordpress'],
    required: true,
  },
  connectionRef: { type: String, required: true },

  status: {
    type: String,
    enum: ['draft', 'queued', 'bundling', 'deploying', 'live', 'failed', 'cancelled'],
    default: 'queued',
    index: true,
  },
  attemptCount: { type: Number, default: 0 },
  nextAttemptAt: { type: Date, default: null },
  workerLockedAt: { type: Date, default: null },

  customDomain: { type: String },

  deployUrl: { type: String },
  providerDeployId: { type: String },
  bundleHash: { type: String },
  fileCount: { type: Number },
  publishedAt: { type: Date },

  lastError: { type: DeploymentErrorSchema, default: null },
  errorHistory: { type: [DeploymentErrorSchema], default: [] },
}, {
  timestamps: true,
});

// Worker scan index — claim queued jobs whose backoff has elapsed.
WebsiteDeploymentSchema.index({ status: 1, nextAttemptAt: 1 });
WebsiteDeploymentSchema.index({ companyId: 1, websiteId: 1, createdAt: -1 });

export const WebsiteDeployment =
  mongoose.models.WebsiteDeployment ||
  mongoose.model<IWebsiteDeployment>('WebsiteDeployment', WebsiteDeploymentSchema);
