import { DB } from '../db';
import { Dispute, DisputeEvent, DisputeStatus, DisputeReasonCode, DisputeOutcome } from './types';

export class DisputeService {
  constructor(private db: DB) {}

  async createDispute(disputeData: Omit<Dispute, 'id' | 'status' | 'created_at' | 'updated_at'>): Promise<Dispute> {
    const { deal_id, opened_by_user_id, reason_code, summary, requested_outcome } = disputeData;
    
    const result = await this.db.query(
      `INSERT INTO disputes (deal_id, opened_by_user_id, reason_code, summary, requested_outcome) 
       VALUES (?, ?, ?, ?, ?)`,
      [deal_id, opened_by_user_id, reason_code, summary, requested_outcome]
    );
    
    const disputeId = result.insertId;
    return await this.getDisputeById(disputeId);
  }

  async getDisputeById(id: number): Promise<Dispute | null> {
    const [rows] = await this.db.query('SELECT * FROM disputes WHERE id = ?', [id]);
    return rows.length > 0 ? rows[0] as Dispute : null;
  }

  async updateDisputeStatus(disputeId: number, status: DisputeStatus, updatedByUserId: number): Promise<void> {
    // Get current status for event logging
    const dispute = await this.getDisputeById(disputeId);
    if (!dispute) {
      throw new Error('Dispute not found');
    }
    
    await this.db.query(
      'UPDATE disputes SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
      [status, disputeId]
    );
    
    // Log the status change as an event
    await this.logDisputeEvent(disputeId, 'status_change', updatedByUserId, { 
      old_status: dispute.status, 
      new_status: status 
    });
  }

  async addEvidence(disputeId: number, userId: number, evidenceData: any): Promise<void> {
    // Log the evidence addition as an event
    await this.logDisputeEvent(disputeId, 'evidence_added', userId, evidenceData);
  }

  async resolveDispute(disputeId: number, resolvedByUserId: number, decision: DisputeOutcome, reason: string): Promise<void> {
    await this.db.query(
      `UPDATE disputes 
       SET status = 'resolved', final_decision = ?, final_reason = ?, decided_by_user_id = ?, decided_at = CURRENT_TIMESTAMP 
       WHERE id = ?`,
      [decision, reason, resolvedByUserId, disputeId]
    );
    
    // Log the resolution as an event
    await this.logDisputeEvent(disputeId, 'resolved', resolvedByUserId, { decision, reason });
  }

  async logDisputeEvent(disputeId: number, eventType: string, actorUserId: number, payload: any): Promise<void> {
    await this.db.query(
      `INSERT INTO dispute_events (dispute_id, event_type, actor_user_id, payload_json) 
       VALUES (?, ?, ?, ?)`,
      [disputeId, eventType, actorUserId, JSON.stringify(payload)]
    );
  }

  async getDisputeEvents(disputeId: number): Promise<DisputeEvent[]> {
    const [rows] = await this.db.query('SELECT * FROM dispute_events WHERE dispute_id = ? ORDER BY created_at ASC', [disputeId]);
    return rows as DisputeEvent[];
  }
}